Skip to content

Rotation integrated as translation on Xiaomi 2406APNFAG after HyperOS 2026-06-12 (camera↔IMU clock offset 13–35 ms) #1779

Description

@rutmir

ARCore: rotation is integrated as translation on Xiaomi 2406APNFAG / HyperOS 2026-06-12

Status: open, blocks on-device acceptance (T045). Not an application defect — see
"Why this is not the app" below.

Summary

On this device ARCore tracks orientation correctly but produces tens of metres of
phantom translation whenever the device rotates. Rotating in place for 35 s moves the
reported camera pose 13 m up and 14 m sideways. The device is stationary and stable
when not rotating, so the fault is specific to angular motion.

Environment

Device Xiaomi 2406APNFAG ("degas"), MediaTek, Mali GPU
OS HyperOS OS3.0.302.0.WNERUXM, built 2026-06-12, Android 16 (API 36)
Play Services for AR 1.55.261550593 (also reproduced on 1.54.260890093)
ARCore SDK 1.54.0 (also reproduced on 1.52.0)
Camera android.sensor.info.timestampSource = REALTIME
IMU uncali_gyro / uncali_acc at 200 Hz (hardware max 400 Hz)

Worked before the 2026-06-12 firmware update; broke after it. Reproduced with a build
predating any recent app change (identical fault counts), so app code is not involved.

Measurements

Camera pose is read once per second via ArCamera_getViewMatrix; "path" is the summed
frame-to-frame distance of the camera position, i.e. how far ARCore believes the device
has travelled.

Device stationary on a table, 16 s — healthy:

camera [0.040 0.002 -0.017] fwd [0.02 -0.98 -0.22] path 0.07m
camera [0.040 0.002 -0.017] fwd [0.02 -0.98 -0.22] path 0.10m

Position varies by ~1 mm; path accumulates 3 cm (≈2 mm/s).

Rotating in place, no walking, 35 s — broken:

camera [-6.231 10.310  0.740] fwd [-0.58 -0.03  0.82] path  90.31m
camera [-9.759 11.154 -7.014] fwd [-0.83  0.05 -0.55] path  99.58m
camera [-11.052 11.618 -12.034] fwd [-0.69 0.07 -0.72] path 105.55m
camera [-13.800 13.232  8.315] fwd [ 0.98  0.15  0.15] path 138.94m

Path accumulates 48.6 m (≈1.4 m/s, 700× the stationary rate). Reported altitude reaches
+13.2 m while the phone stayed in the user's hands at ~1.5 m. The fwd vector sweeps
smoothly through the full rotation, so orientation is correct throughout.

Scale is also wrong. When planes are detected at all, they land at implausible
distances — a floor plane ~1.5 m in front of the user was reported at
[0.30, -4.05, -12.28], i.e. 12 m away and 4 m below. Metric scale in VIO comes from the
IMU, which is consistent with a timing fault.

Plane detection. Zero planes ever on ARCore 1.54. On 1.55 planes appear
(planes: 0 -> 2 -> 3 -> 4 -> 6 -> 7 -> 10 -> 11) but collapse to 0 whenever tracking
hiccups, and none are found at all while rotating.

ARCore's own diagnostics

Throughout every run, ~20–30 occurrences per 45 s:

E feature_tracks_producer.cc:886] Camera to IMU clock offset (34.86ms) exceeds threshold (5ms)
I vio_fault_detector.cc:636] [VioFaultDetector] Insufficient inliers or feature ratio (0 / 238)

Measured offsets range 13–35 ms with both signs across sessions; within a session they
are stable (e.g. 34.85 / 34.86 / 34.86 ms). ArCamera_getTrackingFailureReason returns
NONE almost always, occasionally INSUFFICIENT_FEATURES — ARCore does not attribute
the fault to lighting, motion, or texture.

Features are found and rejected geometrically (0 of 238 inliers), which is what a
constant temporal misalignment between image and IMU produces.

Why this is not the app

  • The failure is identical on a build predating all recent app changes (17 vs 15
    clock-offset errors, 41 vs 41 inlier faults over equal intervals).
  • VIO runs on ARCore's own threads fed directly by the camera datasource; the app's
    render loop is not in that path.
  • All three camera configurations the device offers (640×480, 1280×720, 1920×1080, all
    30 fps, camera 0) were tested: identical clock-offset counts, zero planes in each.
  • get_planes() uses the canonical trackable enumeration; the emptiness comes from ARCore.
  • Adding HIGH_SAMPLING_RATE_SENSORS changed nothing — ARCore itself requests 200 Hz.
  • Clearing Play Services for AR data changed nothing.

Reproduction

  1. Launch any ARCore session on the device above.
  2. Hold the phone in one spot and rotate left/right ~90° for 30 s without walking.
  3. Read the camera pose from ArCamera_getViewMatrix once per second and sum
    frame-to-frame distance.

Expected: path stays near zero. Actual: path grows by tens of metres, reported position
leaves the room.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions