Local Level Lab

Airborne measurements. Open methods.

Participant collection now uses the stationary ground protocol. The aircraft/consumer sections below preserve the earlier method and its evidence; they are not the current stationary decision policy. NASA archival analysis remains primary. See the stationary method and validation needs.

The math

This is the mathematical reference for readers checking the equations. Start with the plain-language methodology for the flight signal and measurement procedure. An IMU (inertial measurement unit) combines instruments for measuring turning and acceleration.

All rates are angular velocities in rad/s, expressed in the local NED frame (north, east, down) unless noted. Reports convert them to °/h (1 rad/s = 206 264.8 °/h). The reasons behind each choice, the alternatives rejected and the simulation evidence are in METHODOLOGY.md. Historical numerical tables are in the technical evidence record; Evidence so far explains their limits and the current results.

What a gyro measures

A gyro measures the IMU's angular velocity relative to inertial space (any non-rotating frame). It senses this mechanically and doesn't look at anything. In the IMU's own axes:

ω_ib = C_bn · ω_in  +  ω_nb  +  bias  +  g-sensitivity · f  +  noise

The models: four defined, three tested

The labels below describe kinematic predictions. “Earth rotation” denotes the standard background angular-rate term in these equations; its presence in a successful fit does not independently determine its physical cause. “Still globe” sets that term to zero, so it does not represent a theory proposing a stationary Earth with a nonzero inertial field. The field-measurement plan separates free estimation from causal interpretation. Historical coefficient and uncertainty claims below belong to the earlier experiment, not a completed solar-versus-sidereal measurement.

Four kinematic models are defined. Three of them can be told apart by this protocol, and those three are the ones the analysis tests.

Earth rotation Transport (moving over the surface) tested?
Globe, rotating Ω (cos φ, 0, −sin φ) ω_en (globe) yes
Globe, still 0 ω_en (globe) yes
Flat disc, still 0 ω_disc yes
Flat disc, spinning (0, 0, −Ω), about the vertical everywhere ω_disc no: indistinguishable from the still disc (see below)

ω_en = ( v_E / (R_N + h), −v_N / (R_M + h), −v_E tan φ / (R_N + h) ) R_M = a(1−e²) / (1 − e² sin²φ)^{3/2} R_N = a / (1 − e² sin²φ)^{1/2}

For example, 224 m/s due north at the equator gives 7.29 °/h. At 900 km/h (250 m/s) it is 8.1 °/h. - Disc transport. The flat model is an azimuthal-equidistant disc centred on the north pole, with latitude as distance from the centre and north pointing to the centre. Moving east means circling the centre, so local level turns about the vertical once per 360° of longitude:

ω_disc = ( 0, 0, −dλ/dt )

The analysis takes dλ/dt straight from the logged GNSS longitudes, differentiated with 30-s smoothing, so the disc's prediction uses no velocity, no Earth radius and no disc scale. Westbound, dλ/dt is negative and local level turns the other way. The disc never tilts local level, so there is no horizontal part. The app's live display, which has only the current fix, uses the equivalent v_E / ((R_N + h) cos φ). - Why the spinning disc isn't tested. It differs from the still disc only by a constant rotation about the local vertical. This protocol can't separate that from the gyro's bias and g-sensitivity along gravity (see "The vertical channel"), so the two disc models make the same testable predictions. The tested flat model is the still disc, which is also how the flat model is usually stated. The spinning disc is still defined in the geometric truth generator (analysis/tests/truthgen.py), so anyone can check that claim.

Sign conventions, checked

NED is right-handed (N × E = D), and a rotation vector ω turns a frame-fixed vector at dr/dt = ω × r.

Independent check. analysis/tests/truthgen.py computes ω_in from frame geometry alone. It builds the NED axes at each position in an inertial frame and differentiates their orientation numerically, with no transport or Earth-rate formula. All three tested models agree with it to 9 × 10⁻¹² rad/s (EVIDENCE §1). Synthetic test data takes its gyro truth from this generator, never from lll.models. The same formulas are implemented in Kotlin for the live display and checked against docs/test_vectors.json.

Which measurement separates which models

