Browse Source

AP_NavEKF: rewrite readIMUData

master
Jonathan Challinger 10 years ago committed by Randy Mackay
parent
commit
cb0c424da1
  1. 97
      libraries/AP_NavEKF/AP_NavEKF.cpp
  2. 8
      libraries/AP_NavEKF/AP_NavEKF.h

97
libraries/AP_NavEKF/AP_NavEKF.cpp

@ -1124,16 +1124,9 @@ void NavEKF::UpdateStrapdownEquationsNED() @@ -1124,16 +1124,9 @@ void NavEKF::UpdateStrapdownEquationsNED()
// use weighted average of both IMU units for delta velocities
correctedDelVel12 = correctedDelVel1 * IMU1_weighting + correctedDelVel2 * (1.0f - IMU1_weighting);
// apply corrections for earths rotation rate and coning errors
// apply correction for earths rotation rate
// % * - and + operators have been overloaded
if (haveDeltaAngles) {
correctedDelAng = correctedDelAng - prevTnb * earthRateNED*dtIMUactual;
} else {
correctedDelAng = correctedDelAng - prevTnb * earthRateNED*dtIMUactual + (prevDelAng % correctedDelAng) * 8.333333e-2f;
}
// save current measurements
prevDelAng = correctedDelAng;
correctedDelAng = correctedDelAng - prevTnb * earthRateNED*dtIMUactual;
// convert the rotation vector to its equivalent quaternion
rotationMag = correctedDelAng.length();
@ -3978,6 +3971,33 @@ void NavEKF::ConstrainStates() @@ -3978,6 +3971,33 @@ void NavEKF::ConstrainStates()
terrainState = max(terrainState, state.position.z + rngOnGnd);
}
bool NavEKF::readDeltaVelocity(uint8_t ins_index, Vector3f &dVel, float &dVel_dt) {
const AP_InertialSensor &ins = _ahrs->get_ins();
if (ins_index < ins.get_accel_count()) {
if (ins.get_delta_velocity(ins_index,dVel)) {
dVel_dt = ins.get_delta_velocity_dt(ins_index);
} else {
dVel = ins.get_accel(ins_index) * dtIMUactual;
dVel_dt = dtIMUactual;
}
return true;
}
return false;
}
bool NavEKF::readDeltaAngle(uint8_t ins_index, Vector3f &dAng) {
const AP_InertialSensor &ins = _ahrs->get_ins();
if (ins_index < ins.get_gyro_count()) {
if (!ins.get_delta_angle(ins_index,dAng)) {
dAng = ins.get_gyro(ins_index) * dtIMUactual;
}
return true;
}
return false;
}
// update IMU delta angle and delta velocity measurements
void NavEKF::readIMUData()
{
@ -3986,44 +4006,35 @@ void NavEKF::readIMUData() @@ -3986,44 +4006,35 @@ void NavEKF::readIMUData()
dtIMUavg = 1.0f/ins.get_sample_rate();
dtIMUactual = max(ins.get_delta_time(),1.0e-3f);
// the imu sample time is sued as a common time reference throughout the filter
// the imu sample time is used as a common time reference throughout the filter
imuSampleTime_ms = hal.scheduler->millis();
bool dual_ins = ins.get_accel_health(0) && ins.get_accel_health(1);
haveDeltaAngles = true;
if (dual_ins) {
Vector3f dAngIMU1;
Vector3f dAngIMU2;
if(!ins.get_delta_velocity(0,dVelIMU1)) {
dVelIMU1 = ins.get_accel(0) * dtIMUactual;
}
if(!ins.get_delta_velocity(1,dVelIMU2)) {
dVelIMU2 = ins.get_accel(1) * dtIMUactual;
}
if(!ins.get_delta_angle(0, dAngIMU1)) {
haveDeltaAngles = false;
dAngIMU1 = ins.get_gyro(0) * dtIMUactual;
}
if(!ins.get_delta_angle(1, dAngIMU2)) {
haveDeltaAngles = false;
dAngIMU2 = ins.get_gyro(1) * dtIMUactual;
}
dAngIMU = (dAngIMU1+dAngIMU2) * 0.5f;
if (ins.get_accel_health(0) && ins.get_accel_health(1)) {
// dual accel mode
readDeltaVelocity(0, dVelIMU1, dtDelVel1);
readDeltaVelocity(1, dVelIMU2, dtDelVel2);
} else {
if(!ins.get_delta_velocity(dVelIMU1)) {
dVelIMU1 = ins.get_accel() * dtIMUactual;
}
// single accel mode - one of the first two accelerometers are unhealthy
// read primary accelerometer into dVelIMU1 and copy to dVelIMU2
readDeltaVelocity(ins.get_primary_accel(), dVelIMU1, dtDelVel1);
dtDelVel2 = dtDelVel1;
dVelIMU2 = dVelIMU1;
}
if(!ins.get_delta_angle(dAngIMU)) {
haveDeltaAngles = false;
dAngIMU = ins.get_gyro() * dtIMUactual;
}
if (ins.get_gyro_health(0) && ins.get_gyro_health(1)) {
// dual gyro mode - average first two gyros
Vector3f dAng;
dAngIMU.zero();
readDeltaAngle(0, dAng);
dAngIMU += dAng;
readDeltaAngle(1, dAng);
dAngIMU += dAng;
dAngIMU *= 0.5f;
} else {
// single gyro mode - one of the first two gyros are unhealthy or don't exist
// just read primary gyro
readDeltaAngle(ins.get_primary_gyro(), dAngIMU);
}
}
@ -4493,7 +4504,6 @@ void NavEKF::InitialiseVariables() @@ -4493,7 +4504,6 @@ void NavEKF::InitialiseVariables()
hgtMea = 0;
storeIndex = 0;
lastGyroBias.zero();
prevDelAng.zero();
lastAngRate.zero();
lastAccel1.zero();
lastAccel2.zero();
@ -4549,7 +4559,6 @@ void NavEKF::InitialiseVariables() @@ -4549,7 +4559,6 @@ void NavEKF::InitialiseVariables()
inhibitMagStates = true;
gndOffsetValid = false;
flowXfailed = false;
haveDeltaAngles = false;
validOrigin = false;
gndEffectMode = false;
gpsSpdAccuracy = 0.0f;

8
libraries/AP_NavEKF/AP_NavEKF.h

@ -330,6 +330,10 @@ private: @@ -330,6 +330,10 @@ private:
// initialise the covariance matrix
void CovarianceInit();
// helper functions for readIMUData
bool readDeltaVelocity(uint8_t ins_index, Vector3f &dVel, float &dVel_dt);
bool readDeltaAngle(uint8_t ins_index, Vector3f &dAng);
// update IMU delta angle and delta velocity measurements
void readIMUData();
@ -535,7 +539,6 @@ private: @@ -535,7 +539,6 @@ private:
Vector3f correctedDelVel2; // delta velocities along the XYZ body axes for IMU2 corrected for errors (m/s)
Vector3f summedDelAng; // corrected & summed delta angles about the xyz body axes (rad)
Vector3f summedDelVel; // corrected & summed delta velocities along the XYZ body axes (m/s)
Vector3f prevDelAng; // previous delta angle use for INS coning error compensation
Vector3f lastGyroBias; // previous gyro bias vector used by filter divergence check
Matrix3f prevTnb; // previous nav to body transformation used for INS earth rotation compensation
ftype accNavMag; // magnitude of navigation accel - used to adjust GPS obs variance (m/s^2)
@ -722,7 +725,8 @@ private: @@ -722,7 +725,8 @@ private:
float rangeAtArming; // range finder measurement when armed
uint32_t timeAtArming_ms; // time in msec that the vehicle armed
bool haveDeltaAngles;
float dtDelVel1;
float dtDelVel2;
// states held by optical flow fusion across time steps
// optical flow X,Y motion compensated rate measurements are fused across two time steps

Loading…
Cancel
Save