Skip to content

AP_Compass: report specific failure reason when fit rejected#32757

Draft
christianpetri wants to merge 1 commit into
ArduPilot:masterfrom
christianpetri:compass-cal-early-abort
Draft

AP_Compass: report specific failure reason when fit rejected#32757
christianpetri wants to merge 1 commit into
ArduPilot:masterfrom
christianpetri:compass-cal-early-abort

Conversation

@christianpetri

@christianpetri christianpetri commented Apr 13, 2026

Copy link
Copy Markdown

Summary

Extend the CompassCalibrator::Status enum with three new terminal failure values (BAD_OFFSETS=8, BAD_DIAG_SCALING=9, BAD_FITNESS=10) and refactor fit_acceptable() to set the appropriate specific status instead of falling back to the generic FAILED.

Classification & Testing (check all that apply and add your own)

  • Checked by a human programmer
  • Automated test(s) verify changes (e.g. unit test, autotest)
  • Tested manually, description below (e.g. SITL)

Description

Previously fit_acceptable() returned a silent false — the GCS and user had no way to know why calibration was rejected. This PR maps each rejection condition to a specific Status value that is transmitted in the MAG_CAL_REPORT.cal_status field.

New Status enum values (extend MAG_CAL_STATUS MAVLink enum):

Value Name Condition
8 BAD_OFFSETS Any offset component ≥ COMPASS_OFFS_MAX
9 BAD_DIAG_SCALING Diagonal or off-diagonal scaling out of range
10 BAD_FITNESS _fitness > sq(_tolerance)

BAD_RADIUS (7) was already present. All four conditions were previously collapsed into FAILED (5).

Behaviour changes:

  • fit_acceptable() loses const (it now calls set_status()).
  • set_status(FAILED) is guarded against overwriting any of the five specific BAD_* statuses (previously only BAD_ORIENTATION and BAD_RADIUS were protected).
  • update_cal_status(), failed(), is_calibrating(), and send_cal_report() all handle the three new cases identically to BAD_RADIUS.
  • No GCS_SEND_TEXT calls added; flash cost +48 bytes on CubeOrange plane (measured via Tools/scripts/size_compare_branches.py).

Note: The new integer values (8/9/10) are transmitted immediately. GCS will display the raw number until a matching MAG_CAL_STATUS entry is added in the upstream mavlink/mavlink XML and a pymavlink bump lands in ArduPilot. The autotest uses getattr(mavutil.mavlink, 'MAG_CAL_BAD_FITNESS', 10) fallbacks pending that bump.

Related

Testing

Builds clean on SITL and CubeOrange (./waf configure --board CubeOrange && ./waf plane). Flash delta vs master: +48 bytes (measured on CubeOrange plane via official ArduPilot size_compare_branches.py tool).

SITL autotest SITLCompassCalibration passes:

Tools/autotest/autotest.py test.Copter.SITLCompassCalibration

Two new subtests added:

  1. Tight-fit test (COMPASS_CAL_FIT=0.001) — all compasses report MAG_CAL_BAD_FITNESS (10) instead of MAG_CAL_FAILED (5).
  2. Selective-failure test (SIM_MAG1_OFS_X/Y/Z=2000) — compass 0 reports MAG_CAL_BAD_OFFSETS (8); remaining compasses still succeed.

This contribution was AI-assisted (GitHub Copilot).

@christianpetri

This comment was marked as outdated.

@IamPete1

Copy link
Copy Markdown
Member

I think 950 is too low, that is within the range of offsets that we might see in normal operation. I think we might be better off to try and improve the reporting at the end of a calibration attempt rather than guessing at the beginning.

@christianpetri christianpetri force-pushed the compass-cal-early-abort branch from f4e053b to a428227 Compare April 13, 2026 23:03
@christianpetri

This comment was marked as outdated.

@rmackay9

Copy link
Copy Markdown
Contributor

Hi @christianpetri,

Thanks for this. One small thing is we don't accept merge commits so could you rebase on master to remove it?

@christianpetri christianpetri force-pushed the compass-cal-early-abort branch 2 times, most recently from a6d793b to b0f7dc6 Compare April 14, 2026 11:15

@peterbarker peterbarker left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create an autotest

  • want other compasses to keep calibrating if one of them gets a long field
  • we have lots of autotests already doing calibration, steal code from there
  • does this make calibration faster with a badly-affected compass?

Generally in favour of this at DevCallEU

What's the flash cost?

@christianpetri

This comment was marked as outdated.

@IamPete1

Copy link
Copy Markdown
Member

Not keen on the short circuit stuff, but I like the improved reporting at the end of the calibration. To get the most out of this we might need some GCS changes, in mission planner you can't see messages on the compass calibration page, you would have to go and look manualy.

@christianpetri christianpetri force-pushed the compass-cal-early-abort branch from 560b8e1 to 09774b4 Compare April 19, 2026 20:26
@christianpetri

christianpetri commented Apr 19, 2026

Copy link
Copy Markdown
Author

