Skip to content
Open
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
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ See the **[Parts List](docs/PARTS.md)** for everything you need with purchase li

### 2. Wire it up

Follow the **[Sound Trigger Wiring Guide](docs/sound-trigger-wiring.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/sound-trigger-wiring.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.1; 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 Expand Up @@ -96,6 +96,9 @@ details and troubleshooting.
# Default: rolling buffer mode with sound trigger
scripts/start-kiosk.sh

# Opt-in OPS243 internal hardware trigger (30 ksps, S#6)
scripts/start-kiosk.sh --trigger hardware

# With the IWR6843 angle radar (OPS243 on the Pi GPIO UART).
# Geometry values are examples — measure your own; see the operator guide.
scripts/start-kiosk.sh --iwr6843 \
Expand Down Expand Up @@ -305,6 +308,7 @@ uv run pytest tests/ -v

- **[Parts List](docs/PARTS.md)** — What to buy
- **[Sound Trigger Wiring](docs/sound-trigger-wiring.md)** — How to wire the sound trigger
- **[Internal Hardware Trigger](docs/hardware-trigger.md)** — OPS243 internal trigger methodology and Pi retest checklist
- **[Raspberry Pi Setup](docs/raspberry-pi-setup.md)** — Full setup guide
- **[Battery Monitoring](docs/battery/README.md)** — Provider architecture, UI states, and shared Pi support
- **[Geekworm X1202/X1206 Operator Guide](docs/battery/geekworm.md)** — Batteries, Pi setup, native telemetry, and warnings
Expand Down
7 changes: 7 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- **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
`GC` 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.1. 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
75 changes: 75 additions & 0 deletions docs/hardware-trigger.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# 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.1**, the release used for
the validation sessions. The driver queries `?V` before sending the internal
trigger setup commands and fails fast if the reported version is different 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. Arm the outbound internal speed threshold with `ST-n` (25 mph by default;
outbound radar velocity is negative).
3. Enter rolling-buffer mode with `GC`.
4. Restore the detector settings that `GC` resets: 30 ksps, MPH units, 128 samples, `X=2`, outbound filtering, JSON plus magnitude output, and the configured `S#n` split.
5. Restore `ST-n` and the magnitude gate `SMn`, then 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 `GC`, restore the cached settings, and wait for the buffer to fill again. A serial write timeout keeps the capture and reports a retryable re-arm failure instead of discarding the shot.

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 PR as ready for merge, run the hardware path on the target Pi and record the observations in the PR body:

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

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

I was unable to regression test the sound trigger.
10 changes: 9 additions & 1 deletion docs/rolling_buffer_spin_detection.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ estimation from that capture remains experimental.
4. An overlapping timeline separates the club, impact, and ball regions.
5. An ungated multitaper estimator records an experimental spin candidate.

The normal kiosk command uses this pipeline:
The normal kiosk command uses this sound-trigger pipeline:

```bash
scripts/start-kiosk.sh
Expand All @@ -32,6 +32,13 @@ The runtime then starts in the persisted `GC` rolling-buffer mode without
re-entering it. See [Sound Trigger Wiring](sound-trigger-wiring.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.1, 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 @@ -75,4 +82,5 @@ in the session JSONL logs described in the

- [Raspberry Pi Setup](raspberry-pi-setup.md)
- [Sound Trigger Wiring](sound-trigger-wiring.md)
- [OPS243 Internal Hardware Trigger](hardware-trigger.md)
- [Spin Replay and Diagnostics](spin-dechirp-replay.md)
25 changes: 24 additions & 1 deletion scripts/start-kiosk.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ DRY_RUN=false
# Rolling buffer mode is the only mode (streaming mode removed)
TRIGGER="sound" # Default: hardware sound trigger (SEN-14262 → HOST_INT)
SOUND_PRE_TRIGGER=""
TRIGGER_THRESHOLD=25
TRIGGER_THRESHOLD_SET=false
TRIGGER_MAGNITUDE=25
PRE_TRIGGER_SEGMENTS=6
BUFFER_SPLIT=""
IWR6843=false
IWR6843_PORT=""
Expand Down Expand Up @@ -139,6 +143,19 @@ while [[ $# -gt 0 ]]; do
TRIGGER="$2"
shift 2
;;
--trigger-threshold|--speed-trigger-threshold)
TRIGGER_THRESHOLD="$2"
TRIGGER_THRESHOLD_SET=true
shift 2
;;
--trigger-magnitude)
TRIGGER_MAGNITUDE="$2"
shift 2
;;
--pre-trigger-segments)
PRE_TRIGGER_SEGMENTS="$2"
shift 2
;;
--sound-pre-trigger)
SOUND_PRE_TRIGGER="$2"
shift 2
Expand Down Expand Up @@ -601,7 +618,13 @@ if [ -n "$TRIGGER" ] && [ "$SWING_SPEED" != true ]; then
SERVER_CMD="$SERVER_CMD --trigger $TRIGGER"
fi

if [ -n "$SOUND_PRE_TRIGGER" ] && [ "$SWING_SPEED" != true ]; then
if [ "$TRIGGER" = "hardware" ] && [ "$SWING_SPEED" != true ]; then
SERVER_CMD="$SERVER_CMD --trigger-threshold $TRIGGER_THRESHOLD"
SERVER_CMD="$SERVER_CMD --trigger-magnitude $TRIGGER_MAGNITUDE"
SERVER_CMD="$SERVER_CMD --pre-trigger-segments $PRE_TRIGGER_SEGMENTS"
elif [ "$TRIGGER" = "speed" ] && [ "$TRIGGER_THRESHOLD_SET" = true ] && [ "$SWING_SPEED" != true ]; then
SERVER_CMD="$SERVER_CMD --trigger-threshold $TRIGGER_THRESHOLD"
elif [ -n "$SOUND_PRE_TRIGGER" ] && [ "$SWING_SPEED" != true ]; then
SERVER_CMD="$SERVER_CMD --sound-pre-trigger $SOUND_PRE_TRIGGER"
fi

Expand Down
Loading