Marine Heading
Node ID: marineHeading · Role: Filter · Realtime config: no
Description
Marine attitude and heading from the firmware-ported quaternion Kalman filter: gyro prediction, gravity-referenced tilt, yaw referenced by the continuously hard-iron-calibrated magnetometer (field-validity, tilt-leak, rate and innovation gated), crab-gated GNSS course over ground, or the receiver’s true heading (HDT). Position is raw GNSS passthrough - no position fusion. Outputs FusedPose (raw-GNSS ENU position + true-heading attitude) and GlobalFusedPose (WGS84, for map sinks).
Algorithm notes
How it works
The node estimates attitude from the IMU and turns it into a true-north heading. The gyroscope carries the heading between corrections, gravity from the accelerometer keeps roll and pitch level, and the yaw is anchored by whichever absolute references are available: the magnetometer, the GNSS course over ground, or the receiver’s own true heading. The magnetometer is calibrated continuously while the node runs - it learns the constant magnetic offset of the installation from the sensor data itself, so no swing procedure is needed. Every magnetic sample is checked against the expected local field before it is trusted; disturbed samples are ignored rather than allowed to pull the heading. Position is not fused at all: the GNSS fix is passed straight through, so the output position is exactly the receiver’s.
What you must configure
Set Input gyro unit and Input accel unit to match the sensor feeding the node. Getting these wrong makes the heading drift wildly or the tilt never settle. If you do not have a GNSS input, set Magnetic declination (deg, east positive) for your area, otherwise the heading will be magnetic, not true. With GNSS connected, leave World Magnetic Model reference field on and declination, inclination and field magnitude are taken from your position automatically. Turn on Use receiver true heading (HDT) if the receiver provides a dual-antenna or gyrocompass heading - it is the strongest reference available.
How it starts
Nothing is emitted until the node has an absolute heading reference. The first usable magnetic sample, course over ground, or receiver heading sets the heading immediately, and output begins from there. Tilt settles within a second or two of the first samples. The magnetic calibration keeps improving in the background for minutes afterwards; heading accuracy improves as it converges. With Persist calibration on, the calibration is stored per sensor and reloaded on the next start, so a known installation is accurate much sooner.
Tuning
- Field magnitude tolerance (fraction) and Inclination tolerance (deg): widen them if a magnetically noisy installation rejects nearly every sample; tighten them to reject disturbances more aggressively.
- Learn local field as gate reference should stay on inside steel structures or vehicle cabins, where the ambient field is permanently far from the textbook value. Local field time constant (s) sets how fast that learned reference follows the environment.
- Compass: mag innovation gate (deg) rejects sudden magnetic jumps; lower it to ride through more disturbance, raise it if genuine heading changes are being rejected. Compass: innovation gate release (s) is how long a consistent disagreement must last before the heading is pulled back.
- COG truth: min speed (m/s), max yaw rate (rad/s) and min straight duration (s) decide when course over ground is trusted as heading. Raise the speed on a vessel that drifts sideways in current; lower it on slow craft.
- Deviation card (heading-dependent correction) helps when the heading error changes with direction. It trains only from trusted course over ground, so it needs a varied route to be useful.
- Soft-iron scales (diagonal) helps only when the installation squashes the field unevenly, and it needs motion in pitch and roll, not just turns.
Troubleshooting
- No output at all - no heading reference yet. Check the magnetometer is actually being delivered with the IMU data, or move so course over ground can open.
- Heading drifts steadily - magnetic corrections are being rejected. Check the field status; widen the field tolerances or enable the learned local field reference.
- Heading is offset by a constant amount - declination is wrong, or the sensor is not mounted with its x-axis along the bow. Enable World Magnetic Model reference field, or check the mounting.
- Heading is wrong after moving the sensor or the boat - the stored calibration no longer applies. Use the reset calibration command and let it relearn.
- Heading shifts when the vessel pitches or heels - vertical calibration has not converged. Give it motion in pitch and roll, not just turns.
- Heading lags during fast turns - expected: magnetic corrections pause above Compass: max rate for mag correction (deg/s). Raise it only if the tilt estimate is good.
- Position jumps or is noisy - that is the raw GNSS fix; fix it at the receiver, the node does not smooth position.
Inputs / Outputs
- Inputs:
Imu,Gnss - Outputs:
FusedPose,GlobalFusedPose
Config aliases
MarineHeadingFilter, marineHeadingFilter, marineHeading
Properties
Each row shows the setting’s label in the node’s Properties panel and, in code, its key in the node’s settings object in the config file. A setting omitted from the config file uses the default shown here.
| Property | Type | Default | Description |
|---|---|---|---|
Magnetic declination (deg, east positive) declinationDeg | number | 0.0 | |
Magnetic inclination / dip (deg, down positive) inclinationDeg | number | 60.0 | |
Expected field magnitude (uT) fieldMagnitudeUt | number | 50.0 | |
Field magnitude tolerance (fraction) magnitudeTolerance | number | 0.15 | |
Inclination tolerance (deg) inclinationToleranceDeg | number | 8.0 | |
Calibration forgetting factor rlsForgetting | number | 0.9999 | |
Soft-iron scales (diagonal) enableSoftIron | boolean | false | |
Soft-iron scale prior sigma softIronScaleSigma | number | 2.0 | |
Min field-space sample spacing (uT) minSampleSpacingUt | number | 2.0 | |
Magnetometer noise stddev (uT) magNoiseUt | number | 0.5 | |
COG truth: min speed (m/s) cogMinSpeedMps | number | 2.0 | |
COG truth: max yaw rate (rad/s) cogMaxYawRateRadS | number | 0.02 | |
COG truth: min straight duration (s) cogMinStraightS | number | 5.0 | |
Persist calibration persistCalibration | boolean | true | |
World Magnetic Model reference field useWmm | boolean | true | |
Learn local field as gate reference useLocalFieldReference | boolean | true | |
Local field time constant (s) localFieldTauS | number | 120.0 | |
Deviation card (heading-dependent correction) enableDeviationModel | boolean | false | |
Use receiver true heading (HDT) useReceiverHeading | boolean | false | |
Kalman: accelerometer covariance kfAccCovariance | number | 0.1 | |
Kalman: magnetometer covariance kfMagCovariance | number | 1000.0 | |
Kalman: COG yaw covariance kfCogCovariance | number | 10.0 | |
Kalman: receiver heading covariance kfReceiverCovariance | number | 1.0 | |
Compass: max rate for mag correction (deg/s) compassMaxRateDegS | number | 45.0 | |
Compass: mag innovation gate (deg) compassInnovationGateDeg | number | 30.0 | |
Compass: innovation gate release (s) compassInnovationReleaseS | number | 10.0 | |
Input gyro unit gyroUnit | select | degS | Options: degS, radS. |
Input accel unit accelUnit | select | g | Options: g, mps2. |
Field magnitude gate enableMagnitudeGate | boolean | true | |
Field inclination gate enableInclinationGate | boolean | true | |
COG straight-line gate enableCogGate | boolean | true |
Example node definition
A minimal entry in config.json looks like the block below. Paste it under the sinks key, keyed by an instance name of your choice. All settings are optional: anything not listed under settings uses the default from the Properties table above. See The configuration file for how the sections and endpoint wiring work.
{
"sinks": {
"marineHeading": {
"dataEndpoint": "inproc://marineHeading_data",
"inputEndpoints": [
"inproc://imu_data",
"inproc://gnss_data"
],
"inputDataFilter": [
"Imu",
"Gnss"
],
"settings": {}
}
}
}