mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-12 02:48:28 -04:00
DCM: remove the taylor expansion optimisation for renormalisation
The sqrt() costs about 44usec on a 2560, which is small enough for us not to worry about the speed. This also changes the range of values where we declare a blowup to much less likely, which means we can cope with larger delta_t glitches
This commit is contained in:
parent
128f19cdf7
commit
5cfe1ad5dc
@ -260,21 +260,42 @@ AP_DCM::renorm(Vector3f const &a, int &problem)
|
|||||||
{
|
{
|
||||||
float renorm_val;
|
float renorm_val;
|
||||||
|
|
||||||
renorm_val = a * a;
|
// numerical errors will slowly build up over time in DCM,
|
||||||
|
// causing inaccuracies. We can keep ahead of those errors
|
||||||
|
// using the renormalization technique from the DCM IMU paper
|
||||||
|
// (see equations 18 to 21).
|
||||||
|
|
||||||
if (renorm_val < 1.5625f && renorm_val > 0.64f) { // Check if we are OK to use Taylor expansion
|
// For APM we don't bother with the taylor expansion
|
||||||
renorm_val = 0.5 * (3 - renorm_val); // eq.21
|
// optimisation from the paper as on our 2560 CPU the cost of
|
||||||
} else if (renorm_val < 100.0f && renorm_val > 0.01f) {
|
// the sqrt() is 44 microseconds, and the small time saving of
|
||||||
renorm_val = 1.0 / sqrt(renorm_val);
|
// the taylor expansion is not worth the potential of
|
||||||
renorm_sqrt_count++;
|
// additional error buildup.
|
||||||
} else {
|
|
||||||
problem = 1;
|
// Note that we can get significant renormalisation values
|
||||||
SITL_debug("ERROR: DCM renormalisation error. renorm_val=%f\n",
|
// when we have a larger delta_t due to a glitch eleswhere in
|
||||||
renorm_val);
|
// APM, such as a I2c timeout or a set of EEPROM writes. While
|
||||||
renorm_blowup_count++;
|
// we would like to avoid these if possible, if it does happen
|
||||||
|
// we don't want to compound the error by making DCM less
|
||||||
|
// accurate.
|
||||||
|
|
||||||
|
renorm_val = 1.0 / sqrt(a * a);
|
||||||
|
|
||||||
|
if (renorm_val > 2.0 || renorm_val < 0.5) {
|
||||||
|
// this is larger than it should get - log it as a warning
|
||||||
|
renorm_range_count++;
|
||||||
|
if (renorm_val > 1.0e6 || renorm_val < 1.0e-6) {
|
||||||
|
// we are getting values which are way out of
|
||||||
|
// range, we will reset the matrix and hope we
|
||||||
|
// can recover our attitude using drift
|
||||||
|
// correction before we hit the ground!
|
||||||
|
problem = 1;
|
||||||
|
SITL_debug("ERROR: DCM renormalisation error. renorm_val=%f\n",
|
||||||
|
renorm_val);
|
||||||
|
renorm_blowup_count++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(a * renorm_val);
|
return (a * renorm_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************/
|
/**************************************************/
|
||||||
|
@ -68,7 +68,7 @@ public:
|
|||||||
float yaw; // Radians
|
float yaw; // Radians
|
||||||
|
|
||||||
uint8_t gyro_sat_count;
|
uint8_t gyro_sat_count;
|
||||||
uint8_t renorm_sqrt_count;
|
uint8_t renorm_range_count;
|
||||||
uint8_t renorm_blowup_count;
|
uint8_t renorm_blowup_count;
|
||||||
|
|
||||||
float kp_roll_pitch() { return _kp_roll_pitch; }
|
float kp_roll_pitch() { return _kp_roll_pitch; }
|
||||||
|
@ -49,7 +49,7 @@ public:
|
|||||||
float yaw; // Radians
|
float yaw; // Radians
|
||||||
|
|
||||||
uint8_t gyro_sat_count;
|
uint8_t gyro_sat_count;
|
||||||
uint8_t renorm_sqrt_count;
|
uint8_t renorm_range_count;
|
||||||
uint8_t renorm_blowup_count;
|
uint8_t renorm_blowup_count;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user