Browse Source

try to fix comms issues

master
Alex Mikhalev 6 years ago
parent
commit
703a0715df
  1. 2
      .gitignore
  2. 26
      main/ugv.cc
  3. 2
      main/ugv.hh
  4. 80
      main/ugv_io_mpu.cc
  5. 23
      main/ugv_io_mpu.hh
  6. 6
      tools/config.yml

2
.gitignore vendored

@ -8,3 +8,5 @@
__pycache__ __pycache__
*.pyc *.pyc
/venv
/tools/venv

26
main/ugv.cc

@ -87,6 +87,8 @@ void UGV::Init() {
esp_timer_start_periodic(timer_handle, LOOP_PERIOD_US); esp_timer_start_periodic(timer_handle, LOOP_PERIOD_US);
last_print_ = 0; last_print_ = 0;
last_noise_ = 0; last_noise_ = 0;
last_left_ = 0;
last_right_ = 0;
} }
void UGV::UpdateAHRS() { void UGV::UpdateAHRS() {
@ -106,7 +108,7 @@ void UGV::UpdateAHRS() {
void UGV::DoDebugPrint() { void UGV::DoDebugPrint() {
auto &mpu = inputs_.mpu; auto &mpu = inputs_.mpu;
ESP_LOGV(TAG, "inputs: acc=(%f, %f, %f) gyro=(%f, %f, %f) mag=(%f, %f, %f)", ESP_LOGD(TAG, "inputs: acc=(%f, %f, %f) gyro=(%f, %f, %f) mag=(%f, %f, %f)",
mpu.accel.x, mpu.accel.y, mpu.accel.z, mpu.gyro_rate.x, mpu.accel.x, mpu.accel.y, mpu.accel.z, mpu.gyro_rate.x,
mpu.gyro_rate.y, mpu.gyro_rate.z, mpu.mag.x, mpu.mag.y, mpu.mag.z); mpu.gyro_rate.y, mpu.gyro_rate.z, mpu.mag.x, mpu.mag.y, mpu.mag.z);
ESP_LOGD(TAG, "ahrs: yaw=%f, pitch=%f, roll=%f", yaw_, pitch_, roll_); ESP_LOGD(TAG, "ahrs: yaw=%f, pitch=%f, roll=%f", yaw_, pitch_, roll_);
@ -286,7 +288,29 @@ void UGV::OnTick() {
outputs_.right_motor = drive_power + angle_pwr; outputs_.right_motor = drive_power + angle_pwr;
} }
constexpr float MAX_ACCEL = 8 * LOOP_PERIOD_S;
if (inputs_.mpu.gyro_rate.x == 0 && inputs_.mpu.gyro_rate.y == 0 &&
inputs_.mpu.gyro_rate.z == 0) {
outputs_.left_motor = 0;
outputs_.right_motor = 0;
} else {
float dleft = outputs_.left_motor - last_left_;
float dright = outputs_.right_motor - last_right_;
if (dleft > MAX_ACCEL) {
outputs_.left_motor = last_left_ + MAX_ACCEL;
} else if (dleft < -MAX_ACCEL) {
outputs_.left_motor = last_left_ - MAX_ACCEL;
}
if (dright > MAX_ACCEL) {
outputs_.right_motor = last_right_ + MAX_ACCEL;
} else if (dright < -MAX_ACCEL) {
outputs_.right_motor = last_right_ - MAX_ACCEL;
}
}
io->WriteOutputs(outputs_); io->WriteOutputs(outputs_);
last_left_ = outputs_.left_motor;
last_right_ = outputs_.right_motor;
if (current_state_ != next_state_) { if (current_state_ != next_state_) {
ESP_LOGI(TAG, "switching state to %d", next_state_); ESP_LOGI(TAG, "switching state to %d", next_state_);

2
main/ugv.hh

@ -53,6 +53,8 @@ class UGV {
float accel_noise_; float accel_noise_;
float gyro_noise_; float gyro_noise_;
bool is_still_; bool is_still_;
float last_left_;
float last_right_;
void UpdateAHRS(); void UpdateAHRS();
void DoDebugPrint(); void DoDebugPrint();

80
main/ugv_io_mpu.cc

@ -22,11 +22,13 @@ static constexpr float MPU_MAG_TO_FLUX = (4912.f) / (32760.f);
static const Vec3f ACCEL_OFFSET = {0., 0., 0.}; static const Vec3f ACCEL_OFFSET = {0., 0., 0.};
static const Mat3f ACCEL_MAT = {-1., 0., 0., 0., -1., 0., 0., 0., -1.}; static const Mat3f ACCEL_MAT = {-1., 0., 0., 0., -1., 0., 0., 0., -1.};
//static const Vec3f MAG_OFFSET = {-7.79683, 3.6735, 32.3868}; // static const Vec3f MAG_OFFSET = {-7.79683, 3.6735, 32.3868};
//static const Vec3f MAG_OFFSET = {-118.902, 18.8173, -39.209}; // static const Vec3f MAG_OFFSET = {-118.902, 18.8173, -39.209};
static const Vec3f MAG_OFFSET = {-135.994629, 19.117216, -33.0}; static const Vec3f MAG_OFFSET = {-135.994629, 19.117216, -33.0};
//static const Mat3f MAG_MAT = {0., -0.0281408, 0., -0.0284409, 0., 0., 0., 0., 0.0261544}; // static const Mat3f MAG_MAT = {0., -0.0281408, 0., -0.0284409, 0., 0.,
static const Mat3f MAG_MAT = {0., -0.0335989, 0., -0.0330167, 0., 0., 0., 0., 0.0335989}; // 0., 0., 0.0261544};
static const Mat3f MAG_MAT = {0., -0.0335989, 0., -0.0330167, 0.,
0., 0., 0., 0.0335989};
static const Vec3f GYRO_OFFSET = {-4.33655, -2.76826, -0.908427}; static const Vec3f GYRO_OFFSET = {-4.33655, -2.76826, -0.908427};
static const Mat3f GYRO_MAT = {1., 0., 0., 0., 1., 0., 0., 0., 1.}; static const Mat3f GYRO_MAT = {1., 0., 0., 0., 1., 0., 0., 0., 1.};
@ -42,6 +44,37 @@ MPU::MPU() : mpu_(nullptr) {}
MPU::~MPU() { delete mpu_; } MPU::~MPU() { delete mpu_; }
void MPU::Init() { void MPU::Init() {
mutex_ = xSemaphoreCreateMutex();
BaseType_t xRet = xTaskCreate(MPU::TaskEntry, "ugv_io_mpu", 8 * 1024, this, 3,
&this->task_);
if (xRet != pdTRUE) {
ESP_LOGE(TAG, "error creating MPU task");
return;
}
}
void MPU::Calibrate() {
mpud::raw_axes_t accel_offset, gyro_offset;
mpu_->computeOffsets(&accel_offset, &gyro_offset);
mpu_->setAccelOffset(accel_offset);
mpu_->setGyroOffset(gyro_offset);
{
auto ao = mpud::math::accelGravity(accel_offset, mpud::ACCEL_FS_2G);
auto go = mpud::math::gyroDegPerSec(gyro_offset, mpud::GYRO_FS_250DPS);
ESP_LOGI(TAG, "MPU offsets: accel=(%f, %f, %f) gyro=(%f, %f, %f)", ao.x,
ao.y, ao.z, go.x, go.y, go.z);
}
}
void MPU::GetData(MpuData &data) {
xSemaphoreTake(mutex_, pdMS_TO_TICKS(10));
data = last_data_;
last_data_.gyro_rate = {0, 0, 0};
xSemaphoreGive(mutex_);
}
bool MPU::Initialize() {
xSemaphoreTake(i2c_mutex, portMAX_DELAY); xSemaphoreTake(i2c_mutex, portMAX_DELAY);
mpu_bus_ = &i2c0; mpu_bus_ = &i2c0;
// This is shared with the oled, so just use those pins // This is shared with the oled, so just use those pins
@ -73,7 +106,7 @@ void MPU::Init() {
break; break;
} }
if (tries == 5) { if (tries == 5) {
return; return false;
} }
// Calibrate(); // Calibrate();
mpu_->setAccelFullScale(MPU_ACCEL_FS); mpu_->setAccelFullScale(MPU_ACCEL_FS);
@ -83,33 +116,34 @@ void MPU::Init() {
xSemaphoreGive(i2c_mutex); xSemaphoreGive(i2c_mutex);
ESP_LOGI(TAG, "MPU initialized"); ESP_LOGI(TAG, "MPU initialized");
return true;
} }
void MPU::Calibrate() { void MPU::DoTask() {
mpud::raw_axes_t accel_offset, gyro_offset; ESP_LOGI(TAG, "MPU task start");
mpu_->computeOffsets(&accel_offset, &gyro_offset); mpud::raw_axes_t accel_, gyro_, mag_;
mpu_->setAccelOffset(accel_offset); esp_err_t ret;
mpu_->setGyroOffset(gyro_offset); MpuData data;
{
auto ao = mpud::math::accelGravity(accel_offset, mpud::ACCEL_FS_2G); if (!Initialize()) {
auto go = mpud::math::gyroDegPerSec(gyro_offset, mpud::GYRO_FS_250DPS); return;
ESP_LOGI(TAG, "MPU offsets: accel=(%f, %f, %f) gyro=(%f, %f, %f)", ao.x,
ao.y, ao.z, go.x, go.y, go.z);
} }
}
void MPU::GetData(MpuData &data) { while (true) {
esp_err_t ret;
xSemaphoreTake(i2c_mutex, portMAX_DELAY); xSemaphoreTake(i2c_mutex, portMAX_DELAY);
ret = mpu_->motion(&accel_, &gyro_); ret = mpu_->motion(&accel_, &gyro_);
if (ret != ESP_OK) { if (ret != ESP_OK) {
ESP_LOGE(TAG, "error reading MPU: %#x", ret); ESP_LOGE(TAG, "error reading MPU: %#x", ret);
xSemaphoreGive(i2c_mutex);
continue;
} }
uint8_t compass_data[7]; uint8_t compass_data[7];
mpu_->setAuxI2CBypass(true); mpu_->setAuxI2CBypass(true);
ret = mpu_bus_->readBytes(mpud::COMPASS_I2CADDRESS, 0x03, 7, compass_data); ret = mpu_bus_->readBytes(mpud::COMPASS_I2CADDRESS, 0x03, 7, compass_data);
if (ret != ESP_OK) { if (ret != ESP_OK) {
ESP_LOGE(TAG, "error reading MPU compass: %#x", ret); ESP_LOGE(TAG, "error reading MPU compass: %#x", ret);
xSemaphoreGive(i2c_mutex);
continue;
} }
mpu_->setAuxI2CBypass(false); mpu_->setAuxI2CBypass(false);
xSemaphoreGive(i2c_mutex); xSemaphoreGive(i2c_mutex);
@ -128,6 +162,16 @@ void MPU::GetData(MpuData &data) {
data.mag.y = ((float)my) * MPU_MAG_TO_FLUX; data.mag.y = ((float)my) * MPU_MAG_TO_FLUX;
data.mag.z = ((float)mz) * MPU_MAG_TO_FLUX; data.mag.z = ((float)mz) * MPU_MAG_TO_FLUX;
data.mag = MAG_MAT * (data.mag + MAG_OFFSET); data.mag = MAG_MAT * (data.mag + MAG_OFFSET);
xSemaphoreTake(mutex_, pdMS_TO_TICKS(100));
last_data_ = data;
xSemaphoreGive(mutex_);
}
}
void MPU::TaskEntry(void *arg) {
MPU *mpu = (MPU *)arg;
mpu->DoTask();
vTaskDelete(NULL);
} }
}; // namespace io }; // namespace io

23
main/ugv_io_mpu.hh

@ -42,13 +42,9 @@ struct Vec3f {
return *this; return *this;
} }
float dot(const Vec3f& v) const { float dot(const Vec3f& v) const { return x * v.x + y * v.y + z * v.z; }
return x * v.x + y * v.y + z * v.z;
}
float norm2() const { float norm2() const { return x * x + y * y + z * z; }
return x * x + y * y + z * z;
}
}; };
struct Mat3f { struct Mat3f {
@ -65,8 +61,7 @@ struct Mat3f {
float zx, zy, zz; float zx, zy, zz;
}; };
Mat3f(Vec3f rx_, Vec3f ry_, Vec3f rz_) Mat3f(Vec3f rx_, Vec3f ry_, Vec3f rz_) : rx(rx_), ry(ry_), rz(rz_) {}
: rx(rx_), ry(ry_), rz(rz_) {}
Mat3f(float xx, float xy, float xz, float yx, float yy, float yz, float zx, Mat3f(float xx, float xy, float xz, float yx, float yy, float yz, float zx,
float zy, float zz) float zy, float zz)
@ -76,9 +71,7 @@ struct Mat3f {
return {rx.dot(v), ry.dot(v), rz.dot(v)}; return {rx.dot(v), ry.dot(v), rz.dot(v)};
} }
Mat3f transpose() const { Mat3f transpose() const { return {xx, yx, zx, xy, yy, zy, xz, yz, zz}; }
return {xx, yx, zx, xy, yy, zy, xz, yz, zz};
}
Mat3f operator*(const Mat3f& m) const { Mat3f operator*(const Mat3f& m) const {
Mat3f mt = m.transpose(); Mat3f mt = m.transpose();
@ -108,7 +101,13 @@ class MPU {
private: private:
mpud::mpu_bus_t* mpu_bus_; mpud::mpu_bus_t* mpu_bus_;
mpud::MPU* mpu_; mpud::MPU* mpu_;
mpud::raw_axes_t accel_, gyro_, mag_; TaskHandle_t task_;
SemaphoreHandle_t mutex_;
MpuData last_data_;
void DoTask();
bool Initialize();
static void TaskEntry(void* arg);
}; };
} // namespace io } // namespace io

6
tools/config.yml

@ -1,12 +1,12 @@
REVISION: 1 REVISION: 1
angle_pid: angle_pid:
kp: 0.10 kp: 0.04
ki: 0.0001 ki: 0.0001
kd: 0.4 kd: 0.2
max_output: 0.5 max_output: 0.5
max_i_error: 15.0 max_i_error: 15.0
min_target_dist: 10.0 min_target_dist: 1.0
min_flip_pitch: 90.0 min_flip_pitch: 90.0
drive_power: 0.3 drive_power: 0.3
mag_declination: 11.5 mag_declination: 11.5

Loading…
Cancel
Save