Dropped the early-abort in pull_sample() as requested. Kept and improved the fit_acceptable() diagnostics: each failure condition (fitness NaN, radius out of range, offsets too large, diagonal/offdiagonal out of range, fitness over tolerance) now emits its own GCS message with the actual values, so all failures are visible in a single calibration attempt rather than just the first hit. Removed const from fit_acceptable() since GCS_SEND_TEXT is a side effect. This is consistent with the pre-existing messages already in calculate_orientation() and fix_radius().

@christianpetri

christianpetri commented Apr 20, 2026

Copy link
Copy Markdown
Author

SITL Test Plan

Manual SITL verification for the Mag(N) bad ... STATUSTEXT capture in the compass calibration dialog.

  • Mission Planner now shows the Mag(N) bad fit diagnostics directly in the compass calibration panel, so the failure reason is visible immediately without leaving the page. image

  • Close-up of the Onboard Mag Calibration box showing a specific rejection reason (offsets over limit) alongside the live calibration progress. image

Related PRs

Setup

sim_vehicle.py -v ArduCopter -f calibration --console --map

Connect Mission Planner via TCP 127.0.0.1:5762, navigate to Initial Setup → Mandatory Hardware → Compass.

Reset between tests

param set COMPASS_CAL_FIT 16
param set SIM_MAG1_OFS_X 0 ; param set SIM_MAG1_OFS_Y 0 ; param set SIM_MAG1_OFS_Z 0
param set SIM_MAG2_OFS_X 0 ; param set SIM_MAG2_OFS_Y 0 ; param set SIM_MAG2_OFS_Z 0
param set SIM_MAG3_OFS_X 0 ; param set SIM_MAG3_OFS_Y 0 ; param set SIM_MAG3_OFS_Z 0
sitl_stop ; sitl_attitude 0 0 0

Tests

