Reproducing the Shipped Ground Truth

The outdoor and Mars ground truth ships as a GPS+magnetometer attitude solution. Reproducing it from the raw published CSVs both validates the shipped product and pins down exactly what went into it (code).

Result

Re-running the maintainers’ Wahba GPS+mag pipeline (the numeric core of gps_mag_orientation.m) on the raw published CSVs reproduces the shipped ground_truth_8hz.csv / ground_truth_80hz.csv bit-for-bit on 18 of 19 Mars missions — position RMSE ~1e-15 m, quaternion RMSE ~1e-6°, on both the 8 Hz and the 100 Hz-grid lanes.

The reproduction extends past the truth product to the re-stamped sensor lanes the estimator consumes against the GT clock. On the reproducing Mars missions:

  • the regenerated px4_imu_data.csv and rtk_gps{1,2}_data_revised.csv are bytewise identical to the shipped files
  • px4_mag_data_revised.csv matches per column — t, cart_x/y/z, and spher_norm bit-exact, the degree-valued spher_az/spher_el to ~1e-14 (the only source of that file’s byte-length difference)
  • The recovered restamp offsets t_mag_gps / t_pximu_imugt in time_info.yaml reproduce identically

So the RTK (gps_time − t_pximu_imugt) and magnetometer (t + t_mag_pximu) restamping is reproduced end-to-end, not just the pose.

The match is what proves the shipped ground truth was solved on the raw px4_mag: the soft/hard-iron intrinsic is left commented at gps_mag_orientation.m:215.

Applying the intrinsic instead breaks the match — the intrinsic-corrected mag differs from raw by 21–34° on Mars — so raw mag is what shipped.

The attitude consequence of that choice is on Ground-Truth Attitude: Gravity Inconsistency.

The four Klagenfurt-site runs do not reproduce from this pipeline:

  • outdoor_1, transition_1, and transition_2 carry a ~10–15° attitude offset from a different or earlier attitude solution
  • transition_3 additionally fails the magnetometer-to-GPS time registration

Their positions still reproduce; the discrepancy is in the shipped attitude solution.

The shipped Klagenfurt-site attitude is ~15–17° gravity-inconsistent regardless (see Source of Truth).

The second GT family, outdoor_gt.csv / outdoor_gt_interpolate.csv (mars_3,12,14,15,18), regenerates only when the same pipeline is forced with the published ground_truth/time_offset.yaml offsets instead of the internally recomputed time_info.yaml pair.

  • Forcing them reproduces the shipped Family-B row counts exactly (mars_14 608 / 14520, full pairing at zero shift)
  • and recovers position to ~3.5 cm RMSE
  • but ~51–52° of attitude RMSE remains (mars_14 52.3° at 8 Hz, 51.4° on the 100 Hz grid)

The offset file alone therefore reproduces Family B’s timing and position but not its attitude: Family B is a genuinely different attitude solution from Family A, not a re-cropped or re-stamped copy of it.

Reconstruct Family-B attitude from the shipped CSV (or the bag-native gt JSONL it serializes bit-for-bit on mars_12/mars_14), not from the published offsets.

Reproduction

The pipeline needs two inputs the maintainer repository does not ship:

  • matlab_sensor_data.mat rebuilt from each run’s <run>_sensors/*.csv
  • sensor_calibration_<site>.m emitted from the published calibration YAMLs

With those staged, run the maintainers’ GPS+mag solve per mission and diff the emitted ground_truth_{8,80}hz.csv against the shipped files (constant-shift alignment, within-1 ms pairing).

The regenerated products and the reconstructed calibration files persist as the retained run artifacts of the ground-truth reproduction study.

Per-run row counts, rates, and offsets are on Per-Run Quick Reference.