function
Tests.HeadingConsiderTests.checkHeading
Public declarations
Explicit source declarations; dimensions, modifications and defaults are shown as written, without evaluation.
| Role | Name | Type | Dimensions / attributes / default | Description |
|---|---|---|---|---|
| output | result | Boolean | |
Modelica declarations and implementation
Show parameters, interfaces and source
Parameters, inputs, outputs, defaults and equations from the source file.
function checkHeading
output Boolean result;
protected
Estimation.StrapdownINS.ESKF.State prior;
Estimation.StrapdownINS.ESKF.State posterior;
Avionics.MagnetometerSample measurement;
Real coupling[15];
Real magneticField[3];
Real covariance[15, 15];
Real inverseCovariance[15, 15];
Real angles[3];
Boolean accepted;
Boolean factorized;
Integer outcome;
Real nis;
algorithm
coupling := fill(0.1, 15);
covariance := 0.01 * identity(15) + transpose({coupling}) * {coupling};
prior := Estimation.StrapdownINS.ESKF.State(
barometerBiasCrossCovariance=zeros(15),
barometerBias_m=0.0, barometerBiasVariance_m2=0.0, useJointBarometerBias=false,
positionWorldEnu_m={1, 2, 3},
velocityWorldEnu_m_s={0.1, 0.2, 0.3},
quaternionWorldBody={1, 0, 0, 0},
gyroscopeBiasBodyFlu_rad_s={0.01, -0.02, 0.03},
accelerometerBiasBodyFlu_m_s2={0.02, -0.01, 0.015},
covariance=covariance,
useSquareRootCovariance=false, covarianceRoot=zeros(15, 15));
magneticField := {-1.59e-6, 20.04e-6, -47.91e-6};
measurement := Avionics.MagnetometerSample(
valid=true, fresh=true, timestamp_s=0.0,
magneticFieldBodyFlu_T=transpose(LieGroups.SO3.Quat.to_DCM(
LieGroups.SO3.EulerB321.to_Quat({0.1, 0, 0}))) * magneticField,
covarianceBody_T2=1.0e-12 * identity(3));
(posterior, accepted, outcome, nis) :=
Estimation.StrapdownINS.ESKF.correctMagnetometer(
prior, measurement, magneticField, 6.0);
assert(accepted, "Usable heading observation was rejected");
assert(Tests.Assertions.maxAbsVector(
posterior.positionWorldEnu_m - prior.positionWorldEnu_m) < 1.0e-12
and Tests.Assertions.maxAbsVector(
posterior.velocityWorldEnu_m_s - prior.velocityWorldEnu_m_s) < 1.0e-12
and Tests.Assertions.maxAbsVector(
posterior.accelerometerBiasBodyFlu_m_s2
- prior.accelerometerBiasBodyFlu_m_s2) < 1.0e-12,
"Heading observation changed a considered translation or accelerometer bias");
assert(Tests.Assertions.maxAbsVector(
posterior.gyroscopeBiasBodyFlu_rad_s[1:2]
- prior.gyroscopeBiasBodyFlu_rad_s[1:2]) < 1.0e-12
and abs(posterior.gyroscopeBiasBodyFlu_rad_s[3]
- prior.gyroscopeBiasBodyFlu_rad_s[3]) > 1.0e-8,
"Heading observation did not restrict gyro-bias learning to the vertical");
angles := LieGroups.SO3.EulerB321.from_Quat(posterior.quaternionWorldBody);
assert(angles[1] > 0.0 and angles[1] < 0.1
and abs(angles[2]) + abs(angles[3]) < 1.0e-12,
"Heading correction did not rotate only about the vertical");
assert(Tests.Assertions.maxAbsMatrix(posterior.covariance[13:15, 13:15]
- prior.covariance[13:15, 13:15]) < 1.0e-12,
"Heading observation reduced a considered accelerometer-bias variance");
(inverseCovariance, factorized) := LinearAlgebra.solveSPD(
posterior.covariance, identity(15));
assert(factorized, "Constrained heading gain lost positive definiteness");
result := true;
end checkHeading;