CogniPilot

MODELICA LIBRARY · ENGINEERING REFERENCE

function

Estimation.FusionHorizon.navigationEstimate

Publish the predicted pose in the canonical estimator-independent fields

Public declarations

Explicit source declarations; dimensions, modifications and defaults are shown as written, without evaluation.

RoleNameTypeDimensions / attributes / defaultDescription
inputposeEstimation.FusionHorizon.Pose
inputangularVelocityBodyFlu_rad_sReal[3]Already corrected by the estimator's gyroscope bias
inputspecificForceMeasuredBodyFlu_m_s2Real[3]
inputaccelerometerBiasBodyFlu_m_s2Real[3]
inputgravityWorldEnu_m_s2Real[3]
outputpositionWorldEnu_mReal[3]
outputvelocityWorldEnu_m_sReal[3]
outputaccelerationWorldEnu_m_s2Real[3]
outputquaternionWorldBodyReal[4]
outputrotationWorldBodyReal[3, 3]
outputeulerRpy_radReal[3]
outputangularVelocityWorldEnu_rad_sReal[3]

Modelica declarations and implementation

Show parameters, interfaces and source

Parameters, inputs, outputs, defaults and equations from the source file.

function navigationEstimate
  "Publish the predicted pose in the canonical estimator-independent fields"
  input Estimation.FusionHorizon.Pose pose;
  input Real angularVelocityBodyFlu_rad_s[3]
    "Already corrected by the estimator's gyroscope bias";
  input Real specificForceMeasuredBodyFlu_m_s2[3];
  input Real accelerometerBiasBodyFlu_m_s2[3];
  input Real gravityWorldEnu_m_s2[3];
  output Real positionWorldEnu_m[3];
  output Real velocityWorldEnu_m_s[3];
  output Real accelerationWorldEnu_m_s2[3];
  output Real quaternionWorldBody[4];
  output Real rotationWorldBody[3, 3];
  output Real eulerRpy_rad[3];
  output Real angularVelocityWorldEnu_rad_s[3];
protected
  Real eulerB321_rad[3];
  Real correctedSpecificForceBody_m_s2[3];
algorithm
  // Separate outputs rather than one Avionics.NavigationEstimate, and the
  // caller assigns the connector field by field. That is how every estimator in
  // this library publishes: a whole record assigned to a connector is not
  // something OpenModelica generates code for, and Rumoca counts it short of
  // the fields it defines, so the model comes out unbalanced.
  //
  // Same construction the filters publish, driven by the predicted pose at now
  // instead of the filter state at the horizon. The redundant attitude forms
  // are produced here rather than by the consumer so no consumer depends on a
  // representation choice.
  rotationWorldBody := LieGroups.SO3.Quat.to_DCM(pose.quaternionWorldBody);
  eulerB321_rad := LieGroups.SO3.EulerB321.from_Quat(pose.quaternionWorldBody);
  correctedSpecificForceBody_m_s2 := specificForceMeasuredBodyFlu_m_s2
    - accelerometerBiasBodyFlu_m_s2;
  positionWorldEnu_m := pose.positionWorldEnu_m;
  velocityWorldEnu_m_s := pose.velocityWorldEnu_m_s;
  accelerationWorldEnu_m_s2 := rotationWorldBody
    * correctedSpecificForceBody_m_s2 + gravityWorldEnu_m_s2;
  quaternionWorldBody := pose.quaternionWorldBody;
  eulerRpy_rad := {eulerB321_rad[3], eulerB321_rad[2], eulerB321_rad[1]};
  angularVelocityWorldEnu_rad_s := rotationWorldBody
    * angularVelocityBodyFlu_rad_s;
end navigationEstimate;