Skip to content

fix(ui): record the G peaks that were measured, not the ones the dial can draw - #209

Merged
PurpleSentinel merged 2 commits into
mainfrom
fix/162-g-peak-clamp
Oct 16, 2026
Merged

PurpleSentinel merged 2 commits into
mainfrom
fix/162-g-peak-clamp

Conversation

@PurpleSentinel

Copy link
Copy Markdown
Contributor

Closes #162.

The defect

ImuMeterController::rotate_sample() clamped both planar axes to kImuDisplayLimitG (2.0 g) before returning, and update() fed that already-clamped point to update_peaks(). The recorded session peaks were therefore bounded by the radar's drawing range rather than by anything the car did.

The evidence in the issue is a hand-shaken session that recorded 2577 milli-g — sqrt(2² + 2²), i.e. both axes sitting exactly on the clamp. That is the artwork's diagonal, not a measurement.

The vertical axis had the same problem by a different route: it was clamped on its way into the snapshot, so a kerb strike was logged as 2.0 g whatever it really was.

The fix

  • The measurement reaches update_peaks() first; the display clamps its own copy. The dial still never draws outside its 2.0 g artwork.
  • Peaks are bounded by a new kImuRecordedLimitG = 10.0F — a credibility limit, not a drawing one.
  • Anything beyond that limit sets ImuPeakSummary::truncated, so a clipped figure can never be read back as a real one.
  • A static_assert in screen_router.cpp ties kImuRecordedLimitG to logger::kMaximumCrediblePeakG, the bound the log writer already applied downstream. The two cannot drift apart silently.

Tests

Four new blocks in tests/cpp/test_imu_meter.cpp:

case expectation
2.6 g right-hand corner recorded as 2.6; dial reads 2.0
3.4 g vertical kerb strike recorded as 3.4
14 g spike bounded at 10.0 and truncated set
ordinary sub-2 g session unchanged by this work

I reinstated the clamp temporarily to confirm the new assertions actually fail without the fix:

imu_meter_test: tests/cpp/test_imu_meter.cpp:180: int main():
  Assertion `near(recorded.peaks.right_g, 2.6F)' failed.

Verification

  • simulator 76/76 pass
  • make check → CHECK_RC=0
  • firmware build clean, 0xfdb00, 32% free
  • repo-check passes

This is verifiable on the bench: shake the device in G-METER mode and the peak summary should now exceed 2.0 g. No car required.

Also in this PR

One unrelated commit adds blog/ to .gitignore — post drafts for caterham7diaries.com are written in the working tree because the facts have to come from this repository, but they are not part of its history.

🤖 Generated with Claude Code

PurpleSentinel and others added 2 commits October 16, 2026 20:47
The blog/ folder holds posts written for caterham7diaries.com. The device is the
subject and the facts have to come from this repository, which is why the drafts
are written here, but they are not part of this project's history.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… can draw

rotate_sample() clamped both planar axes to kImuDisplayLimitG before anything
else saw them, so the session peak summary was bounded by the radar's drawing
range rather than by what the car did. A hand-shaken session recorded 2577
milli-g, which is sqrt(2^2 + 2^2): both axes pinned at the clamp, not a
measurement.

The measurement now reaches update_peaks() first and the display clamps its own
copy, so the dial still stays inside its 2.0 g artwork while the peaks hold what
the IMU actually reported. Peaks are bounded instead by kImuRecordedLimitG, a
credibility limit at 10 g rather than a drawing limit, and anything beyond it
sets ImuPeakSummary::truncated so a clipped figure can never be read as a real
one. A static_assert ties that limit to logger::kMaximumCrediblePeakG, which is
the bound the log writer already applied downstream.

The vertical axis went the same way: it was clamped on its way into the snapshot,
so a kerb strike was recorded as 2.0 g whatever it really was.

Tests cover a 2.6 g corner recorded as measured while the dial shows 2.0, a
3.4 g vertical strike, a 14 g spike that is both bounded and flagged, and an
ordinary session that the change leaves untouched. The clamp was temporarily
reinstated to confirm the new assertions fail without the fix.

Closes #162

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@PurpleSentinel
PurpleSentinel merged commit 7839462 into main Oct 16, 2026
3 checks passed
@PurpleSentinel
PurpleSentinel deleted the fix/162-g-peak-clamp branch October 16, 2026 19:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Recorded G peaks are clamped by the display limit

1 participant