CogniPilot

MODELICA LIBRARY · ENGINEERING REFERENCE

record

Avionics.EstimatorStatus

Algorithm-neutral estimator health and correction status

Public declarations

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

RoleNameTypeDimensions / attributes / defaultDescription
fieldinitializedBoolean
fieldpredictionAcceptedBoolean
fieldmocapCorrectionAcceptedBoolean
fieldgpsPositionCorrectionAcceptedBoolean
fieldgpsVelocityCorrectionAcceptedBoolean
fieldmagnetometerCorrectionAcceptedBoolean
fieldbarometerCorrectionAcceptedBoolean
fieldterrainCorrectionAcceptedBooleanA fresh downward-range sample updated the terrain-altitude filter
fieldopticalFlowCorrectionAcceptedBoolean
fieldconsecutiveRejectedCorrectionsIntegerConsecutive attempted aiding corrections rejected by conditioning or innovation gating; zero after any accepted correction
fieldrejectionElapsed_sReal(unit = "s")Wall-clock time the anchor source has held without moving the state. Advanced on ESTIMATOR TICKS, not on aiding attempts and not on the sensors` valid duty cycle, so it means the same elapsed time whatever rate the block is wired at and whatever waveform the drivers put on `valid`. Cleared when the anchor accepts, when the anchor changes, or when there is no anchor at all
fieldmocapConsecutiveRejectionsIntegerConsecutive rejections of the mocap source alone
fieldgpsConsecutiveRejectionsIntegerConsecutive rejections of the GPS source alone
fieldopticalFlowConsecutiveRejectionsIntegerConsecutive rejections of the optical-flow source alone. The per-source counters exist because the aggregate above cannot show a failed sensor while a healthy one keeps resetting it: a source rejected on every one of its own samples is visible here from the first sample, whatever the other sources are doing
fieldcorrectionOutcomeIntegerOutcome of this tick's attempted aiding correction: 0 none attempted, 1 accepted, 2 rejected as not finite, 3 rejected by the innovation gate, 4 rejected because the innovation covariance did not factor, 5 rejected because the sensor-reported measurement covariance was not finite or claimed non-positive noise, 7 the state was re-seeded from a fresh anchor sample by the automatic recovery ladder. Every outcome is named rather than inferred from the absence of other flags
fieldacceptedCorrectionCountIntegerMonotonic count of SHIFTED FUSION INSTANTS since the last reset: the number of estimator ticks on which at least one aiding correction was accepted. AT MOST ONE PER ESTIMATOR TICK, and that is a contract on this field rather than a property of any particular filter. It counts instants and not measurements deliberately. The consumer this field exists for is an output predictor, which must recompose its buffered window once per tick on which the state it composes onto MOVED; two measurements fused into the same tick move it once, and counting them twice would ask for a second recomposition that has nothing to recompose. A filter fusing several sources in one tick coalesces their acceptance flags here and must not increment per measurement: at a delayed fusion horizon every ripe measurement is an accepted correction, and the aiding set of a small multirotor offers well over a hundred a second against a recomposition budget of single digits. correctionOutcome is a LEVEL: it stands for the whole estimator tick, which at a 100 Hz filter behind an 800 Hz consumer is eight consumer ticks. A consumer that must act once per correction cannot edge-detect that level -- back-to-back accepted corrections hold it true across the boundary and the second one is invisible -- so the boundary carries the count and the consumer compares it with the one it last saw. That is the only well-defined edge across a rate change, which is why it is here and not reconstructed downstream
fieldcorrectionSourceIntegerAiding source the outcome above refers to: 0 none, 1 mocap, 2 GPS, 3 optical flow, 4 magnetometer, 5 barometer. With multiple corrections, ESKF reports the first attempted source in priority order mocap, GPS, optical flow, barometer, magnetometer. Per-source acceptance flags describe the other corrections independently
fieldnormalizedInnovationSquaredRealNIS of this tick's attempted aiding correction; zero if none was attempted
fieldrecoveryStageIntegerAutomatic recovery ladder: 0 nominal, 1 covariance ramping toward the mission envelope with the state untouched, 2 anchor still divergent at the envelope. THIS IS THE DEGRADED-MODE SIGNAL. It is the field a consumer reads to decide that the navigation solution is no longer trustworthy enough for position-holding flight, and it is deliberately separate from NavigationEstimate.valid, which says only that the published numbers are numbers. The separation is not cosmetic: on the deployed stack the rate loop takes body rates from the estimator, so clearing valid clears RatesValid, zeroes the motors and latches the fault in every mode including ACRO. A degraded navigation solution must be able to demote the flight mode without stopping the vehicle flying, so stage 2 raises this field and leaves valid alone. An optional third stage, off by default and enabled per deployment, re-seeds position and velocity from a fresh anchor sample once the divergence has outlasted a longer window; it is reported on the separate reseeded flag and reseedCount rather than as a distinct recoveryStage value, so a filter with the stage disabled reports only stages 0 to 2 and a commanded reset stays the only other re-seed
fieldimuPayloadHeldBooleanTrue when this tick`s published IMU-derived outputs -- angular velocity, world acceleration and the estimate timestamp -- were held from an earlier sample because the current inertial reading was not finite. Those three fields are computed from the raw sample rather than from the filter state, so they bypass the state finiteness guard entirely; holding them is what stops a NaN reaching a consumer. This flag, not NavigationEstimate.valid, is the signal that it happened: dropping valid clears RatesValid and latches a motors-zero fault in every mode, so using it to report a transient inertial glitch would turn a recoverable sample dropout into a crash
fieldanchorSourceIntegerSource currently anchoring the solution, by the same Source* codes as correctionSource. The recovery ladder is timed on this source alone, and a change of anchor restarts that timing
fieldreseededBooleanTrue on the tick the automatic recovery ladder re-seeded the state from a fresh anchor sample. It is an OPTIONAL, off-by-default stage, so on a filter that leaves it disabled this is always false and the commanded reset input is the only path that re-seeds. When it fires, correctionOutcome carries the CorrectionReseeded code rather than an acceptance code
fieldreseedCountIntegerMonotonic count of automatic re-seeds since the last reset. Like acceptedCorrectionCount it gives a consumer a well-defined edge across a rate change, since reseeded is a per-tick level
fieldalignmentSourceIntegerEstimation.StrapdownINS.Alignment* code of the initial attitude alignment in force: which sample leveled the filter and whether a heading was available. Recorded so a flight log shows what the attitude started from
fieldalignmentSpecificForceBodyFlu_m_s2Real[3](each unit = "m/s2")The low-pass specific force the quasi-static test reads and the initial alignment levels on, zero until the first usable IMU sample
fieldquietElapsed_sReal(unit = "s")Time the low-pass IMU has reported a quasi-static vehicle: specific force within tolerance of gravity and angular rate below the limit. A tick that fails the test costs one tick and sustained motion drains it to zero. Gates the initial alignment and the zero-velocity update
fieldpseudoPositionCorrectionAcceptedBooleanTrue on a tick the synthetic hold-position measurement moved the state
fieldzeroVelocityCorrectionAcceptedBooleanTrue on a tick the synthetic zero-velocity measurement moved the state