At 40°N, 230 m/s due east:

globe, rotating globe, still disc
horizontal Ω cos φ + v/R tilt 7.4 °/h tilt 0
vertical −sin φ (Ω + dλ/dt) ≈ −16 °/h −6.2 °/h −9.7 °/h

The vertical channel

A rotation about the plumb line points along gravity. So does the gyro's g-sensitivity along that axis, and so does its bias along whichever IMU axis points up. In level flight, with the IMU's attitude fixed, all three are constants on the same IMU axis. Neither a stationary test nor level flight can separate them. Only changes in size, along the route or across latitudes, carry information. This is why a spinning disc can't be tested, and why the disc's own vertical term is identified only through how dλ/dt changes along the route.

Ground calibration

The IMU lies still in four positions: label up, label up turned 180° about the vertical, label down, and label down turned 180°. The app records them as a palindrome, each position twice in mirror order: up0 up180 down0 down180 (one double-length stay) down0 up180 up0. For each visit k, per axis:

m_k = b + d (t_k − t̄) + w_{p_k},     Σ_p w_p = 0

Reversal test (bench)

The IMU stays label up and is turned 180° about the vertical between placements, six pairs in all (rev.up0.N, rev.up180.N). Each pair gives h_N = (w₀ − w₁₈₀)/2 with the part along up removed, free of g-sensitivity for the same reason as above.

The pairs are placed against the same edge, so their vectors point the same way. The horizontal rate is the length of their mean, estimated with the same Rice likelihood, with intervals and the p-value of zero rate. The scatter of the pair lengths is the unit's repeatability.

In flight

Segments and bins

The flight is cut into stable cruise segments, each at least 10 minutes long:

Segments also break at GNSS gaps, Bluetooth drops, bumps and deliberate IMU turns. Each segment is averaged into 60-s bins.

The IMU's orientation

quantity source uses the gyro?
model prediction ω_in (NED) GNSS: latitude, height, north and east velocity no
apparent up axis accelerometer specific force (gravity plus aircraft acceleration) no
azimuth GNSS course, plus a fitted crab offset per course leg no
forward axis gyro roll rate during banked turns, correlated with the bank GNSS implies only the large roll transients (°/s), never the slow signal (°/h)
aircraft rotation ω_nb accelerometer tilt rate and GNSS course rate no
turns of the IMU itself gyro, integrated over the few seconds of the turn only the turn itself (tens of °/s)

Each deliberate turn of the IMU starts a new mount epoch. The gyro integrates the rotation during the turn to within about 0.1° (EVIDENCE §10). Later epochs are mapped back into the first epoch's frame, so banked turns anywhere in the flight give one forward axis.

Acceleration limitation and research correction. The accelerometer direction equals gravity direction only when translational acceleration is negligible. With the specific-force convention used here, f_b = C_bn (a_n − g_n). Consequently true up is proportional to f_b − C_bn a_n. Treating unit(f_b) as up while differentiating it can introduce a false tilt rate. Saved replay data show this is a material processing error even in retained cruise.

The research prototype in the acceleration study uses frequent observed GPS velocity/altitude and actual IMU force magnitude, with common filter support, to estimate acceleration and solve the orientation relation iteratively. It differentiates recovered orientation before averaging rates into minutes. Mount mappings, forward direction and provisional crab states constrain azimuth. Unsupported gaps and force/ acceleration states are excluded locally. The approximation differentiates local velocity components without model-specific Coriolis or curvature acceleration; their bounded systematic effects remain necessary. It is not enabled in the production fit. Finite wind/forward/filter sensitivity and independent-observation error propagation are diagnostics, not validated coverage or replacements for jointly fitting motion and nuisance parameters.

The joint research prototype now recomputes C_bn, aircraft angular rate and science prediction at each wind/forward state. Six coherent acceleration/force error modes enter the same prediction with provisional unit Gaussian priors, so the Jacobian and local joint covariance include their cross-couplings. Fixed support is determined from observed data before fitting; trial parameters cannot select different rows. Twenty-four saved-data fits converge and nest correctly, with no boundary flags. This remains outside production: local penalized curvature is not validated coverage, six coherent modes do not span all measurement errors, and the inherited conditional GPS/TAS likelihood and original gyro weights are not a fully joint measurement likelihood.

