Обработка данных IMU переделана наподобие рабочей прошивки
This commit is contained in:
@@ -24,8 +24,8 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int16_t ax, ay, az; // lsb
|
float ax, ay, az; // lsb
|
||||||
int16_t gx, gy, gz; // lsb
|
float gx, gy, gz; // lsb
|
||||||
} imu_raw_t;
|
} imu_raw_t;
|
||||||
|
|
||||||
void imu_pow_init();
|
void imu_pow_init();
|
||||||
|
|||||||
@@ -17,8 +17,12 @@ typedef struct
|
|||||||
|
|
||||||
void imu_processing_init();
|
void imu_processing_init();
|
||||||
|
|
||||||
void imu_read_scaled(imu_scaled_t* out);
|
void imu_read_scaled(imu_scaled_t* out, const uint8_t* allowed_calib);
|
||||||
|
void imu_calib(imu_raw_t* imu, long gyrLim, long accZero, long accMax);
|
||||||
|
|
||||||
void imu_calibrate();
|
void imu_calibrate();
|
||||||
|
|
||||||
|
float normalize(float value, float scale, float min, float max);
|
||||||
|
long absl(long value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
#include "biquad_filter.h"
|
#include "biquad_filter.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static float gyro_bias_x = 0.0f;
|
static float gyro_bias_x = 0.0f;
|
||||||
static float gyro_bias_y = 0.0f;
|
static float gyro_bias_y = 0.0f;
|
||||||
static float gyro_bias_z = 0.0f;
|
static float gyro_bias_z = 0.0f;
|
||||||
@@ -18,6 +20,15 @@ static biquad_t gyro_x_lpf;
|
|||||||
static biquad_t gyro_y_lpf;
|
static biquad_t gyro_y_lpf;
|
||||||
static biquad_t gyro_z_lpf;
|
static biquad_t gyro_z_lpf;
|
||||||
|
|
||||||
|
const float accel_min = -8192.0f;
|
||||||
|
const float accel_max = 8192.0f;
|
||||||
|
|
||||||
|
static int16_t x_calib;
|
||||||
|
static int16_t y_calib;
|
||||||
|
static int16_t z_calib;
|
||||||
|
static long gyro_shift[3] = {0, 0, 0};
|
||||||
|
static float acc;
|
||||||
|
|
||||||
void imu_processing_init()
|
void imu_processing_init()
|
||||||
{
|
{
|
||||||
biquad_init_lpf(&accel_x_lpf, 25.0f, 500.0f);
|
biquad_init_lpf(&accel_x_lpf, 25.0f, 500.0f);
|
||||||
@@ -29,13 +40,42 @@ void imu_processing_init()
|
|||||||
biquad_init_lpf(&gyro_z_lpf, 25.0f, 500.0f);
|
biquad_init_lpf(&gyro_z_lpf, 25.0f, 500.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void imu_read_scaled(imu_scaled_t* out)
|
void imu_read_scaled(imu_scaled_t* out, const uint8_t* allowed_calib)
|
||||||
{
|
{
|
||||||
static imu_raw_t raw;
|
static imu_raw_t raw;
|
||||||
|
|
||||||
imu_read_raw(&raw);
|
imu_read_raw(&raw);
|
||||||
|
|
||||||
out->ax = raw.ax / ACCEL_SENS_SCALE_FACTOR - accel_bias_x;
|
raw.ax = biquad_apply(&accel_x_lpf, raw.ax);
|
||||||
|
raw.ay = biquad_apply(&accel_y_lpf, raw.ay);
|
||||||
|
raw.az = biquad_apply(&accel_z_lpf, raw.az);
|
||||||
|
|
||||||
|
raw.gx = biquad_apply(&gyro_x_lpf, raw.gx);
|
||||||
|
raw.gy = biquad_apply(&gyro_y_lpf, raw.gy);
|
||||||
|
raw.gz = biquad_apply(&gyro_z_lpf, raw.gz);
|
||||||
|
|
||||||
|
if (allowed_calib) imu_calib(&raw, 50, 8192, 1000);
|
||||||
|
|
||||||
|
/*float alpha = 0.01;
|
||||||
|
|
||||||
|
out->ax = out->ax * (1.0f - alpha) + raw.ax * alpha;
|
||||||
|
out->ay = out->ay * (1.0f - alpha) + raw.ay * alpha;
|
||||||
|
out->az = out->az * (1.0f - alpha) + raw.az * alpha;
|
||||||
|
|
||||||
|
out->gx = out->gx * (1.0f - alpha) + raw.gx * alpha;
|
||||||
|
out->gy = out->gy * (1.0f - alpha) + raw.gy * alpha;
|
||||||
|
out->gz = out->gz * (1.0f - alpha) + raw.gz * alpha;*/
|
||||||
|
|
||||||
|
out->ax = normalize(raw.ax, 1.0f, accel_min, accel_max);
|
||||||
|
out->ay = normalize(raw.ay, 1.0f, accel_min, accel_max);
|
||||||
|
out->az = normalize(raw.az, 1.0f, accel_min, accel_max);
|
||||||
|
|
||||||
|
out->gx = (raw.gx - gyro_shift[0]) / GYRO_SENS_SCALE_FACTOR;
|
||||||
|
out->gy = (raw.gy - gyro_shift[1]) / GYRO_SENS_SCALE_FACTOR;
|
||||||
|
out->gz = (raw.gz - gyro_shift[2]) / GYRO_SENS_SCALE_FACTOR;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/*out->ax = raw.ax / ACCEL_SENS_SCALE_FACTOR - accel_bias_x;
|
||||||
out->ay = raw.ay / ACCEL_SENS_SCALE_FACTOR - accel_bias_y;
|
out->ay = raw.ay / ACCEL_SENS_SCALE_FACTOR - accel_bias_y;
|
||||||
out->az = raw.az / ACCEL_SENS_SCALE_FACTOR - accel_bias_z;
|
out->az = raw.az / ACCEL_SENS_SCALE_FACTOR - accel_bias_z;
|
||||||
|
|
||||||
@@ -49,7 +89,33 @@ void imu_read_scaled(imu_scaled_t* out)
|
|||||||
|
|
||||||
out->gx = biquad_apply(&gyro_x_lpf, out->gx);
|
out->gx = biquad_apply(&gyro_x_lpf, out->gx);
|
||||||
out->gy = biquad_apply(&gyro_y_lpf, out->gy);
|
out->gy = biquad_apply(&gyro_y_lpf, out->gy);
|
||||||
out->gz = biquad_apply(&gyro_z_lpf, out->gz);
|
out->gz = biquad_apply(&gyro_z_lpf, out->gz);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void imu_calib(imu_raw_t* imu, long gyrLim, long accZero, long accMax)
|
||||||
|
{
|
||||||
|
long len = imu->gx*imu->gx + imu->gy*imu->gy + imu->gz*imu->gz;
|
||||||
|
if (len > gyrLim*gyrLim) return;
|
||||||
|
|
||||||
|
x_calib = imu->gx, y_calib = imu->gy, z_calib = imu->gz;
|
||||||
|
const float alpha = 0.001f;
|
||||||
|
|
||||||
|
x_calib = x_calib * (1.0f - alpha) + imu->gx * alpha;
|
||||||
|
y_calib = y_calib * (1.0f - alpha) + imu->gy * alpha;
|
||||||
|
z_calib = z_calib * (1.0f - alpha) + imu->gz * alpha;
|
||||||
|
|
||||||
|
gyro_shift[0] = x_calib;
|
||||||
|
gyro_shift[1] = y_calib;
|
||||||
|
gyro_shift[2] = z_calib;
|
||||||
|
|
||||||
|
len = imu->ax*imu->ax + imu->ay*imu->ay + imu->az*imu->az;
|
||||||
|
if (absl(len - accZero*accZero) > accMax*accMax) return;
|
||||||
|
|
||||||
|
len = sqrtf(len);
|
||||||
|
|
||||||
|
acc = len;
|
||||||
|
|
||||||
|
acc = acc * (1.0f - alpha) + len * alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
void imu_calibrate()
|
void imu_calibrate()
|
||||||
@@ -89,3 +155,16 @@ void imu_calibrate()
|
|||||||
gyro_bias_y = sum_gy / samples;
|
gyro_bias_y = sum_gy / samples;
|
||||||
gyro_bias_z = sum_gz / samples;
|
gyro_bias_z = sum_gz / samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float normalize(float value, float scale, float min, float max)
|
||||||
|
{
|
||||||
|
const float len = (max - min) / 2.0f;
|
||||||
|
const float shift = (max + min) / 2.0f;
|
||||||
|
return (value - shift) * scale / len;
|
||||||
|
}
|
||||||
|
|
||||||
|
long absl(long value)
|
||||||
|
{
|
||||||
|
if (value < 0) return -value;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ void TIM6_DAC_IRQHandler();
|
|||||||
|
|
||||||
static uint8_t irs_update_flag = 0;
|
static uint8_t irs_update_flag = 0;
|
||||||
static uint8_t control_update_flag = 0;
|
static uint8_t control_update_flag = 0;
|
||||||
|
static uint8_t allowed_calib = 0;
|
||||||
|
|
||||||
imu_scaled_t imu;
|
imu_scaled_t imu;
|
||||||
IRS irs;
|
IRS irs;
|
||||||
@@ -60,7 +61,7 @@ int main(void)
|
|||||||
{
|
{
|
||||||
irs_update_flag = 0;
|
irs_update_flag = 0;
|
||||||
|
|
||||||
imu_read_scaled(&imu);
|
imu_read_scaled(&imu, &allowed_calib);
|
||||||
|
|
||||||
irs.gyro.x = imu.gx;
|
irs.gyro.x = imu.gx;
|
||||||
irs.gyro.y = imu.gy;
|
irs.gyro.y = imu.gy;
|
||||||
@@ -89,6 +90,8 @@ int main(void)
|
|||||||
|
|
||||||
if (rx_chs_normalized.rc_armed)
|
if (rx_chs_normalized.rc_armed)
|
||||||
{
|
{
|
||||||
|
allowed_calib = 1;
|
||||||
|
|
||||||
motors_set_throttle_mix(
|
motors_set_throttle_mix(
|
||||||
rx_chs_normalized.rc_throttle,
|
rx_chs_normalized.rc_throttle,
|
||||||
&ctrl_chs,
|
&ctrl_chs,
|
||||||
@@ -98,6 +101,7 @@ int main(void)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
motors_turn_off();
|
motors_turn_off();
|
||||||
|
allowed_calib = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user