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.csvandrtk_gps{1,2}_data_revised.csvare bytewise identical to the shipped files px4_mag_data_revised.csvmatches per column —t,cart_x/y/z, andspher_normbit-exact, the degree-valuedspher_az/spher_elto ~1e-14 (the only source of that file’s byte-length difference)- The recovered restamp offsets
t_mag_gps/t_pximu_imugtintime_info.yamlreproduce 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, andtransition_2carry a ~10–15° attitude offset from a different or earlier attitude solutiontransition_3additionally 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_14608 / 14520, full pairing at zero shift) - and recovers position to ~3.5 cm RMSE
- but ~51–52° of attitude RMSE remains (
mars_1452.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.matrebuilt from each run’s<run>_sensors/*.csvsensor_calibration_<site>.memitted 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.