Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ See the **[Parts List](docs/get-started/parts.md)** for everything you need with

### 2. Wire it up

Follow the **[Sound Trigger Wiring Guide](docs/build/sound-trigger.md)** to connect the SEN-14262 to the OPS243-A. The (deprecated) K-LD7 modules connect via USB — no wiring needed.
Follow the **[Sound Trigger Wiring Guide](docs/build/sound-trigger.md)** to connect the SEN-14262 to the OPS243-A. The (deprecated) K-LD7 modules connect via USB — no wiring needed. The OPS243 also has an opt-in internal speed-trigger path, which requires OPS243-A firmware v1.3.2 or newer in the 1.3 release train; see the **[Internal Hardware Trigger Guide](docs/hardware-trigger.md)**.

**Adding the IWR6843 angle radar?** The Pi cannot power both radars over USB, so
the OPS243 moves to the Pi's GPIO UART header while the TI board takes the USB
Expand Down
8 changes: 8 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
and a trigger-frame impact marker. MP4 conversion starts only after a manual
Replay selection, caches the result beside the raw capture, and reports
retryable preparation or playback failures without affecting shot results.
- **Opt-in OPS243 internal hardware trigger.** `--trigger hardware` configures
the radar's internal speed trigger with 25 mph, magnitude 25, and the tested
`S#6` split at 30 ksps. Captures are parsed and the radar is re-armed with
`PA` after each dump. The existing sound-trigger default and
`--sound-pre-trigger` behavior are unchanged. Hardware mode requires and
validates OPS243-A firmware v1.3.2 or newer in the 1.3 release train;
firmware v1.3.1 is rejected because of a vendor data-sequence bug. See
[OPS243 Internal Hardware Trigger](hardware-trigger.md).
- **Battery and external-power status for Raspberry Pi UPS boards.** OpenFlight
can now display charging state and battery percentage, issue dismissible 20%
and 10% warnings while discharging, and record throttled power telemetry in
Expand Down
24 changes: 12 additions & 12 deletions docs/get-started/parts.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Hardware components for building the OpenFlight golf launch monitor.

The sound trigger detects club impact to precisely time radar captures. Essential for spin detection via rolling buffer mode.

> **Optional path, not merged yet:** [PR #221](https://github.com/open-flight/openflight/pull/221) adds an opt-in `--trigger hardware` mode in which the OPS243 fires the rolling-buffer dump from its own internal speed trigger, with no SEN-14262 in the loop. It needs OPS243-A firmware 1.3.2, which every OPS243-A can run; whether getting there costs you anything depends on the firmware your radar arrived with, see [Internal Trigger Instead](#internal-trigger-instead-pr-221) below. Until the PR lands the sound trigger is the supported trigger and stays in the totals.
> **Optional internal-trigger path:** Hardware mode lets the OPS243 fire the rolling-buffer dump from its own internal speed trigger, with no SEN-14262 in the loop. It requires OPS243-A firmware 1.3.2 or newer in the 1.3 release train; firmware 1.3.1 is rejected because of a vendor data-sequence bug. See [Internal Hardware Trigger](#internal-hardware-trigger) below.

| Part | Description | Link | ~Price |
|------|-------------|------|--------|
Expand All @@ -49,7 +49,7 @@ SEN-14262 Raspberry Pi OPS243

See [sound-trigger-wiring.md](../build/sound-trigger.md) for detailed instructions and troubleshooting.

### Internal Trigger Instead (PR #221)
### Internal Hardware Trigger

> **Why this is worth wanting, beyond the parts it saves.** A microphone cannot
> tell your strike from someone else's, and it cannot tell either from a door,
Expand All @@ -60,12 +60,12 @@ See [sound-trigger-wiring.md](../build/sound-trigger.md) for detailed instructio
> responds to something moving in front of the sensor rather than to sound in
> the building. In theory that makes it both less error-prone and usable in
> loud places the sound trigger cannot cope with. Treat that as the expectation
> rather than a measured result: the mode is still unmerged, and nobody has
> published a false-trigger comparison between the two.
> rather than a measured result: nobody has published a false-trigger
> comparison between the two.

[PR #221](https://github.com/open-flight/openflight/pull/221) lets the OPS243-A start the rolling-buffer capture from its own speed trigger, so the sound detector, its resistor and its wiring are not needed. The firmware that adds that trigger is OPS243-A 1.3.2, and any OPS243-A can be brought to it. What that costs you depends on what your radar arrived with, so check before buying anything: plug the radar into USB, open a serial terminal, send `?V`, and read the version it prints back.
Hardware mode lets the OPS243-A start the rolling-buffer capture from its own speed trigger, so the sound detector, its resistor and its wiring are not needed. The supported firmware is OPS243-A 1.3.2 or newer in the 1.3 release train. Check before buying anything: plug the radar into USB, open a serial terminal, send `?V`, and read the version it prints back.

- **It reports 1.3.2 or later.** Nothing to buy. OmniPreSense [told the project on 2026-09-10](https://github.com/open-flight/openflight/pull/221#issuecomment-5619646576) that 1.3.2 went onto the sensors shipping from that build on (1.3.1 had gone to some earlier customers with a late bug), so a new order should arrive like this. Once the PR lands, skip the Sound Trigger table above.
- **It reports 1.3.2 or later in the 1.3 train.** Nothing to buy; use `scripts/start-kiosk.sh --trigger hardware`. OmniPreSense [told the project on 2026-09-10](https://github.com/open-flight/openflight/pull/221#issuecomment-5619646576) that 1.3.2 went onto the sensors shipping from that build on (1.3.1 had gone to some earlier customers with a late bug), so a new order should arrive like this. Skip the Sound Trigger table above if you choose hardware mode.
- **It reports 1.3.1 or older.** You flash it yourself, which is where the debugger cost comes in. OmniPreSense's [AN-013 code-update note](https://omnipresense.com/wp-content/uploads/2019/06/AN-013-D_OPS241-Code-Update.pdf) is the procedure: a SEGGER J-Link on the radar's keyed `J2` JTAG header (a 10-pin 1.27 mm Cortex debug header, not the `J3` UART header OpenFlight wires to), Infineon's free XMCFlasher in Serial Wire Debug mode with the XMC4500-1024 target selected, and the 1.3.2 hex file, which is not a public download — OmniPreSense hand it out on request. **Two ways to ask, both confirmed by Sandy at OmniPreSense**, who [said on the project Discord](https://github.com/open-flight/openflight/pull/221#issuecomment-5619646576) *"If you have a Segger programmer, and would like to update the code on your OPS243, please send me a message here or via email on our website"*: message them on **Discord**, or use the **contact page on [omnipresense.com](https://omnipresense.com/contact/)**. The customerservice@omnipresense.com address reaches them too. They will also confirm which J-Link model to get. Send `?P` first and pick the XMC4700 in XMCFlasher instead if the board reports that part ([note on the PR](https://github.com/open-flight/openflight/pull/221#issuecomment-5463503457)). Do not press Erase in XMCFlasher: it clears the factory settings some sensors carry and anything you saved to persistent memory. On Windows run the J-Link driver installer as administrator and tick the legacy J-Link USB driver, or XMCFlasher will not find the probe ([upgrade report](https://github.com/open-flight/openflight/pull/221#issuecomment-5756563718)).

| Part | Description | Link | ~Price |
Expand Down Expand Up @@ -383,12 +383,12 @@ and its four cells come to $32, so the battery line is $116 gross and
changes: the X1206 V2.0 carries its four 21700 holders on the board, uses the
same power-button header, and takes the same 12 V adapter.

If the [PR #221](https://github.com/open-flight/openflight/pull/221) internal
trigger lands, the Sound Trigger line ($18) becomes optional and drops out of
every total above for a radar that already reports firmware 1.3.2. For one that
arrived with 1.3.1 or older, the swap instead costs the ~$76 J-Link EDU Mini
listed under [Internal Trigger Instead](#internal-trigger-instead-pr-221), a
one-off tool that flashes the 1.3.2 firmware.
With the internal hardware trigger, the Sound Trigger line ($18) becomes
optional and drops out of every total above for a radar that already reports
firmware 1.3.2. For one that arrived with 1.3.1 or older, the swap instead costs
the ~$76 J-Link EDU Mini listed under
[Internal Hardware Trigger](#internal-hardware-trigger), a one-off tool that
flashes the 1.3.2 firmware.

OpenFlight works without any angle radar: you get ball speed, club speed, smash
factor, spin rate, and estimated carry. The angle radar adds measured launch
Expand Down
101 changes: 101 additions & 0 deletions docs/hardware-trigger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# OPS243 Internal Hardware Trigger

OpenFlight’s `hardware` trigger mode lets the OPS243-A decide when a rolling-buffer capture starts. It is opt-in; the kiosk default remains the existing SEN-14262 sound trigger.

## OPS243 firmware prerequisite

Hardware-trigger mode requires **OPS243-A firmware v1.3.2 or newer in the 1.3
release train**. Firmware v1.3.1 has a vendor data-sequence bug and is rejected.
The driver queries `?V` before sending the internal trigger setup commands and
fails fast if the reported version is from an older or different release train,
malformed, or unavailable. Update the physical OPS243 using the manufacturer’s
firmware procedure before running `--trigger hardware`; this application does
not flash the radar.

## Methodology

The host configures the radar once and then waits for the radar’s completed rolling-buffer dump. The host does not poll speed reports or send `S!` for each shot:

1. Put the radar in idle mode with `PI`.
2. Set a temporary outbound `ST-90` guard before entering rolling-buffer mode.
`GC` can restore the detector units to m/s before `US` is sent; 90 is below
the 30 ksps ceiling of 93.2 m/s and is still above ordinary startup motion
if the board retained mph units.
3. Enter rolling-buffer mode with `GC`, then resend the guard because `GC`
resets detector settings.
4. Restore the detector settings that `GC` resets: 30 ksps and MPH units first,
then raise the temporary guard to `ST-200` while the remaining settings are
written: 128 samples, `X=2`, outbound filtering, JSON plus magnitude output,
and the configured `S#n` split.
5. Restore the magnitude gate `SMn`, then restore the requested `ST-n` last and allow the 4,096-sample history to fill.
6. Wait for the board-triggered dump, parse the I/Q payload, and reject it if it has no outbound ball-speed reading at or above 35 mph.
7. Re-arm with `PA`. After a dump the board drops to idle power mode with every
detector setting intact, so `PA` alone resumes sampling. Re-arming with `GC`
would reset those settings, and motion during the rebuild can fire an
unguarded trigger whose dump is lost, leaving the board idle with nothing to
re-arm it. Serial input is never cleared once the board is live: a dump can
start immediately, and output before its capture marker is skipped. A serial
write timeout keeps the capture and reports a retryable re-arm failure
instead of discarding the shot.
8. If the tail of a dump arrives without its start (its head was discarded by
an unrelated command), treat the board as idle and re-arm it with `PA`. The
session log records these as `orphaned_dump` trigger rejections.

The implementation is intentionally limited to the OPS243 trigger path; the
experimental analysis and UI work remain outside this focused change.

## Defaults and command

| Setting | Hardware-mode default |
|---|---:|
| Trigger threshold | 25 mph |
| Trigger magnitude | 25 (`SM25`) |
| Pre-trigger split | 6 segments (`S#6`) |
| Sample rate | 30 ksps (required) |
| Minimum accepted outbound ball speed | 35 mph |

Run the mode directly with:

```bash
openflight-server \
--trigger hardware \
--trigger-threshold 25 \
--trigger-magnitude 25 \
--pre-trigger-segments 6 \
--sample-rate 30
```

The kiosk script forwards the same settings:

```bash
scripts/start-kiosk.sh --trigger hardware
```

Use `--trigger-threshold`, `--trigger-magnitude`, and `--pre-trigger-segments` to override the hardware path. `S#6` applies only to this new mode. The established sound path continues to use `--sound-pre-trigger` and keeps its existing default and behavior:

```bash
scripts/start-kiosk.sh --trigger sound --sound-pre-trigger 16
```

The internal trigger does not depend on the SEN-14262 sound edge. Existing sound-trigger wiring can remain installed, but selecting `hardware` is the software choice that activates the OPS243 internal trigger.

## Raspberry Pi retest checklist

Before treating a change to this mode as ready for merge, run the hardware path
on the target Pi and record the observations in the PR body:

```bash
scripts/start-kiosk.sh --trigger hardware
```

- Representative ball strikes: how many triggered, parsed, and re-armed.
- Practice swings without a ball, and ambient motion with no swing, for false
triggers.
- Rapid repeated motion past the radar for 15–20 seconds. The board must keep
re-arming; a blue LED that stays lit means it is idle and was never re-armed.

Also run the unchanged sound path with the same representative shots:

```bash
scripts/start-kiosk.sh --trigger sound
```
8 changes: 8 additions & 0 deletions docs/how-it-works/rolling-buffer.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ The runtime then starts in the persisted `GC` rolling-buffer mode without
re-entering it. See [Sound trigger wiring](../build/sound-trigger.md) for the
recommended direct hardware trigger.

The OPS243 internal speed trigger is available as a separate, opt-in capture
strategy. It requires OPS243-A firmware v1.3.2 or newer in the 1.3 release
train, uses the tested 30 ksps configuration, and defaults to `S#6`; see
the [Internal Hardware Trigger guide](../hardware-trigger.md) for its command
ordering, re-arm behavior, and Raspberry Pi validation checklist. The sound
path and its defaults remain unchanged.

## Current defaults

| Setting | Value |
Expand Down Expand Up @@ -70,4 +77,5 @@ in the session JSONL logs described in the

- [Raspberry Pi Setup](../setup/raspberry-pi.md)
- [Sound Trigger Wiring](../build/sound-trigger.md)
- [OPS243 Internal Hardware Trigger](../hardware-trigger.md)
- [Spin Replay and Diagnostics](../development/spin-replay.md)
5 changes: 4 additions & 1 deletion docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ How a capture is initiated and framed.

| Flag | Type / default | Description |
| --- | --- | --- |
| `--trigger` | choices: `sound`, `speed`; default `sound` | Trigger strategy |
| `--trigger` | choices: `sound`, `speed`, `hardware`; default `sound` | Trigger strategy |
| `--trigger-threshold`, `--speed-trigger-threshold`, `--trigger-speed` | float | Internal or host speed-trigger threshold in mph; hardware default `25` |
| `--trigger-magnitude` | int; default `25` | OPS243 internal trigger magnitude (`SMn`) |
| `--pre-trigger-segments` | int; default `6` | Hardware-trigger pre-trigger segments (`S#n`) |
| `--sound-pre-trigger` | int; default `16` | Pre-trigger segments S#n, 0-32 (default: 16 = 50/50 split, each segment ~4.27ms at 30ksps) |

## IWR6843 angle radar
Expand Down
Loading
Loading