Estimation/StrapdownINS/updateTerrainAltitude.mo
Download original .moGitHub source
Documentation: Estimation.StrapdownINS.updateTerrainAltitude
within Estimation.StrapdownINS;
function updateTerrainAltitude
"Estimate locally horizontal terrain altitude from a downward slant range"
input Boolean initializedPrevious;
input Real altitudePrevious_m;
input Real variancePrevious_m2;
input Real positionWorldEnu_m[3];
input Real quaternionWorldBody[4];
input Real navigationCovarianceLocal[15, 15];
input Avionics.OpticalFlowSample measurement;
input Real dt(unit = "s");
input Real initialAltitude_m = 0.0;
input Real initialVariance_m2 = 4.0;
input Real processNoise_m2_s = 1.0e-3;
input Real minimumCosTilt = 0.5;
input Real minimumQuality = 0.2;
output Boolean initializedNext;
output Real altitudeNext_m;
output Real varianceNext_m2;
output Boolean accepted;
protected
Real rotationWorldBody[3, 3];
Real cosTilt;
Real terrainH[15];
Real observedAltitude_m;
Real predictedVariance_m2;
Real observationVariance_m2;
Real innovationVariance_m2;
Real gain;
Boolean usable;
algorithm
rotationWorldBody := LieGroups.SO3.Quat.to_DCM(quaternionWorldBody);
cosTilt := rotationWorldBody[3, 3];
terrainH := zeros(15);
terrainH[1:3] := rotationWorldBody[3, :];
// R_new = R*Exp(delta): d(R[3,3])/d(delta) = {-R[3,2],R[3,1],0}.
terrainH[7:9] := measurement.groundDistance_m
* {rotationWorldBody[3, 2], -rotationWorldBody[3, 1], 0.0};
observedAltitude_m := positionWorldEnu_m[3]
- measurement.groundDistance_m * cosTilt;
predictedVariance_m2 := max(
if initializedPrevious then variancePrevious_m2 else initialVariance_m2,
1.0e-12) + max(processNoise_m2_s, 0.0) * max(dt, 0.0);
observationVariance_m2 := cosTilt * cosTilt
* measurement.groundDistanceVariance_m2
+ terrainH * navigationCovarianceLocal * terrainH;
innovationVariance_m2 := predictedVariance_m2 + observationVariance_m2;
usable := measurement.valid and measurement.fresh
and measurement.quality >= minimumQuality
and measurement.groundDistance_m > 0.05
and measurement.groundDistanceVariance_m2 > 0.0
and cosTilt >= minimumCosTilt
and abs(observedAltitude_m) < 1.0e100
and observationVariance_m2 > 0.0
and innovationVariance_m2 > 1.0e-12;
if usable then
gain := predictedVariance_m2 / innovationVariance_m2;
altitudeNext_m := (if initializedPrevious then altitudePrevious_m
else initialAltitude_m) + gain * (observedAltitude_m
- (if initializedPrevious then altitudePrevious_m else initialAltitude_m));
varianceNext_m2 := max((1.0 - gain) * predictedVariance_m2, 1.0e-12);
initializedNext := true;
accepted := true;
else
altitudeNext_m := if initializedPrevious then altitudePrevious_m
else initialAltitude_m;
varianceNext_m2 := predictedVariance_m2;
initializedNext := initializedPrevious;
accepted := false;
end if;
end updateTerrainAltitude;