tools: MAVExplorer: add EKF3 variance, innovation, and sensor consistency graphs - #1708
Open
asikarastallion wants to merge 2 commits into
Open
tools: MAVExplorer: add EKF3 variance, innovation, and sensor consistency graphs#1708asikarastallion wants to merge 2 commits into
asikarastallion wants to merge 2 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds comprehensive EKF and multi-sensor diagnostic preset graphs to
mavgraphs.xml.Closes #1595
Motivation
Evaluating EKF health, lane switching, and pre-filter sensor inconsistencies
currently requires manual plotting of multiple
XKF*,NKF*, and raw sensormessages. These presets allow immediate, one-click analysis of filter health
and hardware consistency directly from the MAVExplorer menu, and directly
address the gap reported in #1595 (no monitoring tool for EKF3 affinity and
lane switching).
Changes
SV,SP,SH,SM,SVT). A1.0threshold line is included(
1.0+0*XKF4[0].*) — this is not an arbitrary reference: it isArduPilot's actual innovation-rejection gate (see "Verification" below).
Position, Mag, and Yaw.
SS) and estimated attitudeerrors (
errRP).a genuine EKF/algorithm problem from an underlying sensor problem when a
Variance or Innovation graph above shows something unhealthy:
1.0e7) and quality metrics (HDop,NSats).Technical Details
XKF3/XKF4) and legacy EKF2 (NKF3/NKF4)log messages within the same views, so the graphs remain useful across
older logs as well as current ones.
[0],[1],[2])to support redundant hardware setups (dual/triple IMU, GPS, compass).
degrees()for radian-to-degree conversions on Gyro anderrRPdata for readability.
Verification: the 1.0 threshold is ArduPilot's real rejection gate
Traced through
AP_NavEKF3source to confirm this isn't an arbitraryreference line:
AP_NavEKF3_Outputs.cpp::getVariances()returnsvelVar = sqrtF(velTestRatio)(and the equivalent for pos/hgt/mag/tas) — this is exactly what gets logged
as
XKF4.SV/SP/SH/SM/SVT.AP_NavEKF3_PosVelFusion.cpp:if (velTestRatio < 1.0), andAP_NavEKF3_MagFusion.cpp:magHealth = (magTestRatio[0] < 1.0f && ...).So
SV/SP/SH/SM/SVTcrossing1.0in these graphs is the samecondition ArduPilot itself uses internally to start rejecting that
measurement — the graph is reading the filter's actual decision boundary,
not an approximation of it.
Testing
Verified all 17 graph expressions evaluate without errors (no NameError /
eval exceptions) against a real dual-IMU, dual-core EKF3 log
(178,979 messages, ~35 min flight):
XKF3/XKF4) expressions returned full data (6,088 samplesper field, both cores populated).
data (146,103 / 2,435 samples).
EKF3/Variance/Velocityto PNG to visually confirm the1.0threshold line sits correctly against real
SVvalues, which stayed inthe 0–0.03 range with one genuine spike to 0.28 — axis scaling and
threshold placement both looked correct.
by dataflash magic bytes): the large majority contained
XKF3/XKF4(EKF3), a small number of older logs contained
NKF3/NKF4(EKF2, seebelow), none contained a second GPS instance.
EKF2 (
NKF3/NKF4) was additionally verified against two logs:home-directory-wide scan.
EK2_ENABLE=1,EK3_ENABLE=0,AHRS_EKF_TYPE=2), to check current-format behavior directly.Result:
NKF3[0]/NKF4[0]bracket-instance syntax returns full, correctdata on modern EKF2 logs (2,477 samples per field, both cores populated,
PNG-rendered and visually confirmed) — see the coverage limitation below
for the one gap this surfaced.
Known test-coverage limitations
NKF3[0]/NKF4[0]instance syntax verified against two EKF2 logs:a real legacy log (ArduPlane V3.8.2-dev, ~2017/2018) and a SITL-generated
modern log (
EK2_ENABLE=1/EK3_ENABLE=0). Result: the bracket-instancesyntax works correctly on modern EKF2 logs, where
NKF3/NKF4carry acore/lane field (
C) — same asXKF3/XKF4. On pre-core-field EKF2 logs(roughly pre-2018, before multi-lane EKF2 existed),
NKF3[0]/NKF4[0]silently returns empty data rather than raising an error, because there
is no
Cfield to index into. The plain (bracket-free) form —NKF3.IVN,NKF4.SV, etc. — does return data on these older logs.This is a narrow edge case (affects only genuinely old EKF2-only logs,
not
XKF3/XKF4, which have always had a core field), but worth knowing:a blank EKF2 graph on a very old log means "no core field," not
"everything's fine."
Sensors/GPS/Position-OffsetandSensors/GPS/Qualityrender emptyon any single-GPS setup (i.e. most vehicles) — this is expected
behavior (no
GPS[1]data to plot), not a bug, but worth knowing beforeassuming the graph is broken on a normal log.
a lane switch event itself is not highlighted/annotated on the timeline;
the graphs only make it visually apparent by eye.
On the EKF3 vs Sensors split
These are kept in one PR because the
Sensorsgraphs exist specificallyto help answer why a
Variance/Innovationsgraph shows a problem(e.g. a Mag Variance spike traced back to a Compass Field-Consistency
mismatch). Happy to split into two PRs if maintainers would prefer
independent review — flagging as an option, not proposing it.
AI assistance disclosure: This contribution was developed with the assistance of Claude (Anthropic). I reviewed and tested the results as described above and understand the change.