Skip to content

feat(ops243): add internal hardware trigger - #221

Open
JPMarhefka wants to merge 7 commits into
open-flight:mainfrom
JPMarhefka:agent/hardware-trigger
Open

feat(ops243): add internal hardware trigger#221
JPMarhefka wants to merge 7 commits into
open-flight:mainfrom
JPMarhefka:agent/hardware-trigger

Conversation

@JPMarhefka

@JPMarhefka JPMarhefka commented Aug 18, 2026

Copy link
Copy Markdown

What does this PR do?

Adds an opt-in OPS243 internal hardware-trigger capture strategy for rolling-buffer mode.

  • Requires and validates OPS243-A firmware v1.3.1.
  • Adds --trigger hardware with hardware-mode defaults of a 25 mph outbound threshold, SM25, S#6, and 30 ksps.
  • Configures the OPS243 internal trigger, waits for the board-generated I/Q dump, parses the capture, and re-arms with GC.
  • Adds recovery for delayed UART output after a re-arm timeout.
  • Threads the hardware-trigger options through the server, monitor, and kiosk script.
  • Preserves the existing sound-trigger default and --sound-pre-trigger behavior.
  • Adds focused driver, strategy, CLI-forwarding, and documentation coverage.

Why was this required?

The existing rolling-buffer path depends on the external SEN-14262 sound-trigger edge. The OPS243 can perform the speed-trigger decision internally, allowing installations with the internal trigger wiring to capture the rolling I/Q history without requiring the sound-trigger module.

This is opt-in so existing installations continue to use sound mode unchanged. Hardware mode is intentionally limited to the OPS243 trigger path; unrelated experimental analysis, replay, board-diagnostic, clock, and UI work is not included.

Automated tests

  • PYTHONPATH=src uv run --no-sync pytest tests/ -q: 1,352 passed, 8 skipped, 17 warnings
  • uv run --no-sync ruff check src/openflight/: passed
  • uv run --no-sync pylint src/openflight/ --fail-under=9: passed, 9.72/10
  • cd ui && npm run build: passed
  • cd ui && npm run lint: passed

The focused tests cover command ordering, firmware and parameter validation, dump-boundary filtering, dump parsing, re-arm behavior and recovery, accepted/rejected captures, strategy selection, and CLI forwarding.

Manual (human) testing

Hardware testing was performed with an OPS243 running firmware v1.3.1.

  • The representative hardware-trigger run used the adjusted SM25 setting.
  • Approximately 9/10 representative shots were counted and parsed correctly as swings.
  • S#6 produced the best ball/club parsing compared with S#4 and S#8.
  • No ambient/noise false triggers were observed while keeping the magnitude above 20.
  • In club-only practice-swing testing, approximately 8/10 swings produced full outputs instead of the desired no-ball result. This is a known object-classification limitation and is distinct from the absence of ambient/noise false triggers.
  • The supplied Initial with ball.jsonl session recorded 18 hardware-trigger shot outputs with zero logged errors.
  • The supplied swing_only_no_ball.jsonl session recorded 4 accepted no-ball outputs with zero logged errors, documenting the limitation above.
  • Supplemental archive entries hit-0005 and hit-0006 produced usable ball/club outputs. The rail-adjacent energy in the I/Q view was the club passing close to the sensor and did not prevent useful output parsing.
  • Sound mode was not physically tested because the available setup was wired only for the internal hardware trigger. The sound-trigger implementation was not changed and remains the default; sound-mode hardware verification should be completed on a compatible setup before this PR is merged.

Checklist

  • Single feature/fix — this PR is scoped to the OPS243 internal hardware trigger
  • Automated tests included
  • Manual testing described
  • Python tests pass
  • Pylint passes
  • Ruff passes
  • UI builds
  • UI lint passes
  • Documentation and changelog updated
  • No unrelated changes mixed in

@JPMarhefka
JPMarhefka marked this pull request as ready for review August 18, 2026 22:15
@JPMarhefka
JPMarhefka requested a review from jewbetcha as a code owner August 18, 2026 22:15
Copilot AI lite review requested due to automatic review settings August 18, 2026 22:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in OPS243 internal hardware-trigger strategy for rolling-buffer capture, threading new configuration flags through the kiosk script and server so installations without the external sound-trigger module can still capture I/Q history (while keeping sound-trigger as the default).

Changes:

  • Add OPS243 driver support for configuring, waiting on, parsing, and re-arming the internal speed-trigger rolling-buffer dump (firmware-gated to v1.3.1).
  • Extend server/kiosk CLI plumbing with --trigger hardware plus hardware-mode defaults/overrides (threshold, magnitude, pre-trigger split) and corresponding validation.
  • Add focused tests and documentation for the new trigger mode and its operational constraints.

