Decide: the pose contract — shape, units, site frame #7

Open
opened 2026-08-11 15:41:38 +00:00 by lars · 1 comment
Owner

Question

Lock the interface that the positioning half produces and the rendering half consumes, so integrating them later is plumbing rather than redesign.

Settle:

  • Shape — position, heading, confidence, timestamp. The starting proposal is {timestamp, position{x,y,z}, heading{yaw,pitch,roll}, confidence{positionM, headingDeg}}.
  • Units — meters, degrees, milliseconds since epoch.
  • Frame — an abstract site frame: a documented origin and forward axis, of which a ship frame (x = bow, y = starboard, z = up) is one instance and the office room is another. Avoids baking "bow" into a spec tested in an office.
  • Heading semantics — relative to the site frame, not magnetic north, given the magnetometer problem.
  • Confidence — keep it. It is the field that lets the renderer degrade honestly when a jittery estimate meets a photorealistic image, instead of snapping confidently to a wrong place.
  • Where the contract is written down so both session specs can cite it.

Also worth deciding here: whether deck identity is part of position from the start or added later (see the map's fog).


Part of the wayfinder map #1.

## Question Lock the interface that the positioning half produces and the rendering half consumes, so integrating them later is plumbing rather than redesign. Settle: - **Shape** — position, heading, confidence, timestamp. The starting proposal is `{timestamp, position{x,y,z}, heading{yaw,pitch,roll}, confidence{positionM, headingDeg}}`. - **Units** — meters, degrees, milliseconds since epoch. - **Frame** — an abstract **site frame**: a documented origin and forward axis, of which a ship frame (x = bow, y = starboard, z = up) is one instance and the office room is another. Avoids baking "bow" into a spec tested in an office. - **Heading semantics** — relative to the site frame, not magnetic north, given the magnetometer problem. - **Confidence** — keep it. It is the field that lets the renderer degrade honestly when a jittery estimate meets a photorealistic image, instead of snapping confidently to a wrong place. - Where the contract is written down so both session specs can cite it. Also worth deciding here: whether deck identity is part of position from the start or added later (see the map's fog). --- Part of the wayfinder map #1.
lars added this to the Wayfinder: RN prototyping spec milestone 2026-08-11 15:41:38 +00:00
lars added the wayfinder:grilling label 2026-08-11 15:41:38 +00:00
lars added a new dependency 2026-08-11 15:42:14 +00:00
Author
Owner

Hard constraint on the confidence field — ARKit gives you almost nothing to fill it with.

From the ARKit research pass:

  • Apple publishes no covariance and no accuracy field. The entire uncertainty API is a 3-state trackingState (normal / limited / notAvailable) plus two documented reasons that matter indoors: .excessiveMotion and .insufficientFeatures ("blank walls, low lighting" — i.e. a ship corridor).
  • limited tracking still returns a pose. Covering the camera or facing a blank bulkhead does not stop ARCamera.transform; it silently degrades to inertial dead reckoning. Nothing in the API tells you the pose just got much worse.

So confidence.positionM cannot be read from the platform — it has to be modelled. The realistic inputs are: distance travelled since the last absolute fix (see #15: drift is 0.5–8% of distance), time in limited state, and the tracking-state reason. That makes two fields worth adding to the contract:

  • metresSinceLastFix (or timeSinceLastFix) — the actual driver of positional uncertainty under VIO.
  • trackingQuality — pass ARKit's state through rather than collapsing it into a number, so the renderer can distinguish "drifting slowly" from "flying blind".

This matters more than usual because the display is a photorealistic render: a confidently-wrong pose produces a convincing image of the wrong place. The contract should make it impossible to render confidently without asserting a fix age.

**Hard constraint on the `confidence` field — ARKit gives you almost nothing to fill it with.** From the ARKit research pass: - **Apple publishes no covariance and no accuracy field.** The entire uncertainty API is a **3-state `trackingState`** (`normal` / `limited` / `notAvailable`) plus two documented reasons that matter indoors: `.excessiveMotion` and `.insufficientFeatures` (*"blank walls, low lighting"* — i.e. a ship corridor). - **`limited` tracking still returns a pose.** Covering the camera or facing a blank bulkhead does not stop `ARCamera.transform`; it silently degrades to inertial dead reckoning. Nothing in the API tells you the pose just got much worse. So `confidence.positionM` cannot be read from the platform — it has to be **modelled**. The realistic inputs are: distance travelled since the last absolute fix (see #15: drift is 0.5–8% of distance), time in `limited` state, and the tracking-state reason. That makes two fields worth adding to the contract: - **`metresSinceLastFix`** (or `timeSinceLastFix`) — the actual driver of positional uncertainty under VIO. - **`trackingQuality`** — pass ARKit's state through rather than collapsing it into a number, so the renderer can distinguish "drifting slowly" from "flying blind". This matters more than usual because the display is a **photorealistic render**: a confidently-wrong pose produces a convincing image of the wrong place. The contract should make it impossible to render confidently without asserting a fix age.
Sign in to join this conversation.