Accept fixed-ambiguity GNSS heading and align the mount to boat-forward - #72
Merged
Conversation
Co-Authored-By: Claude <noreply@anthropic.com>
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.
Dual-antenna GNSS heading works again on the team's mosaic-go-H, so the firmware can stop running mag-only. Three things stood in the way.
The firmware discarded every GNSS heading
bring_upasked the receiver forAttitudeResolution::Float, a workaround from when the aux antenna looked dead. Under Float the receiver reports AttEuler mode 1, andgnss_bridgeaccepts only the fixed-ambiguity modes 2 and 4 by design, so every sample arrivedvalid=false. Measured on hardware: 596 of 596 samples rejected while the receiver had a healthy solution (AuxAntPositions error=0, 11 to 12 satellites). Switched toFixed.The mount was never calibrated
Both offsets are now measured on the boat, level and mounted:
imu_mount: the BNO085's -X axis points at the bow, hence the 180 yaw. Roll and pitch are the board's residual tilt in its bracket, solved so the filter reports 0.000 / 0.000 in this attitude.gnss.baseline_offset_degstays 0: the antennas sit on the centerline with the aux one forward, so the main to aux baseline already points at the bow. Now documented as verified rather than left at a default.mti_yaw.offset_seed_deg: -131.7 to -64.7, read off the filter's own learned offset once it converged against fixed-ambiguity headings, which beats a hand compass as a reference.p0_offset_deg2stays at 4.0. Loosening it was considered, since GNSS now owns absolute heading, but that would give up the boot anchor and the outage hold for no gain: the seed is a real measurement again, not a provisional one.A stale persisted offset shadowed the seed
The flash blob held -101.401 and re-latched every boot, so no
tuning.tomlchange could take effect.offset_store::VERSIONgoes 1 to 2, which rejects it on load. A persisted offset is only valid for the frame it was learned in, so a mount or baseline change has to invalidate it; the comment now says so.Verified on hardware
Pico 2, stationary, before and after:
mode=1)mode=2)Gate rejects 0,
|quat|1.00000, gyro biases under 0.005 deg/s throughout.Test changes
Recalibrating broke three tests, which is itself the finding: they snapshotted physical measurements.
test_default_tuning_enables_mti_yawasserted the exactMtiYawConfig, andtest_load_mount_reads_gnss_sectionassertedbaseline_offset_deg == 0.0. Both now assert the property that matters (the mag measurement is on, seeded and pinned; the values are in range) and leave exact parsing to the fixture-based loader tests next to them.test_default_tuning_has_zero_imu_mountis deleted. It only restated a measurement, andtest_load_tuning_reads_imu_mount_sectionalready covers the loader.test_boot_anchorbuilt itsSimulatedSourcewith an identityimu_mountwhile handing the filter the shipped tuning, so the filter de-rotated a rotation the synthetic IMU never had. It now derivesimu_mountfrom the same config it runs, as__main__does.Note that five other sim test files have the same latent coupling (
load_tuningplus an identity-mountSimulatedSource). They pass only because GNSS is present to pull heading back, so the mag offset absorbs the error. Left alone here.217 native tests and 211 sim tests pass;
pio run -e pico2builds.Not fixed here: about 6% of telemetry lines are still corrupted by the unmutexed sink. Separate PR.