Sensor Calibration

This page explains how MAVLink can be used by a ground station or companion computer to trigger sensor calibrations. The user wiki pages for these procedures are here: accelerometer, compass, radio.

Note

The vehicle must be disarmed before starting a calibration. If armed, MAV_CMD_PREFLIGHT_CALIBRATION replies with a “Disarm to allow calibration” status text and is rejected, and MAV_CMD_DO_START_MAG_CAL replies with “Disarm to allow compass calibration”. MAV_CMD_DO_ACCEPT_MAG_CAL and MAV_CMD_DO_CANCEL_MAG_CAL have no armed-state check.

Simple calibrations

Gyro, barometer, board-level (trim) and simple accelerometer calibrations are each triggered with a single MAV_CMD_PREFLIGHT_CALIBRATION sent within a COMMAND_INT (or COMMAND_LONG). Only one of the fields below should be non-zero in a given message.

Command Field Type Description
param1 float 1: gyro calibration
param2 float magnetometer calibration — see below
param3 float 1: barometer (and airspeed, if fitted) calibration
param4 float positive value: sets an internal "RC calibrating" flag that blocks arming (arming check fails with "RC calibrating") while true; zero/negative clears it — but only when param1 and param3 are both 0. ArduPilot does not itself run an RC endpoint calibration routine in response to this field. See note below
x (param5) int32_t Accelerometer calibration action: 1: full 6-position calibration (see below) 2: board-level/trim calibration 4: simple (single position) accelerometer calibration 76: force-accept the existing accelerometer calibration as valid, without re-running it
y (param6) int32_t Vehicle-specific: Copter — 1: CompassMot calibration. Rover — 1: windvane direction calibration, 2: windvane speed calibration. Sub — 1: rejected (MAV_RESULT_UNSUPPORTED), CompassMot is not supported. Plane, AntennaTracker and Blimp: not used.
z (param7) float not used

Note

x/y are int32_t fields of COMMAND_INT, not float. When this command is sent as COMMAND_LONG instead, its float param5/param6 are cast directly to x/y on receipt.

Note

ArduPilot does not itself run an RC endpoint calibration routine in response to param4 — see the radio calibration page for how RC calibration actually works. The “RC calibrating” flag it does set/clear is only actually evaluated when param1 and param3 are both 0 — a command that also triggers a gyro (param1=1) or barometer (param3=1) calibration returns before reaching the param4 check, so param4 has no effect in that same message. In practice this means: combining a gyro or barometer calibration with param4=0 will not clear a flag left set by an earlier command — a separate command with param1=0, param3=0 and param4 ≤ 0 (or a reboot) is required to clear it. Conversely, an unrelated accelerometer-calibration command (param5/x set, param1=0, param3=0) with param4 left at its default of 0 will clear the flag, even in the middle of an in-progress RC calibration.

ArduPilot only implements one action for the magnetometer’s param2 field: a value of 76 force-accepts the existing compass calibration as valid without re-running it (useful after a parameter reload that cleared the calibration-valid flags). The MAVLink spec also defines a value of 1 to start a magnetometer calibration via this same command, but ArduPilot does not implement that path — sending param2 = 1 alone returns MAV_RESULT_UNSUPPORTED. Use the dedicated compass calibration commands below to actually start a mag calibration.

Full 6-position accelerometer calibration

Sending MAV_CMD_PREFLIGHT_CALIBRATION with x (param5) = 1 starts the interactive full accelerometer calibration, which requires the vehicle to be placed in each of 6 orientations in turn. ArduPilot drives this using MAV_CMD_ACCELCAL_VEHICLE_POS:

Note

Before starting the position wizard, ArduPilot first runs a gyro calibration internally. If that gyro calibration fails (for example the vehicle is being handled or vibrating), the whole command fails immediately with MAV_RESULT_FAILED and no MAV_CMD_ACCELCAL_VEHICLE_POS is ever sent — a GCS that has already shown a “place vehicle LEVEL” prompt and is waiting for that message will wait forever unless it also handles this failure result.

  • ArduPilot sends this command to the GCS with param1 set to the position it wants next (ACCELCAL_VEHICLE_POS: 1=LEVEL, 2=LEFT, 3=RIGHT, 4=NOSEDOWN, 5=NOSEUP, 6=BACK), which the GCS should show to the user

  • once the vehicle has been placed in that position (and is stationary), the GCS sends the same command back to the vehicle with the same param1 value to confirm that position is ready and trigger capture of that orientation’s data

  • ArduPilot then either requests the next position, or ends the calibration by sending MAV_CMD_ACCELCAL_VEHICLE_POS with param1 = 16777215 (success) or 16777216 (failed)

Compass (magnetometer) calibration

Compass calibration uses three dedicated commands rather than MAV_CMD_PREFLIGHT_CALIBRATION. Each is sent within a COMMAND_INT/COMMAND_LONG with a bitmask of which compasses to act on in param1 (0 means all):

  • MAV_CMD_DO_START_MAG_CAL — start calibration. param2 = retry on failure (0/1), param3 = autosave without waiting for MAV_CMD_DO_ACCEPT_MAG_CAL (0/1), param4 = delay in seconds before starting, x (param5) = autoreboot when done (0/1)

  • MAV_CMD_DO_ACCEPT_MAG_CAL — accept/save a completed calibration (only needed if autosave was not requested)

  • MAV_CMD_DO_CANCEL_MAG_CAL — cancel a running calibration

While a compass calibration is running, ArduPilot streams MAG_CAL_PROGRESS messages showing each compass’s completion_pct. Both MAG_CAL_PROGRESS and MAG_CAL_REPORT (below) are sent as part of the EXTRA3 telemetry stream, so a GCS/companion computer that has that stream’s rate set to 0 will not see them, and calibration will appear to hang even though it is progressing normally.

Note

MAG_CAL_REPORT is not a one-shot message. Once a compass finishes calibrating, ArduPilot has no “already reported” latch — it keeps re-sending that compass’s MAG_CAL_REPORT at the EXTRA3 stream rate rather than sending it just once. Its cal_status field gives the fit result (success/failed), and a separate autosaved field indicates whether the calibration has actually been saved to the compass’s offset parameters (true if autosave was requested via MAV_CMD_DO_START_MAG_CAL’s param3, or after MAV_CMD_DO_ACCEPT_MAG_CAL is sent) — the two are independent, so a compass can report a successful fit that has not yet been saved. A client that treats the first MAG_CAL_REPORT as a single completion event should still expect further copies of it to keep arriving.

Example

The example commands below can be copy-pasted into MAVProxy (aka SITL) to test these commands. Before running these commands enter, “module load message”

  • message COMMAND_LONG 0 0 241 0 1 0 0 0 0 0 0 — gyro calibration

  • message COMMAND_LONG 0 0 241 0 0 0 1 0 0 0 0 — barometer calibration

  • message COMMAND_LONG 0 0 241 0 0 0 0 0 4 0 0 — simple accelerometer calibration

  • message COMMAND_LONG 0 0 42424 0 0 0 1 0 0 0 0 — start compass calibration (autosave)