|
|
|
@ -12,11 +12,24 @@
@@ -12,11 +12,24 @@
|
|
|
|
|
namespace ugv { |
|
|
|
|
namespace io { |
|
|
|
|
|
|
|
|
|
static const char *TAG = "ugv_io"; |
|
|
|
|
|
|
|
|
|
#define ERROR_CHECK(ret) \ |
|
|
|
|
{ \ |
|
|
|
|
esp_err_t _error_code = (ret); \ |
|
|
|
|
if (_error_code != ESP_OK) { \ |
|
|
|
|
const char *_error_name = esp_err_to_name(_error_code); \ |
|
|
|
|
ESP_LOGE(TAG, "%s:%d error: %s (%d)", __FUNCTION__, __LINE__, \ |
|
|
|
|
_error_name, _error_code); \ |
|
|
|
|
return; \ |
|
|
|
|
} \ |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static constexpr mcpwm_unit_t MCPWM_UNIT = MCPWM_UNIT_0; |
|
|
|
|
static constexpr gpio_num_t MOTOR_LEFT_PWM = GPIO_NUM_0; |
|
|
|
|
static constexpr gpio_num_t MOTOR_LEFT_DIR = GPIO_NUM_0; |
|
|
|
|
static constexpr gpio_num_t MOTOR_RIGHT_PWM = GPIO_NUM_0; |
|
|
|
|
static constexpr gpio_num_t MOTOR_RIGHT_DIR = GPIO_NUM_0; |
|
|
|
|
static constexpr gpio_num_t MOTOR_LEFT_DIR = GPIO_NUM_2; |
|
|
|
|
static constexpr gpio_num_t MOTOR_RIGHT_PWM = GPIO_NUM_12; |
|
|
|
|
static constexpr gpio_num_t MOTOR_RIGHT_DIR = GPIO_NUM_14; |
|
|
|
|
|
|
|
|
|
IOClass IO; |
|
|
|
|
|
|
|
|
@ -31,12 +44,12 @@ void IOClass::Init() {
@@ -31,12 +44,12 @@ void IOClass::Init() {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void IOClass::InitMotors() { |
|
|
|
|
gpio_set_direction(MOTOR_LEFT_PWM, GPIO_MODE_OUTPUT); |
|
|
|
|
gpio_set_direction(MOTOR_LEFT_DIR, GPIO_MODE_OUTPUT); |
|
|
|
|
gpio_set_direction(MOTOR_RIGHT_PWM, GPIO_MODE_OUTPUT); |
|
|
|
|
gpio_set_direction(MOTOR_RIGHT_DIR, GPIO_MODE_OUTPUT); |
|
|
|
|
mcpwm_gpio_init(MCPWM_UNIT, MCPWM0A, MOTOR_LEFT_PWM); |
|
|
|
|
mcpwm_gpio_init(MCPWM_UNIT, MCPWM0B, MOTOR_RIGHT_PWM); |
|
|
|
|
ERROR_CHECK(gpio_set_direction(MOTOR_LEFT_PWM, GPIO_MODE_OUTPUT)); |
|
|
|
|
ERROR_CHECK(gpio_set_direction(MOTOR_LEFT_DIR, GPIO_MODE_OUTPUT)); |
|
|
|
|
ERROR_CHECK(gpio_set_direction(MOTOR_RIGHT_PWM, GPIO_MODE_OUTPUT)); |
|
|
|
|
ERROR_CHECK(gpio_set_direction(MOTOR_RIGHT_DIR, GPIO_MODE_OUTPUT)); |
|
|
|
|
ERROR_CHECK(mcpwm_gpio_init(MCPWM_UNIT, MCPWM0A, MOTOR_LEFT_PWM)); |
|
|
|
|
ERROR_CHECK(mcpwm_gpio_init(MCPWM_UNIT, MCPWM1A, MOTOR_RIGHT_PWM)); |
|
|
|
|
|
|
|
|
|
mcpwm_config_t mcpwm_config; |
|
|
|
|
mcpwm_config.frequency = 20000; // 20khz
|
|
|
|
@ -44,7 +57,8 @@ void IOClass::InitMotors() {
@@ -44,7 +57,8 @@ void IOClass::InitMotors() {
|
|
|
|
|
mcpwm_config.cmpr_b = 0; |
|
|
|
|
mcpwm_config.counter_mode = MCPWM_UP_DOWN_COUNTER; // for symmetric pwm
|
|
|
|
|
mcpwm_config.duty_mode = MCPWM_DUTY_MODE_0; // active high
|
|
|
|
|
mcpwm_init(MCPWM_UNIT, MCPWM_TIMER_0, &mcpwm_config); |
|
|
|
|
ERROR_CHECK(mcpwm_init(MCPWM_UNIT, MCPWM_TIMER_0, &mcpwm_config)); |
|
|
|
|
ERROR_CHECK(mcpwm_init(MCPWM_UNIT, MCPWM_TIMER_1, &mcpwm_config)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void IOClass::ReadInputs(Inputs &inputs) { |
|
|
|
@ -53,15 +67,27 @@ void IOClass::ReadInputs(Inputs &inputs) {
@@ -53,15 +67,27 @@ void IOClass::ReadInputs(Inputs &inputs) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void IOClass::WriteOutputs(const Outputs &outputs) { |
|
|
|
|
mcpwm_set_duty(MCPWM_UNIT, MCPWM_TIMER_0, MCPWM_OPR_A, |
|
|
|
|
fabs(outputs.left_motor)); |
|
|
|
|
mcpwm_set_duty(MCPWM_UNIT, MCPWM_TIMER_0, MCPWM_OPR_B, |
|
|
|
|
fabs(outputs.right_motor)); |
|
|
|
|
esp_err_t ret; |
|
|
|
|
ret = mcpwm_set_duty(MCPWM_UNIT, MCPWM_TIMER_0, MCPWM_OPR_A, |
|
|
|
|
fabs(outputs.left_motor * 100.0)); |
|
|
|
|
ERROR_CHECK(ret); |
|
|
|
|
ret = mcpwm_start(MCPWM_UNIT, MCPWM_TIMER_0); |
|
|
|
|
ERROR_CHECK(ret); |
|
|
|
|
ret = mcpwm_set_duty(MCPWM_UNIT, MCPWM_TIMER_1, MCPWM_OPR_A, |
|
|
|
|
fabs(outputs.right_motor * 100.0)); |
|
|
|
|
ERROR_CHECK(ret); |
|
|
|
|
ret = mcpwm_start(MCPWM_UNIT, MCPWM_TIMER_1); |
|
|
|
|
ERROR_CHECK(ret); |
|
|
|
|
bool left_dir, right_dir; |
|
|
|
|
left_dir = outputs.left_motor < 0.f; |
|
|
|
|
right_dir = outputs.right_motor < 0.f; |
|
|
|
|
gpio_set_level(MOTOR_LEFT_DIR, left_dir); |
|
|
|
|
gpio_set_level(MOTOR_RIGHT_DIR, right_dir); |
|
|
|
|
|
|
|
|
|
ret = gpio_set_level(MOTOR_LEFT_DIR, left_dir); |
|
|
|
|
ERROR_CHECK(ret); |
|
|
|
|
ret = gpio_set_level(MOTOR_RIGHT_DIR, right_dir); |
|
|
|
|
ERROR_CHECK(ret); |
|
|
|
|
ESP_LOGD(TAG, "motor outputs: (%f, %f)", outputs.left_motor, |
|
|
|
|
outputs.right_motor); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
}; // namespace io
|
|
|
|
|