Repository navigation
feat(bench): app UI on the real plates over a 200 Hz bench stream - #13
Merged
Merged
Conversation
The production firmware and board-side main.py aren't written yet, so the app's UI has only run on synthetic swings. This feeds it real plate data: - bench/ads1220_stream: reads all 8 ADS1220s on L1's DRDY (~1 kHz), averages into 5 ms frames and prints 10 frames per Monitor line (B,<seq>,<t_first_us>,<period_us>,<flags>,<hex>), the fields of protocol.py's Batch. - tools/bench/live_plates.py: parses those lines into Batches and runs them through open_fp.app.Core behind the simulator's WebUI stand-in, serving app/assets on :7070. Seeds bench/live/config.json with signs -1 (these cells read lower under load) and zeroes the empty plates at start. - firmware CI compiles the new sketch; docs/harness.md 5 shows how to run it. On the plates: 197 frames/s by MCU time, no sequence gaps, ~5 % of frames held while the sketch prints. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- stance.js showed only the newest sample of each live message, so the CoP dot moved in 20 Hz steps (one batch per 50 ms). Samples now queue and play out per animation frame, 70 ms behind the newest; the trail follows the sample shown. A stream restart (time going backwards) clears the queue. - live_plates.py ticked the core every 10 ms whether or not frames had arrived; the empty `live` messages blanked the readouts (flicker). It now ticks only after new frames, like the simulator, and sends Cache-Control: no-cache so an edited page isn't served stale. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this PR do?
Runs the app's own web UI on the real plates, using real data from all 8 cells: live lead/trail weight shift, CoP on each plate, swing capture and the calibration wizard. It does this before the production firmware and board-side
main.pyexist.bench/ads1220_stream(new sketch): reads all 8 ADS1220s on each L1 DRDY tick (~1 kHz, or a 1 ms timer without L1). It averages the reads into 5 ms frames, the 200 Hzprotocol.pyexpects, and prints 10 frames per Monitor line:B,<seq>,<t_first_us>,<period_us>,<flags>,<hex>, 6 hex digits per 24-bit value.protocol.py: 0x01 means no reads for 50 ms, 0x02 means a board is at full scale.rre-checks every board and restarts the stream.tools/bench/live_plates.py(new): parses those lines intoprotocol.Batches and runs them throughopen_fp.app.Corebehind the simulator'sSimWebUIstand-in, servingapp/assetson :7070. It'ssim_server.pywith the Q in place ofsynth.ronce SSH is attached, prints which boards answer, and zeroes the empty plates at 6 s (--no-zeroturns that off).bench/live/data dir (git-ignored) getssignsof −1, because these cells read lower under load (every press in the bench press test was negative).app/assets/js/stance.js: the stance view used to show only the newest sample of each live message, so the CoP dot moved in 20 Hz steps. Batches arrive every 50 ms, on the board as well as here. Now the samples queue and play out one per animation frame, 70 ms behind the newest; the trail follows the sample shown. A stream restart (time going backwards) clears the queue.docs/harness.md§5: a short "Both plates in the app's UI" section.Why was this required?
Every unit on both carriers now passes the bench and press tests, and the owner wants to see weight move between the plates in something more polished than the bench live view. That means the app's UI, with both plates. The UI, pipeline and swing detector are written and tested but have only ever run on synthetic data, because the board side (M2/M3 firmware and
main.py) isn't written yet. This gets real data into them now with no new transport risk: it uses the same SSH monitor every bench tool uses. The production Bridge path stays a separate piece of work.Automated tests
tests/test_bench_live_plates.py:B,lines (partial values, non-hex, missing fields) are dropped.seed_configwritessignsof −1 to a fresh data dir and never overwrites an existing config.Core. Plates are zeroed empty, then a 70/30 stance with real-looking per-channel offsets. The live message reports lead 70 %, L 560 N and R 240 N.pytest: 207 passed.ruff: clean.pylint: 10.00 on the new file. The sketch compiles locally (arduino-cli compile --warnings default).Manual (human) testing
On the bench with both carriers and all 8 cells:
bench/ads1220_streamand captured the monitor for 10 s:0E C4 40 00;rrestart (127 ms), as designed.live_plates.pywith the owner on the plates; lead/trail and the force chart follow weight shifts.livepushes (the server now ticks only after new frames), and the dot stepped at 20 Hz (the playback above). After the fix, checked in the browser: the newstance.jsloads and runs with no console errors, at 207–221 Hz.Checklist
pytest)ruff check app/python tools tests docs/img)PYTHONPATH=app/python:tools/sim:tools/bench pylint app/python/open_fp tools/sim tools/bench --fail-under=9)docs/VERIFIED.md(measurements, fit checks, pin changes) — none; stream figures are in the harness docdocs/img/corner-assembly.svg, CAD STL/STEP) — n/a🤖 Generated with Claude Code