The saved-data bandwidth check applies an identical additional linear operator to the gyro and complete reconstructed prediction. With one-second observations in a reference frame, its minute operator is L = A H, where H is the supported Hann filter and A is trapezoidal minute integration. Under independent one-second error blocks S, the propagated covariance is V = Q L S Lᵀ Qᵀ, with axis identities implicit and Q rotating each minute back to its sensor frame. Off-diagonal time/axis blocks are retained. This gyro-only calculation omits shared GPS/force errors and the response of fitted parameters. The slower science/bias terms are interpolated for this diagnostic; a continuous measurement equation is required before using this operator in refits.

The continuous sampled research equation now evaluates science terms and sensor-frame bias splines at GPS timestamps. Point-local attitude derivatives are chained through sparse filter/gradient operators to obtain residual input Jacobian B. The physical wind constraint has input Jacobian E from the same GPS velocities. Joint propagation is [B; E] S [B; E]ᵀ, retaining their cross covariance. S includes north/east GPS velocity covariance and time-matched force/gyro blocks under independent-second assumptions; references and scales stay fixed.

For prediction Jacobian J, old weights W, auxiliary parameter Jacobian T and deterministic penalty P, let N = Jᵀ W J + Tᵀ T + Pᵀ P. Local parameter response is δz = N⁺ (Jᵀ W B - Tᵀ E) δx, and residual response is B δx - J δz. This is local Gauss–Newton sampling propagation at saved parameters, not a refit or posterior covariance. Independent direct least-squares checks reproduce it. Unknown input correlations and calibration/mount/systematic uncertainty remain omitted.

The temporal sensitivity calculation factors each input block as S_i = Q_i Q_iᵀ, standardizing channels before taking the principal symmetric correlation root. IMU factors are constructed in sensor axes and mapped into the recovered reference frame. For latent response D_i = [B_i; E_i] Q_i, propagation sums D_i exp(-|t_i-t_j|/τ) D_jᵀ over times, separately for GPS/IMU blocks; τ=0 recovers independent seconds. Forward/backward recurrences apply the exact kernel without a dense timestamp covariance. Elapsed gaps carry covariance, not observations. The finite persistence grid is conditional sensitivity, not a calibrated error envelope.

The frozen-covariance objective uses r=[measured-minus-predicted gyro; positive wind auxiliary] and G=[-J; T], matching the signs used in propagated covariance. For fixed positive-definite C, F(z)=rᵀ C⁻¹ r+||Pz||²; Gaussian deviance also includes log det C. Unit-standardized Cholesky whitening preserves all cross blocks. No covariance modes are clipped or dropped. The physical wind candidate adds independent normalized auxiliary variance1, retaining its existing2m/s discrepancy allowance in addition to propagated measurement covariance. This changes only the auxiliary block; shared GPS cross covariance remains intact. Local GLS sampling covariance and inverse penalized curvature are reported separately. This working objective is conditional on frozen provisional matrices, not a promoted likelihood, calibrated model decision or outcome-independent acceptance gate.

The saved-data GLS comparison now fits this continuous equation under four separately frozen persistence assumptions. Each comparison minimizes the same F freely and at the three model anchors. It uses exact science/bias derivatives and bounded finite derivatives for the nonlinear motion parameters. All 96 optimizations converge; all 24 constrained comparisons nest correctly. This numerical result does not choose a persistence assumption.

Its local pair diagnostic whitens G, projects the science columns orthogonally away from the span of the nuisance columns, and evaluates each model difference in that projected space. Penalties are excluded from this diagnostic; a normalized least-squares cutoff of 1e-10 controls numerical projection. Retention is the ratio of projected to unprojected squared contrast norm. This is a fitted-state description of the remaining information, with no acceptance or decision threshold. It does not replace the conservative geometry-based design gate.

The fit

For each bin:

y = m − b_cal(t) − ω_nb  =  C_bn (k_rot·E_globe + k_curv·T_globe + k_disc·T_disc)  +  b_res[g]  +  noise

