uas-ugv/main/ugv_io.cc

97 lines
3.2 KiB
C++
Raw Normal View History

2019-01-15 10:37:22 -08:00
#include "ugv_io.hh"
#include <driver/gpio.h>
#include <driver/mcpwm.h>
#include <driver/uart.h>
2019-01-15 10:37:22 -08:00
#include <esp_log.h>
#include <math.h>
#include "MPU.hpp"
#include "mpu/math.hpp"
namespace ugv {
namespace io {
2019-01-24 18:10:38 -08:00
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; \
} \
}
2019-01-17 23:15:07 -08:00
static constexpr mcpwm_unit_t MCPWM_UNIT = MCPWM_UNIT_0;
static constexpr gpio_num_t MOTOR_LEFT_PWM = GPIO_NUM_0;
2019-01-24 18:10:38 -08:00
static constexpr gpio_num_t MOTOR_LEFT_DIR = GPIO_NUM_2;
static constexpr gpio_num_t MOTOR_RIGHT_PWM = GPIO_NUM_12;
2019-01-24 18:58:59 -08:00
static constexpr gpio_num_t MOTOR_RIGHT_DIR = GPIO_NUM_16;
IOClass IO;
2019-01-15 10:37:22 -08:00
2019-01-17 19:44:14 -08:00
IOClass::IOClass() {}
2019-01-15 10:37:22 -08:00
2019-01-17 19:44:14 -08:00
IOClass::~IOClass() {}
2019-01-15 10:37:22 -08:00
void IOClass::Init() {
InitMotors();
2019-01-17 19:44:14 -08:00
mpu_.Init();
gps_.Init();
}
2019-01-15 10:37:22 -08:00
void IOClass::InitMotors() {
2019-01-24 18:10:38 -08:00
ERROR_CHECK(gpio_set_direction(MOTOR_LEFT_PWM, GPIO_MODE_OUTPUT));
ERROR_CHECK(gpio_set_direction(MOTOR_LEFT_DIR, GPIO_MODE_OUTPUT));
2019-01-24 18:58:59 -08:00
ERROR_CHECK(gpio_set_pull_mode(MOTOR_LEFT_DIR, GPIO_FLOATING));
2019-01-24 18:10:38 -08:00
ERROR_CHECK(gpio_set_direction(MOTOR_RIGHT_PWM, GPIO_MODE_OUTPUT));
ERROR_CHECK(gpio_set_direction(MOTOR_RIGHT_DIR, GPIO_MODE_OUTPUT));
2019-01-24 18:58:59 -08:00
ERROR_CHECK(gpio_set_pull_mode(MOTOR_RIGHT_DIR, GPIO_FLOATING));
2019-01-24 18:10:38 -08:00
ERROR_CHECK(mcpwm_gpio_init(MCPWM_UNIT, MCPWM0A, MOTOR_LEFT_PWM));
ERROR_CHECK(mcpwm_gpio_init(MCPWM_UNIT, MCPWM1A, MOTOR_RIGHT_PWM));
2019-01-15 10:37:22 -08:00
mcpwm_config_t mcpwm_config;
mcpwm_config.frequency = 20000; // 20khz
mcpwm_config.cmpr_a = 0;
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
2019-01-24 18:10:38 -08:00
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) {
2019-01-17 19:44:14 -08:00
gps_.GetData(inputs.gps);
mpu_.GetData(inputs.mpu);
2019-01-15 10:37:22 -08:00
}
void IOClass::WriteOutputs(const Outputs &outputs) {
2019-01-24 18:10:38 -08:00
esp_err_t ret;
ret = mcpwm_set_duty(MCPWM_UNIT, MCPWM_TIMER_0, MCPWM_OPR_A,
2019-01-24 19:40:17 -08:00
fabsf(outputs.left_motor * 100.0));
2019-01-24 18:10:38 -08:00
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,
2019-01-24 19:40:17 -08:00
fabsf(outputs.right_motor * 100.0));
2019-01-24 18:10:38 -08:00
ERROR_CHECK(ret);
ret = mcpwm_start(MCPWM_UNIT, MCPWM_TIMER_1);
ERROR_CHECK(ret);
2019-01-15 10:37:22 -08:00
bool left_dir, right_dir;
left_dir = outputs.left_motor < 0.f;
right_dir = outputs.right_motor < 0.f;
2019-01-24 18:10:38 -08:00
ret = gpio_set_level(MOTOR_LEFT_DIR, left_dir);
ERROR_CHECK(ret);
ret = gpio_set_level(MOTOR_RIGHT_DIR, right_dir);
ERROR_CHECK(ret);
2019-01-24 19:16:18 -08:00
ESP_LOGV(TAG, "motor outputs: (%f, %f)", outputs.left_motor,
2019-01-24 18:10:38 -08:00
outputs.right_motor);
2019-01-15 10:37:22 -08:00
}
}; // namespace io
}; // namespace ugv