Reviewed changes

Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/test_start_kiosk.py Verifies kiosk CLI forwarding behavior for hardware trigger defaults and overrides.
tests/test_server.py Adds server CLI parsing/forwarding tests for hardware trigger mode and its constraints.
tests/test_rolling_buffer.py Registers/validates the new trigger strategy and adds behavior tests for accept/reject/re-arm flows.
tests/test_ops243.py Adds focused OPS243 command-ordering, validation, re-arm, and recovery tests for internal triggering.
src/openflight/server.py Adds hardware trigger CLI flags/validation and threads trigger kwargs into monitor startup.
src/openflight/rolling_buffer/trigger.py Implements HardwareTriggeredCapture strategy around board-managed trigger + host-side validation + re-arm.
src/openflight/rolling_buffer/monitor.py Configures OPS243 internal trigger on connect when trigger_type == "hardware".
src/openflight/rolling_buffer/init.py Exposes HardwareTriggeredCapture from the rolling_buffer package.
src/openflight/ops243.py Implements firmware validation, internal-trigger configuration, re-arm, and UART recovery behavior.
scripts/start-kiosk.sh Adds kiosk flag parsing and forwarding for hardware-trigger-specific settings.
README.md Documents the new opt-in hardware trigger mode and links to the new guide.
docs/rolling_buffer_spin_detection.md Clarifies the default sound-trigger pipeline and references the new hardware trigger option.
docs/hardware-trigger.md New guide describing command ordering, defaults, and retest expectations for internal triggering.
docs/CHANGELOG.md Adds an Unreleased changelog entry describing the new hardware trigger mode and constraints.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/openflight/server.py Outdated
Comment thread docs/hardware-trigger.md
@jewbetcha

Copy link
Copy Markdown
Member

This is great, and much needed. However we are waiting on Omnipresence for a way to update OPS radars to this version that doesn't require their extra device. Will ping them again to see if this is a realistic ask.

@HuggeK

HuggeK commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

So do we have the hex file to flash with the new firmware?

@JPMarhefka

Copy link
Copy Markdown
Author

So do we have the hex file to flash with the new firmware?

Send an email to Rob at customerservice@omnipresense.com. He will be able to get you the file once it's public and help you find the correct model SEGGER.

@HuggeK

HuggeK commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Review note: version != required in validate_internal_trigger_firmware() is exact-equality, so any future OPS243-A release (1.3.2+) gets refused even if it still supports STn/SMn. A >= comparison or a documented allowlist would age better.

Correcting my earlier version of this comment: I claimed boards reporting 1.5.2 would be blocked today. AN-010 rev AE Table 9 shows the OPS243-A line runs 1.2.3 → 1.3.1, with the SWn/SFn/STn/SMn enhancements only in 1.3.1 — so the pin is a genuine capability requirement, not just a tested-on marker. The 1.5.2 in docs/ops243-uart-migration.md:148 isn't on that line.

@HuggeK

HuggeK commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Docs suggestion for docs/hardware-trigger.md — the firmware prerequisite could name the two things that are easy to get wrong:

  • Run ?P first. Some rev D2+ boards use the XMC4700, most others the XMC4500; XMCFlasher needs the right one selected.
  • The hex isn't publicly downloadable — request it from customerservice@omnipresense.com. Flashing goes through the keyed J2 JTAG header, not the J3 UART link OpenFlight already uses.

Also worth a warning: AN-013 says never press Erase — it wipes factory settings and persistent memory, which is where A! stores rolling-buffer mode.

Not blocking; the code change is unaffected.

@HuggeK

HuggeK commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

waiting on Omnipresence for a way to update OPS radars ... that doesn't require their extra device

Possible cheap path. The OPS243's I/O is 3.3 V (this repo already wires Pi GPIO straight to J3 with no level shifter), and the XMC4500/4700 speaks SWD, which OpenOCD supports via its in-tree xmc4xxx driver. So a Raspberry Pi Debug Probe ($12) — or direct Pi GPIO on a Pi 4 — could in principle flash it without a SEGGER.

Caveats: XMCFlasher won't drive a CMSIS-DAP probe, so this is OpenOCD-only and off the vendor-supported path. Unverified on this board: BMI/boot-mode handling (J-Link does it automatically) and whether the part is read-protected. J2 is a keyed fine-pitch header, so it needs a proper cable — worth asking OmniPreSense for the pinout.

Vendor-blessed alternative: the SEGGER J-Link EDU Mini, which AN-013 links directly (adafruit.com/product/3571, $75.95).

Worth 30 minutes on a spare board. I wouldn't try it on the only radar in a build.

@HuggeK

HuggeK commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

So do we have the hex file to flash with the new firmware?

Send an email to Rob at customerservice@omnipresense.com. He will be able to get you the file once it's public and help you find the correct model SEGGER.

Email sent!

@HuggeK

HuggeK commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Instructions on how to apply the firmware update:
AN-013-F_Code Update.pdf

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.

4 participants