Expected k for each model, in the order (k_rot, k_curv, k_disc): rotating globe (1, 1, 0), still globe (0, 1, 0), disc (0, 0, 1).

Calibration vector covariance (0.6.0)

With regression design X and estimated per-visit axis covariance S, the coefficient covariance is Vθ = (XᵀX)⁺ ⊗ S (coefficient-major order). S includes residual cross-axis covariance and a nonnegative diagonal addition for the white-noise floor. Let A map the independent fitted position coefficients to all four positions, with w_down180 = −w_up0 −w_up180 −w_down0. Each face has horizontal projector P_f = I − u_f u_fᵀ and contrast (w_f0 − w_f180)/2. Stack those projected contrasts into L. The exported six-vector covariance is V_h = L (A ⊗ I) Vθ (Aᵀ ⊗ I) Lᵀ, including cross-face blocks. Covariance units are (degree/hour)², ordered up-x/y/z then down-x/y/z.

The existing Rice magnitude summary is explicitly an approximate diagnostic: it reduces each projected covariance to half its trace and treats faces as independent, discarding anisotropy and cross-face covariance. Its nominal intervals and p-values are not general anisotropic inference. Ground population pooling remains disabled pending validation.

Uncertainty and model tests

Mount slip watchdog

A slow turn of the IMU in its mount about the vertical goes straight into the vertical gyro channel. The accelerometer can't see it, but the magnetometer can. The horizontal field, in a level frame fixed to the IMU, is modelled as complex numbers:

z(t) = e^{iδ(t)} ( s(t) e^{iθ(t)} H + c ),     θ = ψ − D

The slip rate δ̇ is the slope of the leftover angle in each segment. A segment is excluded when the slip exceeds 1.5 °/h and 3σ.

The watchdog runs twice. One version uses D and s from the World Magnetic Model, which is built on a globe. The other uses none, with D constant and s = 1, as a cross-check. A segment is left out of the gyro fit when the WMM version sees slip above 1.5 °/h and 3σ. Both results are reported.

The choice uses only the magnetometer and GPS, and the gyro fit itself never uses the magnetometer. A selection rule can still shift k, if what it drops correlates with the model terms. So whenever the WMM version excludes anything, the fit is repeated with no exclusions. If a model's rejection changes or any k moves by more than 1σ, the session is flagged wmm_selection_sensitive and left out of the primary result. The no-declination version alone would read the route's real declination change as slip.

Pooling many sessions

Sessions with the same IMU share its quirks, so pooling is hierarchical, with random effects at each level. τ² comes from REML, and standard errors are modified Hartung–Knapp, with t intervals on n − 1 degrees of freedom:

sessions → per IMU unit → population of units

Each level adds the scatter between its members (τ²) to their error bars. The three k come from the same flights, so the model tests pool them jointly:

P_i = (C_i + diag τ²)⁻¹ over the terms session i identified,   V = (Σ P_i)⁻¹,   k̄ = V Σ P_i k_i

This runs within each unit, then across units, and V's diagonal is never below each term's own Hartung–Knapp variance. Each model's expected k is tested with χ² = dᵀ V⁻¹ d. With few units it is referred to F(p, df), using the smallest per-term df. A model is rejected at p < 0.0027 (nominal).

Only sessions that pass every gate enter the primary result:

Breakdowns by heading, mount, IMU variant and unit are consistency checks. Groups that disagree (heterogeneity p < 0.01) are flagged, never averaged away.

Ground results across latitudes:

Unit quality tiers use instrument criteria only, never which model wins:

Horizontal repeatability comes from the reversal test when there is one, else from the palindrome calibration's σ. Allan deviation is also reported at 60, 900 and 1800 s. Its minimum is descriptive only, because it depends on run length and estimator. All thresholds are provisional until real units are measured (BENCH.md).

tier requirement
qualified Allan deviation at 300 s ≤ 3 °/h on the worst axis, and horizontal repeatability ≤ 2 °/h
usable ≤ 6 °/h and ≤ 4 °/h, where measured
exploratory anything else

Known approximations (please review)