Modelica declarations and implementation

Show parameters, interfaces and source

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

record EstimatorStatus
    "Algorithm-neutral estimator health and correction status"
    Boolean initialized;
    Boolean predictionAccepted;
    Boolean mocapCorrectionAccepted;
    Boolean gpsPositionCorrectionAccepted;
    Boolean gpsVelocityCorrectionAccepted;
    Boolean magnetometerCorrectionAccepted;
    Boolean barometerCorrectionAccepted;
    Boolean terrainCorrectionAccepted
      "A fresh downward-range sample updated the terrain-altitude filter";
    Boolean opticalFlowCorrectionAccepted;
    Integer consecutiveRejectedCorrections
      "Consecutive attempted aiding corrections rejected by conditioning
       or innovation gating; zero after any accepted correction";
    Real rejectionElapsed_s(unit = "s")
      "Wall-clock time the anchor source has held without moving the
       state. Advanced on ESTIMATOR TICKS, not on aiding attempts and not
       on the sensors` valid duty cycle, so it means the same elapsed time
       whatever rate the block is wired at and whatever waveform the
       drivers put on `valid`. Cleared when the anchor accepts, when the
       anchor changes, or when there is no anchor at all";
    Integer mocapConsecutiveRejections
      "Consecutive rejections of the mocap source alone";
    Integer gpsConsecutiveRejections
      "Consecutive rejections of the GPS source alone";
    Integer opticalFlowConsecutiveRejections
      "Consecutive rejections of the optical-flow source alone. The
       per-source counters exist because the aggregate above cannot show
       a failed sensor while a healthy one keeps resetting it: a source
       rejected on every one of its own samples is visible here from the
       first sample, whatever the other sources are doing";
    Integer correctionOutcome
      "Outcome of this tick's attempted aiding correction: 0 none
       attempted, 1 accepted, 2 rejected as not finite, 3 rejected by the
       innovation gate, 4 rejected because the innovation covariance did
       not factor, 5 rejected because the sensor-reported measurement
       covariance was not finite or claimed non-positive noise, 7 the state
       was re-seeded from a fresh anchor sample by the automatic recovery
       ladder. Every outcome is named rather than inferred from the absence
       of other flags";
    Integer acceptedCorrectionCount
      "Monotonic count of SHIFTED FUSION INSTANTS since the last reset: the
       number of estimator ticks on which at least one aiding correction was
       accepted. AT MOST ONE PER ESTIMATOR TICK, and that is a contract on
       this field rather than a property of any particular filter.

       It counts instants and not measurements deliberately. The consumer this
       field exists for is an output predictor, which must recompose its
       buffered window once per tick on which the state it composes onto
       MOVED; two measurements fused into the same tick move it once, and
       counting them twice would ask for a second recomposition that has
       nothing to recompose.

       A filter fusing several sources in one tick coalesces their acceptance
       flags here and must not increment per measurement: at a delayed fusion horizon
       every ripe measurement is an accepted correction, and the aiding set of
       a small multirotor offers well over a hundred a second against a
       recomposition budget of single digits.

       correctionOutcome is a LEVEL: it stands for the whole estimator
       tick, which at a 100 Hz filter behind an 800 Hz consumer is
       eight consumer ticks. A consumer that must act once per
       correction cannot edge-detect that level -- back-to-back
       accepted corrections hold it true across the boundary and the
       second one is invisible -- so the boundary carries the count and
       the consumer compares it with the one it last saw. That is the
       only well-defined edge across a rate change, which is why it is
       here and not reconstructed downstream";
    Integer correctionSource
      "Aiding source the outcome above refers to: 0 none, 1 mocap, 2 GPS,
       3 optical flow, 4 magnetometer, 5 barometer. With multiple corrections,
       ESKF reports the first attempted source in priority order mocap, GPS,
       optical flow, barometer, magnetometer. Per-source acceptance flags
       describe the other corrections independently";
    Real normalizedInnovationSquared
      "NIS of this tick's attempted aiding correction; zero if none was attempted";
    Integer recoveryStage
      "Automatic recovery ladder: 0 nominal, 1 covariance ramping toward
       the mission envelope with the state untouched, 2 anchor still
       divergent at the envelope.

       THIS IS THE DEGRADED-MODE SIGNAL. It is the field a consumer reads
       to decide that the navigation solution is no longer trustworthy
       enough for position-holding flight, and it is deliberately separate
       from NavigationEstimate.valid, which says only that the published
       numbers are numbers. The separation is not cosmetic: on the
       deployed stack the rate loop takes body rates from the estimator,
       so clearing valid clears RatesValid, zeroes the motors and latches
       the fault in every mode including ACRO. A degraded navigation
       solution must be able to demote the flight mode without stopping
       the vehicle flying, so stage 2 raises this field and leaves valid
       alone.

       An optional third stage, off by default and enabled per deployment,
       re-seeds position and velocity from a fresh anchor sample once the
       divergence has outlasted a longer window; it is reported on the
       separate reseeded flag and reseedCount rather than as a distinct
       recoveryStage value, so a filter with the stage disabled reports only
       stages 0 to 2 and a commanded reset stays the only other re-seed";
    Boolean imuPayloadHeld
      "True when this tick`s published IMU-derived outputs -- angular
       velocity, world acceleration and the estimate timestamp -- were held
       from an earlier sample because the current inertial reading was not
       finite.

       Those three fields are computed from the raw sample rather than from
       the filter state, so they bypass the state finiteness guard entirely;
       holding them is what stops a NaN reaching a consumer. This flag, not
       NavigationEstimate.valid, is the signal that it happened: dropping
       valid clears RatesValid and latches a motors-zero fault in every
       mode, so using it to report a transient inertial glitch would turn a
       recoverable sample dropout into a crash";
    Integer anchorSource
      "Source currently anchoring the solution, by the same Source* codes
       as correctionSource. The recovery ladder is timed on this source
       alone, and a change of anchor restarts that timing";
    Boolean reseeded
      "True on the tick the automatic recovery ladder re-seeded the state
       from a fresh anchor sample. It is an OPTIONAL, off-by-default stage,
       so on a filter that leaves it disabled this is always false and the
       commanded reset input is the only path that re-seeds. When it fires,
       correctionOutcome carries the CorrectionReseeded code rather than an
       acceptance code";
    Integer reseedCount
      "Monotonic count of automatic re-seeds since the last reset. Like
       acceptedCorrectionCount it gives a consumer a well-defined edge
       across a rate change, since reseeded is a per-tick level";
    Integer alignmentSource
      "Estimation.StrapdownINS.Alignment* code of the initial attitude
       alignment in force: which sample leveled the filter and whether a
       heading was available. Recorded so a flight log shows what the
       attitude started from";
    Real alignmentSpecificForceBodyFlu_m_s2[3](each unit = "m/s2")
      "The low-pass specific force the quasi-static test reads and the
       initial alignment levels on, zero until the first usable IMU sample";
    Real quietElapsed_s(unit = "s")
      "Time the low-pass IMU has reported a quasi-static vehicle: specific
       force within tolerance of gravity and angular rate below the limit.
       A tick that fails the test costs one tick and sustained motion drains
       it to zero. Gates the initial alignment and the zero-velocity update";
    Boolean pseudoPositionCorrectionAccepted
      "True on a tick the synthetic hold-position measurement moved the
       state";
    Boolean zeroVelocityCorrectionAccepted
      "True on a tick the synthetic zero-velocity measurement moved the
       state";
  end EstimatorStatus;