Estimation/StrapdownINS/ESKF/predictPreintegrated.mo
Download original .moGitHub source
Documentation: Estimation.StrapdownINS.ESKF.predictPreintegrated
within Estimation.StrapdownINS.ESKF;
function predictPreintegrated
"Apply one closed-form IMU preintegral and its exact local transition"
input State previous;
input Avionics.ImuSample imu;
input Real gravityWorldEnu_m_s2[3];
input Estimation.StrapdownINS.ProcessNoise processNoise;
output State predicted;
protected
Real dt;
Real deltaPositionBodyFlu_m[3];
Real deltaVelocityBodyFlu_m_s[3];
Real deltaQuaternionBodyFlu[4];
Real deltaRotationBodyFlu[3, 3];
Real previousRotationWorldBody[3, 3];
Real transition[TangentLength, TangentLength];
Real rotationIncrement_rad[3];
Real equivalentAngularVelocity_rad_s[3];
Real equivalentSpecificForce_m_s2[3];
Real A[TangentLength, TangentLength];
algorithm
dt := imu.integrationTime_s;
(deltaPositionBodyFlu_m,
deltaVelocityBodyFlu_m_s,
deltaQuaternionBodyFlu) :=
Estimation.StrapdownINS.correctPreintegratedImu(
imu,
previous.gyroscopeBiasBodyFlu_rad_s,
previous.accelerometerBiasBodyFlu_m_s2);
deltaRotationBodyFlu :=
LieGroups.SO3.Quat.to_DCM(deltaQuaternionBodyFlu);
previousRotationWorldBody :=
LieGroups.SO3.Quat.to_DCM(previous.quaternionWorldBody);
transition := zeros(TangentLength, TangentLength);
transition[1:3, 1:3] := transpose(deltaRotationBodyFlu);
transition[1:3, 4:6] := transpose(deltaRotationBodyFlu) * dt;
transition[1:3, 7:9] := -transpose(deltaRotationBodyFlu)
* LieGroups.SO3.Quat.wedge(deltaPositionBodyFlu_m);
transition[1:3, 10:12] := transpose(deltaRotationBodyFlu)
* imu.deltaPositionGyroscopeBiasJacobian_m_s;
transition[1:3, 13:15] := transpose(deltaRotationBodyFlu)
* imu.deltaPositionAccelerometerBiasJacobian_s2;
transition[4:6, 4:6] := transpose(deltaRotationBodyFlu);
transition[4:6, 7:9] := -transpose(deltaRotationBodyFlu)
* LieGroups.SO3.Quat.wedge(deltaVelocityBodyFlu_m_s);
transition[4:6, 10:12] := transpose(deltaRotationBodyFlu)
* imu.deltaVelocityGyroscopeBiasJacobian_m;
transition[4:6, 13:15] := transpose(deltaRotationBodyFlu)
* imu.deltaVelocityAccelerometerBiasJacobian_s;
transition[7:9, 7:9] := transpose(deltaRotationBodyFlu);
transition[7:9, 10:12] :=
imu.deltaRotationGyroscopeBiasJacobian_s;
transition[10:12, 10:12] := 1.0 * identity(3);
transition[13:15, 13:15] := 1.0 * identity(3);
rotationIncrement_rad :=
LieGroups.SO3.Quat.log_map(deltaQuaternionBodyFlu);
equivalentAngularVelocity_rad_s := rotationIncrement_rad / dt;
equivalentSpecificForce_m_s2 :=
LieGroups.SO3.Quat.left_jacobian_inv(rotationIncrement_rad)
* deltaVelocityBodyFlu_m_s / dt;
A := continuousTransition(
equivalentAngularVelocity_rad_s, equivalentSpecificForce_m_s2);
predicted := predictCovariance(previous, transition, A, processNoise, dt);
predicted := State(
positionWorldEnu_m=previous.positionWorldEnu_m
+ previous.velocityWorldEnu_m_s * dt
+ 0.5 * gravityWorldEnu_m_s2 * dt * dt
+ previousRotationWorldBody * deltaPositionBodyFlu_m,
velocityWorldEnu_m_s=previous.velocityWorldEnu_m_s
+ gravityWorldEnu_m_s2 * dt
+ previousRotationWorldBody * deltaVelocityBodyFlu_m_s,
quaternionWorldBody=LieGroups.SO3.Quat.normalize(
LieGroups.SO3.Quat.product(
previous.quaternionWorldBody, deltaQuaternionBodyFlu)),
gyroscopeBiasBodyFlu_rad_s=previous.gyroscopeBiasBodyFlu_rad_s,
accelerometerBiasBodyFlu_m_s2=
previous.accelerometerBiasBodyFlu_m_s2,
covariance=predicted.covariance,
covarianceRoot=predicted.covarianceRoot,
barometerBiasCrossCovariance=predicted.barometerBiasCrossCovariance,
barometerBias_m=previous.barometerBias_m,
barometerBiasVariance_m2=previous.barometerBiasVariance_m2,
useJointBarometerBias=previous.useJointBarometerBias,
useSquareRootCovariance=previous.useSquareRootCovariance);
end predictPreintegrated;