# Pre-registration of the second MID360 IMU-LiDAR extrinsic audit against LI-Init (v2).
#
# Written on 2026-09-30, before Calibrex, LI-Init, or the common odometry has
# been run on construction_seq2, the last RTK-SLAM recording not yet used for
# IMU-LiDAR calibration.
#
# The first audit (mid360_imu_lidar_translation_preregistration.yaml) was
# refuted: Calibrex's lever arm was inconclusive on stadtgarten_seq1 and
# construction_seq1, because x moved with the segment duration.  The method
# was then changed on development data only (stadtgarten_seq2,
# stadtgarten_seq1, construction_seq1, all spent), as follows:
#   * gravity is fitted per 2-second segment instead of per 10-second window,
#     because the odometry's tilt drifts within a window;
#   * segments need at least 10 scans; and
#   * the segment-duration sensitivity uses 3 s and 4 s refits. 1 s was
#     dropped: with per-segment gravity it is poorly constrained, and on every
#     development recording it moved x by +7 to +16 mm for an unidentified
#     reason.
# With these changes all three development recordings pass (x 28-36 mm,
# 17-25 mm from the design value).
#
# Everything else - scoring procedure, metric, thresholds, failure policy, and
# requirements - is copied unchanged from the first pre-registration.  The
# audit protocol must cite this file's SHA-256 and may not change anything
# listed here.
claim: >-
  On a hand-held MID360 recording of the RTK-SLAM dataset that was not used to
  develop the method (construction_seq2), Calibrex's full IMU-LiDAR extrinsic
  (rotation, lever arm, and clock offset) predicts held-out
  accelerometer-integrated motion at least as well as LI-Init's, and so does
  its lever arm alone.
scope:
  modalities: [imu, lidar]
  quantities: [rotation, translation, time_offset]
  category: targetless_imu_lidar
recordings:
  evaluation: [construction_seq2]
  development_only: [stadtgarten_seq2, stadtgarten_seq1, construction_seq1]
methods:
  calibrex_native: >-
    `calibrex imu-lidar livox` on the whole recording, then
    `calibrex imu-lidar livox-translation` (method accelerometer_lever_arm/v0.2,
    default options) with that rotation artifact.  If the translation
    artifact's policy_status is neither pass nor warn, Calibrex has no
    estimate for the recording.
  li_init: LI-Init commit 66b157a refined result, run in the container with tools/external/li_init
  li_init_lever_arm: LI-Init's lever arm combined with Calibrex's rotation and clock offset
  design_reference: MID360 design value (identity rotation, (11.0, 23.29, -44.12) mm, dt = 0); sanity row
scoring:
  odometry: >-
    One common LiDAR odometry, deskewed with gyro rotations mapped by the
    design reference (identity rotation, zero clock offset, zero gyro bias),
    shared by every candidate.
  held_out_spans: Every third 10-second window of the common odometry (positions % 3 == 1), windows cut at span boundaries.
  gyro_bias: Refit per candidate on the train windows of the common odometry with its rotation and clock offset fixed.
  fixed: the candidate's rotation, clock offset, and lever arm
  refit_per_span: >-
    gravity and accelerometer bias per span piece, one velocity per 2-second
    segment (SCORING_OPTIONS in tools/score_mid360_imu_lidar_extrinsics.py,
    unchanged from the first audit)
  metric: per held-out span, the RMS of the position residual components, each clipped at 50 mm (metres, lower is better)
  unit_of_comparison: held-out span, paired across methods by span start time
  known_leakage: >-
    LI-Init fits on the whole recording; Calibrex's own train/holdout split
    need not coincide with the scoring spans.
failure_policy: a method without an estimate for a recording fails every span of that recording
requirements:
  - id: calibrex-estimate
    rule: calibrex_native failure_rate <= 0 on construction_seq2
  - id: calibrex-extrinsic-not-worse-than-li-init
    rule: paired improvement of calibrex_native over li_init, 95% bootstrap CI lower bound >= 0
  - id: calibrex-lever-arm-not-worse-than-li-init
    rule: paired improvement of calibrex_native over li_init_lever_arm, 95% bootstrap CI lower bound >= 0
  - id: calibrex-absolute-fit
    rule: calibrex_native mean per-span metric <= 0.010 m
missing_li_init: >-
  If LI-Init returns no result, its comparison requirements are recorded as
  missing and the claim is incomplete; no other recording is substituted.
coverage:
  minimum_dataset_families: 1
  minimum_independent_rigs: 1
known_limitations_at_registration:
  - x is 17-25 mm from the MID360 design value on every development recording.
  - The per-segment gravity norm ranges 9.68-10.05 m/s2 on development data, so it absorbs more than gravity.
  - The +x bias of 1-second segments is unexplained.
