Skip to content

experiment: IMU + log rate to 416 Hz for SD writer stress test#643

Closed
sritchie wants to merge 2 commits into
feat/vn300-400hz-baud-bumpfrom
experiment/vn300-416hz-stress
Closed

experiment: IMU + log rate to 416 Hz for SD writer stress test#643
sritchie wants to merge 2 commits into
feat/vn300-400hz-baud-bumpfrom
experiment/vn300-416hz-stress

Conversation

@sritchie
Copy link
Copy Markdown
Collaborator

THROWAWAY BRANCH — not for merge. Stacked on top of #642 (VN-300 400 Hz / 921600 baud).

Purpose

Find out whether OnSpeed's LogSensor / xWriteMutex / ring can keep up at 2x the production sample-rate load. If yes, we plan a real 416 Hz PR with proper AHRS/EKFQ retuning. If no, we know the SD-writer pipeline is the bottleneck and we plan how to fix it.

What this does

Layer Production This branch
kImuSampleRateHz 208 416
IMU330 ODR bits (CTRL1_XL / CTRL2_G) 0101 0110
g_Config.iLogRate 50 or 208 (per web UI) hardcoded 416 at boot
SensorIO write-path branch == 208 >= 208
SensorIO row rate 208 rows/sec 416 rows/sec
AHRS update rate 208 Hz 416 Hz
EKFQ dt ~4.8 ms ~2.4 ms

The VN-300 (from the base PR) already runs at 400 Hz, so this is a true 2x sustained stress on the writer.

What this does NOT do

Things that would be required for a real merge but are deliberately omitted:

  • Retune Madgwick beta gain (function of dt)
  • Update SavGol derivative window sizes
  • Refit EKFQ tuning (gyro-bias process noise scales with dt)
  • Update native test goldens (test_ahrs, test_ekfq_octave, regression snapshot harness all bake in 208 Hz)
  • Add 416 to the web UI rate radio
  • Audit running-average windows that assume 208 Hz

So native tests will drift on this branch; that's expected and ignored.

Bench protocol

.claude/skills/bench-stress/SKILL.md is the canonical procedure. The stress script is tools/bench/stress_web_handlers.py.

🤖 Generated with Claude Code

sritchie and others added 2 commits May 23, 2026 06:47
Closes #637.

Wire format changes from a 127-byte / 50 Hz / 115200 frame to a 138-byte
frame with four active groups (Common + Time + GNSS1 + AHRS). New
per-sample timestamps land in vnTimeStartupNs (ns since boot, always
advancing) and vnTimeGpsNs (ns since GPS epoch, valid once dateOk).
The old 5 Hz GNSS1.UTC string column is dropped.

OnSpeed's EFIS serial port now opens at 921600 baud for VN-300; the
new frame at 400 Hz is 55.2 kB/s on the wire, which 115200 cannot
carry. Other EFIS types (Dynon, Garmin, MGL) keep their 115200 baud
and their native broadcast rates (10-50 Hz).

The VN-300 hardware must be reconfigured to match: write reg 75
($VNWRG,75,1,1,1B,01E3,0200,0090,0142), reg 5 ($VNWRG,5,921600,1),
then $VNWNV to persist. Coupling is intentional and fail-closed —
the parser memcmps the 10-byte header so an unconfigured VN-300
produces zero vn* data rather than corrupt output.

Group masks verified against the canonical vnproglib enum:
- Common 0x01E3 = TimeStartup + TimeGps + AngularRate + Position +
                  Velocity + Accel
- Time   0x0200 = TimeStatus
- GNSS1  0x0090 = Fix + VelNed
- AHRS   0x0142 = YawPitchRoll + LinearAccelBody + YprU

Changes
- software/Libraries/onspeed_core/src/efis/Vn300.{h,cpp}: 138-byte
  frame layout; new kHeader[10]; sync detection on 0xFA 0x1B;
  TimeStartup/TimeGps/TimeStatus decode; szTimeUTC + formatTimeHmsMs
  removed
- software/Libraries/onspeed_core/src/types/LogRow.h: vnTimeUtc
  string + kLogRowUtcTimeLen replaced by three numeric fields
- software/Libraries/onspeed_core/src/proto/LogCsv.{h,cpp}: column
  header line and row emission use the three new numeric columns;
  the comma-in-vnTimeUtc assertion is removed (u64/u8 can't produce
  commas)
- software/Libraries/onspeed_core/src/proto/LogCsvHeaderIndex.{h,cpp}:
  three new idx fields; require-all list grows from 26 to 28; unused
  TakeString helper removed
- software/sketch_common/src/io/EfisSerialPort.{h,cpp}: SuVN300Data
  carries the three new fields; Init() picks 921600 for VN-300,
  115200 for everything else
- software/sketch_common/src/tasks/LogSensor.cpp: plumb new fields
  into LogRow; drop VN-300 utcOrNull source for the sidecar meta
  builder (reconstruct offline from vnTimeGpsNs if needed)
- software/Libraries/onspeed_core/src/test_frames/SynthFrames.cpp:
  138-byte synth frame
- test/test_efis_vn300: new fixture builder, new tests for per-sample
  timestamps and TimeStatus; old-format rejection test
- test/test_efis_vn300_crc_parity: 137-byte fuzz buffer
- test/test_log_csv, test/test_log_csv_header_index: new column names,
  new round-trip assertions; obsolete vnTimeUtc tests dropped
- test/test_efis_dispatcher, test/test_synth_frames: 138-byte builder
- docs/site: vectornav.md rewritten for 400 Hz / 921600 / new VNCC
  config recipe; log-columns.md describes the three new columns

Verification
  pio test -e native             1169 passed, 1 skipped
  pio run -e esp32s3-v4p         SUCCESS (15.7% flash, 22.3% RAM)
  tools/regression/run_snapshot  all 5 goldens match

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
THROWAWAY BRANCH — not for merge. Built to flash on the bench and
exercise the LogSensor / xWriteMutex / ring under 2x the production
sample-rate load.

Changes
- HardwareMap.h: kImuSampleRateHz 208 → 416
- IMU330.cpp: CTRL1_XL and CTRL2_G ODR bits 0101 → 0110 (next LSM6
  datasheet step)
- OnSpeed-Gen3-ESP32.ino: hardcode g_Config.iLogRate=416 after
  LoadConfig so the writer fires every IMU sample, not every 4th
- SensorIO.cpp: loosen iLogRate == 208 comparisons to >= 208 so the
  IMU-rate-write path stays active at 416 Hz

What this does NOT do (and would need to before any real merge):
- Retune Madgwick beta for the new dt
- Update SavGol window sizes
- Refit EKFQ tuning (gyro-bias process noise scales with dt)
- Update regression goldens (test_ahrs, test_ekfq_octave, the snapshot
  harness all bake in 208 Hz assumptions)
- Update the web UI radio to expose 416 as a selectable option

Verification
  pio run -e esp32s3-v4p   SUCCESS

Bench protocol: .claude/skills/bench-stress/SKILL.md
@sritchie sritchie force-pushed the feat/vn300-400hz-baud-bump branch from b296a8a to 85b227b Compare May 25, 2026 13:37
@sritchie sritchie closed this May 25, 2026
@sritchie
Copy link
Copy Markdown
Collaborator Author

spoiler alert, it now can!

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.

1 participant