# Scenario Setup Action Expected
1 Success baseline (defaults) Start → sitl_magcal → Accept Progress/report lines, no bad lines
2 Bad fit COMPASS_CAL_FIT 0.001 Start → sitl_magcal Mag(N) bad fit: fitness X tolerance Y per compass
3 Bad offset (early abort) SIM_MAG1_OFS_X/Y/Z 2000 Start → sitl_magcal Mag(0) bad fit: ofs (2000,2000,2000)>=1800
4 Cancel/restart (defaults) Start → Cancel mid-run → Start Cancel/restart of calibration via MP — diagnostics state resets cleanly (verified with #3706)

Pass criteria

  • Success path shows no bad lines.
  • Failure path shows Mag(N) bad ... lines, line-separated, latest-per-compass.
  • Restart is clean after Cancel.
  • Non-compass STATUSTEXT still flows to HUD/messages.
  • No UI freeze or crash.

@christianpetri christianpetri force-pushed the compass-cal-early-abort branch from 09774b4 to 4fbb08d Compare April 20, 2026 01:01
@christianpetri

This comment was marked as outdated.

@christianpetri christianpetri force-pushed the compass-cal-early-abort branch from 4fbb08d to 774fc4c Compare April 20, 2026 01:50
@christianpetri christianpetri changed the title AP_Compass: early abort calibration on extreme magnetic field AP_Compass: report specific failure reason when fit rejected Apr 20, 2026
@christianpetri christianpetri force-pushed the compass-cal-early-abort branch from 774fc4c to 88799cf Compare April 20, 2026 22:28

@IamPete1 IamPete1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this! And Thanks for doing the Mission Planner fix too!

Comment thread libraries/AP_Compass/CompassCalibrator.cpp Outdated
Comment thread libraries/AP_Compass/CompassCalibrator.cpp Outdated
Comment thread libraries/AP_Compass/CompassCalibrator.cpp Outdated
Comment thread libraries/AP_Compass/CompassCalibrator.cpp Outdated
Comment thread libraries/AP_Compass/CompassCalibrator.cpp
@christianpetri christianpetri force-pushed the compass-cal-early-abort branch 2 times, most recently from 7ace6e0 to f7e0a2e Compare May 11, 2026 20:12
@christianpetri

Copy link
Copy Markdown
Author

Rebased and updated based on review feedback. Latest push includes one follow-up cleanup commit:

  • comment clarifications around retry timing and autoreboot safety rationale
  • removal of two introduced trailing-whitespace lines
  • explicit default initialization for _retry_pending (false)
  • no behavioral change intended from this follow-up commit

Validation on this branch:

  • SITL compass-cal chain manual test: all 4 scenarios pass
  • autotest additions remain in place for:
    • BAD_FITNESS with tight COMPASS_CAL_FIT
    • selective failure where one compass reports BAD_OFFSETS and others continue/succeed
  • local build sanity check passed

Requesting re-review. If anything is still blocking, I can address it quickly.

@christianpetri

christianpetri commented May 11, 2026

Copy link
Copy Markdown
Author

Follow-up question for maintainers on intent:

For the latest cleanup commit, I clarified comments around two behavior points:

  • retry timing visibility (_retry_pending defers transition so BAD_* is observable for one GCS poll cycle)
  • autoreboot safety rationale (do not auto-reboot if any compass ends in BAD_*)

Could you please confirm this is the intended handling?

If preferred, I can adjust to a different policy/wording before merge (for example: keep behavior but simplify wording, or adjust reboot policy expectations).

@christianpetri

christianpetri commented May 11, 2026

Copy link
Copy Markdown
Author

Size re-check on latest branch head using ArduPilot size comparison script:

  • python3 Tools/scripts/size_compare_branches.py --master-branch origin/master --branch compass-cal-early-abort --vehicle plane --board CubeOrange --hide-unchanged
  • Result:

    Board,plane
    CubeOrange,48

So current delta is +48 bytes for CubeOrange plane versus merge-base/origin master.

@christianpetri christianpetri marked this pull request as ready for review May 11, 2026 23:37
@christianpetri christianpetri force-pushed the compass-cal-early-abort branch from 553381f to 15aa6c5 Compare May 11, 2026 23:37
christianpetri added a commit to christianpetri/mavlink that referenced this pull request May 11, 2026
Add three new failure reason enum values (8/9/10) to MAG_CAL_STATUS,
and add descriptions to existing entries 6 and 7 for consistency.

Implemented in ArduPilot firmware: ArduPilot/ardupilot#32757
christianpetri added a commit to christianpetri/mavlink that referenced this pull request May 14, 2026
Add three new failure reason enum values (8/9/10) to MAG_CAL_STATUS,
and add descriptions to existing entries 6 and 7 for consistency.

Implemented in ArduPilot firmware: ArduPilot/ardupilot#32757
@christianpetri christianpetri force-pushed the compass-cal-early-abort branch from 15aa6c5 to ff38025 Compare May 14, 2026 18:22
hamishwillee pushed a commit to christianpetri/mavlink that referenced this pull request May 21, 2026
Add three new failure reason enum values (8/9/10) to MAG_CAL_STATUS,
and add descriptions to existing entries 6 and 7 for consistency.

Implemented in ArduPilot firmware: ArduPilot/ardupilot#32757
christianpetri added a commit to christianpetri/mavlink that referenced this pull request May 22, 2026
…AL_STATUS

Add three new failure reason enum values (8/9/10) to MAG_CAL_STATUS, and add descriptions to existing entries 6 and 7 for consistency.\n\nImplemented in ArduPilot firmware: ArduPilot/ardupilot#32757
christianpetri added a commit to christianpetri/mavlink that referenced this pull request May 22, 2026
…AL_STATUS

Add three new failure reason enum values (8/9/10) to MAG_CAL_STATUS, and add descriptions to existing entries 6 and 7 for consistency.

Implemented in ArduPilot firmware: ArduPilot/ardupilot#32757
@christianpetri christianpetri force-pushed the compass-cal-early-abort branch from 4ce9557 to 399743b Compare May 22, 2026 01:46
christianpetri added a commit to christianpetri/mavlink that referenced this pull request May 28, 2026
…AL_STATUS

Add three new failure reason enum values (8/9/10) to MAG_CAL_STATUS, and add descriptions to existing entries 6 and 7 for consistency.

Implemented in ArduPilot firmware: ArduPilot/ardupilot#32757
@christianpetri christianpetri force-pushed the compass-cal-early-abort branch from 9d73abb to ddea6dc Compare May 28, 2026 12:07
@christianpetri christianpetri force-pushed the compass-cal-early-abort branch from ddea6dc to 15ec2b8 Compare May 28, 2026 12:11
@christianpetri

Copy link
Copy Markdown
Author

Aligned the AP_Compass MAG_CAL failure status naming with mavlink/mavlink#2478 (FAILED_* names), including compatibility fallbacks in autotest until pymavlink catches up.

@christianpetri

christianpetri commented May 28, 2026

Copy link
Copy Markdown
Author

Hi @peterbarker, quick status update on your requested changes:

Could you please re-review and let me know if anything is still blocking from your side?

@rmackay9

Copy link
Copy Markdown
Contributor

Hi @christianpetri,

I've also added this to the weekly dev call so it will be reviewed then if not before, txs!

@peterbarker

Copy link
Copy Markdown
Contributor

Could you please re-review and let me know if anything is still blocking from your side?

We meed the mavlink merged both i mavlink/mavlink/master and into our own tree before we can really progress this PR.

christianpetri added a commit to christianpetri/mavlink that referenced this pull request Jun 2, 2026
…AL_STATUS

Add three new failure reason enum values (8/9/10) to MAG_CAL_STATUS, and add descriptions to existing entries 6 and 7 for consistency.

Implemented in ArduPilot firmware: ArduPilot/ardupilot#32757
@christianpetri christianpetri marked this pull request as draft June 2, 2026 10:43
@hamishwillee

hamishwillee commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Merged in mavlink/mavlink.

@christianpetri

Copy link
Copy Markdown
Author

Hi @hamishwillee and @peterbarker, quick question about the MAVLink to ArduPilot flow.

Is opening that PR sufficient, or are there additional steps we should complete first before it can be brought into ArduPilot?
ArduPilot/mavlink#506

Thank you very much for your guidance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants