Skip to content

Commit 91a19fa

Browse files
committed
IMU improvements
1 parent 86cbc92 commit 91a19fa

10 files changed

+39
-115
lines changed

appconf/appconf_default.h

-12
Original file line numberDiff line numberDiff line change
@@ -560,17 +560,5 @@
560560
#ifndef APPCONF_IMU_G_OFFSET_2
561561
#define APPCONF_IMU_G_OFFSET_2 0.0
562562
#endif
563-
#ifndef APPCONF_IMU_G_OFFSET_COMP_FACT_0
564-
#define APPCONF_IMU_G_OFFSET_COMP_FACT_0 0.0
565-
#endif
566-
#ifndef APPCONF_IMU_G_OFFSET_COMP_FACT_1
567-
#define APPCONF_IMU_G_OFFSET_COMP_FACT_1 0.0
568-
#endif
569-
#ifndef APPCONF_IMU_G_OFFSET_COMP_FACT_2
570-
#define APPCONF_IMU_G_OFFSET_COMP_FACT_2 0.0
571-
#endif
572-
#ifndef APPCONF_IMU_G_OFFSET_COMP_CLAMP
573-
#define APPCONF_IMU_G_OFFSET_COMP_CLAMP 5.0
574-
#endif
575563

576564
#endif /* APPCONF_DEFAULT_H_ */

conf_general.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#define FW_VERSION_MAJOR 5
2525
#define FW_VERSION_MINOR 03
2626
// Set to 0 for building a release and iterate during beta test builds
27-
#define FW_TEST_VERSION_NUMBER 49
27+
#define FW_TEST_VERSION_NUMBER 50
2828

2929
#include "datatypes.h"
3030

confgenerator.c

-12
Original file line numberDiff line numberDiff line change
@@ -362,10 +362,6 @@ int32_t confgenerator_serialize_appconf(uint8_t *buffer, const app_configuration
362362
buffer_append_float32_auto(buffer, conf->imu_conf.gyro_offsets[0], &ind);
363363
buffer_append_float32_auto(buffer, conf->imu_conf.gyro_offsets[1], &ind);
364364
buffer_append_float32_auto(buffer, conf->imu_conf.gyro_offsets[2], &ind);
365-
buffer_append_float32_auto(buffer, conf->imu_conf.gyro_offset_comp_fact[0], &ind);
366-
buffer_append_float32_auto(buffer, conf->imu_conf.gyro_offset_comp_fact[1], &ind);
367-
buffer_append_float32_auto(buffer, conf->imu_conf.gyro_offset_comp_fact[2], &ind);
368-
buffer_append_float32_auto(buffer, conf->imu_conf.gyro_offset_comp_clamp, &ind);
369365

370366
return ind;
371367
}
@@ -734,10 +730,6 @@ bool confgenerator_deserialize_appconf(const uint8_t *buffer, app_configuration
734730
conf->imu_conf.gyro_offsets[0] = buffer_get_float32_auto(buffer, &ind);
735731
conf->imu_conf.gyro_offsets[1] = buffer_get_float32_auto(buffer, &ind);
736732
conf->imu_conf.gyro_offsets[2] = buffer_get_float32_auto(buffer, &ind);
737-
conf->imu_conf.gyro_offset_comp_fact[0] = buffer_get_float32_auto(buffer, &ind);
738-
conf->imu_conf.gyro_offset_comp_fact[1] = buffer_get_float32_auto(buffer, &ind);
739-
conf->imu_conf.gyro_offset_comp_fact[2] = buffer_get_float32_auto(buffer, &ind);
740-
conf->imu_conf.gyro_offset_comp_clamp = buffer_get_float32_auto(buffer, &ind);
741733

742734
return true;
743735
}
@@ -1090,8 +1082,4 @@ void confgenerator_set_defaults_appconf(app_configuration *conf) {
10901082
conf->imu_conf.gyro_offsets[0] = APPCONF_IMU_G_OFFSET_0;
10911083
conf->imu_conf.gyro_offsets[1] = APPCONF_IMU_G_OFFSET_1;
10921084
conf->imu_conf.gyro_offsets[2] = APPCONF_IMU_G_OFFSET_2;
1093-
conf->imu_conf.gyro_offset_comp_fact[0] = APPCONF_IMU_G_OFFSET_COMP_FACT_0;
1094-
conf->imu_conf.gyro_offset_comp_fact[1] = APPCONF_IMU_G_OFFSET_COMP_FACT_1;
1095-
conf->imu_conf.gyro_offset_comp_fact[2] = APPCONF_IMU_G_OFFSET_COMP_FACT_2;
1096-
conf->imu_conf.gyro_offset_comp_clamp = APPCONF_IMU_G_OFFSET_COMP_CLAMP;
10971085
}

confgenerator.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
// Constants
1111
#define MCCONF_SIGNATURE 3706516163
12-
#define APPCONF_SIGNATURE 3944621243
12+
#define APPCONF_SIGNATURE 1531606261
1313

1414
// Functions
1515
int32_t confgenerator_serialize_mcconf(uint8_t *buffer, const mc_configuration *conf);

datatypes.h

-2
Original file line numberDiff line numberDiff line change
@@ -821,8 +821,6 @@ typedef struct {
821821
float rot_yaw;
822822
float accel_offsets[3];
823823
float gyro_offsets[3];
824-
float gyro_offset_comp_fact[3];
825-
float gyro_offset_comp_clamp;
826824
} imu_config;
827825

828826
typedef struct {

imu/Fusion/FusionAhrs.c

+26-36
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "FusionAhrs.h"
4242
#include <float.h> // FLT_MAX
4343
#include <math.h> // atan2f, cosf, sinf
44+
#include "utils.h"
4445

4546
//------------------------------------------------------------------------------
4647
// Definitions
@@ -53,20 +54,35 @@
5354
//------------------------------------------------------------------------------
5455
// Functions
5556

57+
static float calculateAccConfidence(float acc_confidence_decay, float accMag, float *accMagP);
58+
59+
static float calculateAccConfidence(float acc_confidence_decay, float accMag, float *accMagP) {
60+
// G.K. Egan (C) computes confidence in accelerometers when
61+
// aircraft is being accelerated over and above that due to gravity
62+
63+
float confidence;
64+
65+
accMag = *accMagP * 0.9f + accMag * 0.1f;
66+
*accMagP = accMag;
67+
68+
confidence = 1.0 - (acc_confidence_decay * sqrtf(fabsf(accMag - 1.0f)));
69+
utils_truncate_number(&confidence, 0.0, 1.0);
70+
71+
return confidence;
72+
}
73+
5674
/**
5775
* @brief Initialises the AHRS algorithm structure.
5876
* @param fusionAhrs AHRS algorithm structure.
5977
* @param gain AHRS algorithm gain.
6078
*/
61-
void FusionAhrsInitialise(FusionAhrs * const fusionAhrs, const float gain, const float initialGain) {
79+
void FusionAhrsInitialise(FusionAhrs * const fusionAhrs, const float gain, const float acc_conf_decay) {
6280
fusionAhrs->gain = gain;
63-
fusionAhrs->initialGain = initialGain;
81+
fusionAhrs->acc_conf_decay = acc_conf_decay;
6482
fusionAhrs->minimumMagneticFieldSquared = 0.0f;
6583
fusionAhrs->maximumMagneticFieldSquared = FLT_MAX;
6684
fusionAhrs->quaternion = FUSION_QUATERNION_IDENTITY;
6785
fusionAhrs->linearAcceleration = FUSION_VECTOR3_ZERO;
68-
fusionAhrs->rampedGain = fusionAhrs->initialGain;
69-
fusionAhrs->zeroYawPending = false;
7086
}
7187

7288
/**
@@ -78,8 +94,8 @@ void FusionAhrsSetGain(FusionAhrs * const fusionAhrs, const float gain) {
7894
fusionAhrs->gain = gain;
7995
}
8096

81-
void FusionAhrsSetInitialGain(FusionAhrs * const fusionAhrs, const float initialGain) {
82-
fusionAhrs->initialGain = initialGain;
97+
void FusionAhrsSetAccConfDecay(FusionAhrs * const fusionAhrs, const float acc_conf_decay) {
98+
fusionAhrs->acc_conf_decay = acc_conf_decay;
8399
}
84100

85101
/**
@@ -142,15 +158,11 @@ void FusionAhrsUpdate(FusionAhrs * const fusionAhrs, const FusionVector3 gyrosco
142158

143159
} while (false);
144160

145-
// Ramp down gain until initialisation complete
146-
if (fusionAhrs->gain == 0) {
147-
fusionAhrs->rampedGain = 0; // skip initialisation if gain is zero
148-
}
161+
149162
float feedbackGain = fusionAhrs->gain;
150-
if (fusionAhrs->rampedGain > fusionAhrs->gain) {
151-
fusionAhrs->rampedGain -= (fusionAhrs->initialGain - fusionAhrs->gain) * samplePeriod / INITIALISATION_PERIOD;
152-
feedbackGain = fusionAhrs->rampedGain;
153-
}
163+
float accMag = sqrtf(SQ(accelerometer.axis.x) + SQ(accelerometer.axis.y) + SQ(accelerometer.axis.z));
164+
float accelConfidence = calculateAccConfidence(fusionAhrs->acc_conf_decay, accMag, &fusionAhrs->accMagP);
165+
feedbackGain *= accelConfidence;
154166

155167
// Convert gyroscope to radians per second scaled by 0.5
156168
FusionVector3 halfGyroscope = FusionVectorMultiplyScalar(gyroscope, 0.5f * FusionDegreesToRadians(1.0f));
@@ -185,19 +197,7 @@ void FusionAhrsUpdate(FusionAhrs * const fusionAhrs, const FusionVector3 gyrosco
185197
* between the current and previous gyroscope measurements.
186198
*/
187199
void FusionAhrsUpdateWithoutMagnetometer(FusionAhrs * const fusionAhrs, const FusionVector3 gyroscope, const FusionVector3 accelerometer, const float samplePeriod) {
188-
189-
// Update AHRS algorithm
190200
FusionAhrsUpdate(fusionAhrs, gyroscope, accelerometer, FUSION_VECTOR3_ZERO, samplePeriod);
191-
192-
// Zero yaw once initialisation complete
193-
if (FusionAhrsIsInitialising(fusionAhrs) == true) {
194-
fusionAhrs->zeroYawPending = true;
195-
} else {
196-
if (fusionAhrs->zeroYawPending == true) {
197-
FusionAhrsSetYaw(fusionAhrs, 0.0f);
198-
fusionAhrs->zeroYawPending = false;
199-
}
200-
}
201201
}
202202

203203
/**
@@ -252,16 +252,6 @@ FusionVector3 FusionAhrsGetEarthAcceleration(const FusionAhrs * const fusionAhrs
252252
void FusionAhrsReinitialise(FusionAhrs * const fusionAhrs) {
253253
fusionAhrs->quaternion = FUSION_QUATERNION_IDENTITY;
254254
fusionAhrs->linearAcceleration = FUSION_VECTOR3_ZERO;
255-
fusionAhrs->rampedGain = fusionAhrs->initialGain;
256-
}
257-
258-
/**
259-
* @brief Returns true while the AHRS algorithm is initialising.
260-
* @param fusionAhrs AHRS algorithm structure.
261-
* @return True while the AHRS algorithm is initialising.
262-
*/
263-
bool FusionAhrsIsInitialising(const FusionAhrs * const fusionAhrs) {
264-
return fusionAhrs->rampedGain > fusionAhrs->gain;
265255
}
266256

267257
/**

imu/Fusion/FusionAhrs.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -53,21 +53,20 @@
5353
*/
5454
typedef struct {
5555
float gain;
56-
float initialGain;
56+
float acc_conf_decay;
5757
float minimumMagneticFieldSquared;
5858
float maximumMagneticFieldSquared;
5959
FusionQuaternion quaternion; // describes the Earth relative to the sensor
6060
FusionVector3 linearAcceleration;
61-
float rampedGain;
62-
bool zeroYawPending;
61+
float accMagP;
6362
} FusionAhrs;
6463

6564
//------------------------------------------------------------------------------
6665
// Function prototypes
6766

68-
void FusionAhrsInitialise(FusionAhrs * const fusionAhrs, const float gain, const float initialGain);
67+
void FusionAhrsInitialise(FusionAhrs * const fusionAhrs, const float gain, const float acc_conf_decay);
6968
void FusionAhrsSetGain(FusionAhrs * const fusionAhrs, const float gain);
70-
void FusionAhrsSetInitialGain(FusionAhrs * const fusionAhrs, const float initialGain);
69+
void FusionAhrsSetAccConfDecay(FusionAhrs * const fusionAhrs, const float acc_conf_decay);
7170
void FusionAhrsSetMagneticField(FusionAhrs * const fusionAhrs, const float minimumMagneticField, const float maximumMagneticField);
7271
void FusionAhrsUpdate(FusionAhrs * const fusionAhrs, const FusionVector3 gyroscope, const FusionVector3 accelerometer, const FusionVector3 magnetometer, const float samplePeriod);
7372
void FusionAhrsUpdateWithoutMagnetometer(FusionAhrs * const fusionAhrs, const FusionVector3 gyroscope, const FusionVector3 accelerometer, const float samplePeriod);

imu/Fusion/FusionTypes.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ static inline __attribute__((always_inline)) float FusionRadiansToDegrees(const
143143
*/
144144
static inline __attribute__((always_inline)) float FusionFastInverseSqrt(const float x) {
145145
if (x == 0.0) {
146-
return 0.0;
146+
return 1.0;
147147
}
148148
return 1.0 / sqrtf(x);
149149
}

imu/imu.c

+5-44
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,11 @@ static spi_bb_state m_spi_bb;
4343
static ICM20948_STATE m_icm20948_state;
4444
static BMI_STATE m_bmi_state;
4545
static imu_config m_settings;
46-
static float m_gyro_offset[3] = {0.0};
4746
static systime_t init_time;
4847
static bool imu_ready;
4948

5049
// Private functions
5150
static void imu_read_callback(float *accel, float *gyro, float *mag);
52-
static void terminal_gyro_info(int argc, const char **argv);
5351
static void rotate(float *input, float *rotation, float *output);
5452
int8_t user_i2c_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len);
5553
int8_t user_i2c_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint16_t len);
@@ -58,7 +56,6 @@ int8_t user_spi_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *data, uint16_t
5856

5957
void imu_init(imu_config *set) {
6058
m_settings = *set;
61-
memset(m_gyro_offset, 0, sizeof(m_gyro_offset));
6259

6360
imu_stop();
6461
imu_reset_orientation();
@@ -112,19 +109,13 @@ void imu_init(imu_config *set) {
112109
imu_init_bmi160_i2c(HW_I2C_SDA_PORT, HW_I2C_SDA_PIN,
113110
HW_I2C_SCL_PORT, HW_I2C_SCL_PIN);
114111
}
115-
116-
terminal_register_command_callback(
117-
"imu_gyro_info",
118-
"Print gyro offsets",
119-
0,
120-
terminal_gyro_info);
121112
}
122113

123114
void imu_reset_orientation(void) {
124115
imu_ready = false;
125116
init_time = chVTGetSystemTimeX();
126117
ahrs_init_attitude_info(&m_att);
127-
FusionAhrsInitialise(&m_fusionAhrs, 2.0, 20.0);
118+
FusionAhrsInitialise(&m_fusionAhrs, 10.0, 1.0);
128119
ahrs_update_all_parameters(1.0, 10.0, 0.0, 2.0);
129120
}
130121

@@ -298,9 +289,6 @@ void imu_get_calibration(float yaw, float *imu_cal) {
298289
float backup_gyro_offset_x = m_settings.gyro_offsets[0];
299290
float backup_gyro_offset_y = m_settings.gyro_offsets[1];
300291
float backup_gyro_offset_z = m_settings.gyro_offsets[2];
301-
float backup_gyro_comp_x = m_settings.gyro_offset_comp_fact[0];
302-
float backup_gyro_comp_y = m_settings.gyro_offset_comp_fact[1];
303-
float backup_gyro_comp_z = m_settings.gyro_offset_comp_fact[2];
304292

305293
// Override settings
306294
m_settings.sample_rate_hz = 1000;
@@ -315,14 +303,6 @@ void imu_get_calibration(float yaw, float *imu_cal) {
315303
m_settings.gyro_offsets[0] = 0;
316304
m_settings.gyro_offsets[1] = 0;
317305
m_settings.gyro_offsets[2] = 0;
318-
m_settings.gyro_offset_comp_fact[0] = 0;
319-
m_settings.gyro_offset_comp_fact[1] = 0;
320-
m_settings.gyro_offset_comp_fact[2] = 0;
321-
322-
// Clear computed offsets
323-
m_gyro_offset[0] = 0;
324-
m_gyro_offset[1] = 0;
325-
m_gyro_offset[2] = 0;
326306

327307
// Sample gyro for offsets
328308
float original_gyro_offsets[3] = {0, 0, 0};
@@ -419,18 +399,18 @@ void imu_get_calibration(float yaw, float *imu_cal) {
419399
m_settings.gyro_offsets[0] = backup_gyro_offset_x;
420400
m_settings.gyro_offsets[1] = backup_gyro_offset_y;
421401
m_settings.gyro_offsets[2] = backup_gyro_offset_z;
422-
m_settings.gyro_offset_comp_fact[0] = backup_gyro_comp_x;
423-
m_settings.gyro_offset_comp_fact[1] = backup_gyro_comp_y;
424-
m_settings.gyro_offset_comp_fact[2] = backup_gyro_comp_z;
425402

426403
ahrs_init_attitude_info(&m_att);
427404
FusionAhrsReinitialise(&m_fusionAhrs);
428405
}
429406

430407
static void imu_read_callback(float *accel, float *gyro, float *mag) {
431408
static uint32_t last_time = 0;
409+
410+
chSysLock();
432411
float dt = timer_seconds_elapsed_since(last_time);
433412
last_time = timer_time_now();
413+
chSysUnlock();
434414

435415
if (!imu_ready && ST2MS(chVTGetSystemTimeX() - init_time) > 1000) {
436416
ahrs_update_all_parameters(
@@ -440,7 +420,7 @@ static void imu_read_callback(float *accel, float *gyro, float *mag) {
440420
m_settings.madgwick_beta);
441421

442422
FusionAhrsSetGain(&m_fusionAhrs, m_settings.madgwick_beta);
443-
FusionAhrsSetInitialGain(&m_fusionAhrs, m_settings.madgwick_beta * 10.0);
423+
FusionAhrsSetAccConfDecay(&m_fusionAhrs, m_settings.accel_confidence_decay);
444424

445425
imu_ready = true;
446426
}
@@ -492,15 +472,6 @@ static void imu_read_callback(float *accel, float *gyro, float *mag) {
492472
for (int i = 0; i < 3; i++) {
493473
m_accel[i] -= m_settings.accel_offsets[i];
494474
m_gyro[i] -= m_settings.gyro_offsets[i];
495-
496-
if (m_settings.gyro_offset_comp_fact[i] > 0.0) {
497-
utils_step_towards(&m_gyro_offset[i], m_gyro[i], m_settings.gyro_offset_comp_fact[i] * dt);
498-
utils_truncate_number_abs(&m_gyro_offset[i], m_settings.gyro_offset_comp_clamp);
499-
} else {
500-
m_gyro_offset[i] = 0.0;
501-
}
502-
503-
m_gyro[i] -= m_gyro_offset[i];
504475
}
505476

506477
float gyro_rad[3];
@@ -535,16 +506,6 @@ static void imu_read_callback(float *accel, float *gyro, float *mag) {
535506
}
536507
}
537508

538-
static void terminal_gyro_info(int argc, const char **argv) {
539-
(void)argc;
540-
(void)argv;
541-
542-
commands_printf("Gyro offsets: [%.3f %.3f %.3f]\n",
543-
(double)(m_settings.gyro_offsets[0] + m_gyro_offset[0]),
544-
(double)(m_settings.gyro_offsets[1] + m_gyro_offset[1]),
545-
(double)(m_settings.gyro_offsets[2] + m_gyro_offset[2]));
546-
}
547-
548509
void rotate(float *input, float *rotation, float *output) {
549510
// Rotate imu offsets to match
550511
float s1 = sinf(rotation[2] * M_PI / 180.0);

timer.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include "stm32f4xx_conf.h"
2424

2525
// Settings
26-
#define TIMER_HZ 1e7
26+
#define TIMER_HZ 1.4e7
2727

2828
void timer_init(void) {
2929
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);

0 commit comments

Comments
 (0)