[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-95021":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":8,"htmlUrl":9,"language":10,"languages":8,"totalLinesOfCode":8,"stars":11,"forks":12,"watchers":13,"openIssues":14,"contributorsCount":8,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":16,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":17,"rankGlobal":8,"rankLanguage":8,"license":8,"archived":18,"fork":18,"defaultBranch":19,"hasWiki":18,"hasPages":18,"topics":20,"createdAt":8,"pushedAt":8,"updatedAt":25,"readmeContent":26,"aiSummary":27,"trendingCount":15,"starSnapshotCount":15,"syncStatus":28,"lastSyncTime":29,"discoverSource":30},95021,"openflight","jewbetcha\u002Fopenflight","jewbetcha",null,"https:\u002F\u002Fgithub.com\u002Fjewbetcha\u002Fopenflight","Python",912,103,41,14,0,15,53.05,false,"main",[21,22,23,24],"diy","golf","radar","launchmonitor","2026-08-24 04:01:23","\u003Cp align=\"center\">\n\u003Cimg src=\".\u002Fui\u002Fpublic\u002Fopenflightlogo.svg\">\n  DIY Golf Launch Monitor using the OPS243-A Doppler Radar.\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002Fw8hhG4WVMN\">\n    \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FDiscord-join%20the%20community-5865F2?style=for-the-badge&logo=discord&logoColor=white\" alt=\"Join the OpenFlight Discord\" \u002F>\n  \u003C\u002Fa>\n  \u003Ca href=\"https:\u002F\u002Fbuymeacoffee.com\u002Fcolemangolfs\">\n    \u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FBuy%20Me%20a%20Coffee-support-yellow?style=for-the-badge&logo=buy-me-a-coffee&logoColor=white\" alt=\"Buy Me a Coffee\" \u002F>\n  \u003C\u002Fa>\n\u003C\u002Fp>\n\n> [!WARNING]\n> **This project is in active development.** Features may be incomplete, unstable, or change without notice. Contributions and bug reports are welcome!\n\n## Overview\n\nOpenFlight is an open-source golf launch monitor built around the OPS243-A\nDoppler radar, with an optional TI IWR6843 angle radar.\n\n### What It Measures\n\n- **Ball Speed**: 15-200 mph range with ±0.5% accuracy (OPS243-A)\n- **Club Speed**: Detected from pre-impact readings (OPS243-A)\n- **Smash Factor**: Ball speed \u002F club speed ratio\n- **Launch Angle**: Measured by the IWR6843; estimated when no trusted radar angle is available\n- **Club Path**: Experimental pre-impact estimate from the IWR6843\n- **Spin Rate**: Experimental candidate from rolling-buffer I\u002FQ; not used for carry by default\n- **Carry Distance**: Ballistic model with explicit fallbacks for missing measurements\n\n### Hardware at a Glance\n\n| Component | What it does | ~Cost |\n|-----------|-------------|-------|\n| OPS243-A Radar | Ball speed, club speed, experimental spin | $249 |\n| Raspberry Pi 5 | Runs everything | $130 |\n| 7\" Touchscreen | Shows shot data | $46 |\n| SparkFun SEN-14262 | Impact sound trigger for shot capture | $18 |\n| Power supply + accessories | | $27 |\n| **Subtotal, no angle radar** | | **~$400** |\n| TI IWR6843LEVM + cable | Launch angle, experimental club path | $156 |\n| **Total with angle radar** | | **~$556** |\n| K-LD7 (×2) + FTDI adapters | Launch angle + club path (**deprecated**) | $140 |\n\nWithout an angle radar you still get ball speed, club speed, smash factor,\nexperimental spin, and estimated carry. The angle radar adds measured launch\nangle and experimental club path.\n\n> **⚠️ The K-LD7 angle radars are deprecated.** The supported angle radar is now the **TI IWR6843**. Don't buy K-LD7s for a new build; their software support remains for existing builds only. See the [full parts list](docs\u002FPARTS.md) for details and links.\n\n> **The IWR6843 needs custom firmware** — the stock TI demo doesn't expose the raw radar cube OpenFlight needs. A validated prebuilt image ships in `firmware\u002Freleases\u002F`, so flashing it doesn't require the TI toolchain. See the [IWR6843 Operator Guide](docs\u002Fiwr6843\u002FREADME.md).\n\n## Getting Started\n\n### 1. Get the parts\n\nSee the **[Parts List](docs\u002FPARTS.md)** for everything you need with purchase links.\n\n### 2. Wire it up\n\nFollow the **[Sound Trigger Wiring Guide](docs\u002Fsound-trigger-wiring.md)** to connect the SEN-14262 to the OPS243-A. The (deprecated) K-LD7 modules connect via USB — no wiring needed.\n\n**Adding the IWR6843 angle radar?** The Pi cannot power both radars over USB, so\nthe OPS243 moves to the Pi's GPIO UART header while the TI board takes the USB\nport. Do it in this order, validating each step before the next — doing both at\nonce makes any failure ambiguous:\n\n1. **[Move the OPS243 from USB to the Pi GPIO UART](docs\u002Fops243-uart-migration.md)** — rewire and confirm the OPS still triggers on its own.\n2. **[IWR6843 Operator Guide](docs\u002Fiwr6843\u002FREADME.md)** — wire, flash the firmware, mount, aim, and measure geometry.\n\nIf your OPS243-A has **WiFi**, you cannot use the GPIO UART — its WiFi module\nalready drives the radar's UART receive line. Use a separately powered USB hub\ninstead; see the operator guide's Option B.\n\n### 3. Set up the Pi\n\nFlash Raspberry Pi OS (64-bit), plug in the radars, then run the interactive setup:\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fjewbetcha\u002Fopenflight.git\ncd openflight\n.\u002Fscripts\u002Fsetup\u002Fsetup.sh\n```\n\nThe script installs everything and walks you through the one-time hardware\nconfiguration (radar flash setup, legacy K-LD7 device naming, auto-start, and\noptional cloud sync) with prompts. It's safe to re-run any time.\nSee the **[Raspberry Pi Setup Guide](docs\u002Fraspberry-pi-setup.md)** for\ndetails and troubleshooting.\n\n### 4. Hit balls\n\n```bash\n# Default: rolling buffer mode with sound trigger\nscripts\u002Fstart-kiosk.sh\n\n# With the IWR6843 angle radar (OPS243 on the Pi GPIO UART).\n# Geometry values are examples — measure your own; see the operator guide.\nscripts\u002Fstart-kiosk.sh --iwr6843 \\\n  --ops-port \u002Fdev\u002FttyAMA0 \\\n  --iwr6843-tee-m 1.372 --iwr6843-net-m 4.064 \\\n  --iwr6843-tilt-deg 5.5 --iwr6843-radar-height-m 0.229 \\\n  --iwr6843-ball-height-m 0.021\n\n# With legacy K-LD7 hardware (measure the mount tilt first)\nscripts\u002Fstart-kiosk.sh --kld7 --kld7-mount-tilt \u003Cmeasured-degrees>\n\n# Swing speed training (air swings \u002F speed sticks, no sound trigger)\nscripts\u002Fstart-kiosk.sh --swing-speed\n\n# Development mode (no hardware)\nscripts\u002Fstart-kiosk.sh --mock\n\n# With Geekworm X1202\u002FX1206 battery monitoring\nscripts\u002Fstart-kiosk.sh --battery geekworm\n```\n\nThe IWR6843 example values are not universal. Measure the geometry from the\nantenna center and follow the [operator guide](docs\u002Fiwr6843\u002FREADME.md#measure-the-geometry);\nwrong values bias the result instead of producing an obvious startup error.\n\nThen open http:\u002F\u002Flocalhost:8080 or use the touchscreen.\n\n### 5. Sync to the cloud (optional)\n\nOpenFlight can push your sessions to the **FlightWeb** cloud so you can review\nshots from any device. It's opt-in, and **raw radar data never leaves your\nPi** — only shot results and session metadata are uploaded (verify with\n`openflight-cloud push --dry-run`).\n\n`setup.sh` offers to enable this and link your Pi. To do it by hand:\n\n```bash\nopenflight-cloud link       # pair this Pi (enter a short code in your browser)\nopenflight-cloud status     # linked? queued? parked?\n```\n\nOnce linked, sessions sync automatically (on session end and via a ~10-minute\ntimer that heals wifi outages). See the **[Cloud Sync Guide](docs\u002Fcloud-sync.md)**\nfor details.\n\n### TV Display Mode\n\nOpenFlight also serves a fullscreen-friendly browser display for tablets, TV browsers, or a Chrome tab cast to Chromecast.\n\n1. Start OpenFlight as usual with `scripts\u002Fstart-kiosk.sh`.\n2. Find the OpenFlight host on your LAN — its hostname (see below) or its IP address.\n3. Open `http:\u002F\u002F\u003Copenflight-host>:8080\u002Fdisplay` from another laptop, tablet, or TV browser.\n4. For Chromecast, open the display page in Chrome and use Chrome's built-in **Cast** feature to cast the tab.\n\n> **Prefer the hostname over the IP.** Raspberry Pi OS broadcasts its hostname over\n> mDNS (Avahi), so `http:\u002F\u002Fopenflight.local:8080\u002Fdisplay` keeps working even when the\n> Pi's DHCP lease expires and it comes back on a different address — a bookmarked IP\n> breaks unless you reserved it on your router. Set the name in Raspberry Pi Imager's\n> **Hostname** field when you flash the card; the default is `raspberrypi`, i.e.\n> `raspberrypi.local`. The viewing device has to support mDNS — macOS, iOS, Windows 10+\n> and most Linux desktops do, but some smart-TV browsers don't, so use the IP there.\n\nThis is browser\u002Ftab casting only. OpenFlight does not include native Cast SDK support yet.\n\n### Swing Speed Training\n\nFor air swings and speed-stick training, OpenFlight can use the OPS243-A fast\nspeed stream directly instead of waiting for impact audio. Start it with\n`scripts\u002Fstart-kiosk.sh --swing-speed`; the server emits `swing_speed` events\nwith peak club speed, rep duration, reading count, and session stats. See the\n**[Swing Speed Training Guide](docs\u002Fswing-speed-training.md)** for setup and\ntuning options.\n\n## How It Works\n\n### System Architecture\n\n```\nSEN-14262 ── trigger ──► OPS243-A ── I\u002FQ ──► RollingBufferMonitor\n                                                   │\nIWR6843 (optional) ── angle + club path ───────────┤\n                                                   ▼\n                                           Flask + WebSocket ──► React UI\n```\n\n1. **Sound trigger fires** — SEN-14262 detects club impact, triggers OPS243-A HOST_INT\n2. **OPS243-A dumps buffer** — I\u002FQ data is analyzed for ball speed, club speed, and an experimental spin candidate\n3. **IWR6843 correlates** — The optional angle radar uses the same impact edge for launch angle and experimental club path\n4. **Carry computed** — The ballistic model uses trusted measurements and fills missing inputs with documented fallbacks\n5. **UI updates** — Shot data emitted via WebSocket to the React frontend\n\n### Doppler Radar Basics\n\nThe OPS243-A transmits a 24 GHz signal. When it bounces off a moving object (the golf ball), the frequency shifts proportionally to the object's speed — this is the Doppler effect. At 24.125 GHz, each 1 mph of speed creates a ~71.7 Hz Doppler shift.\n\n### Positioning\n\nPlace the OPS243-A **3-5 feet behind the tee**, pointing down the target line:\n\n```\n                Ball Flight Direction\n                ======================>\n\n[Tee]  ←--- 3-5 ft ---→  [OPS243-A]\n```\n\nThe IWR6843 has stricter mounting and measurement requirements; use the\n[operator guide](docs\u002Fiwr6843\u002FREADME.md#mount-and-aim-the-radar) rather than assuming it\nshares the OPS243 position.\n\n## Configuration\n\n### Radar Settings for Golf\n\n| Setting        | Value                  | Why                                          |\n| -------------- | ---------------------- | -------------------------------------------- |\n| Mode           | Rolling buffer         | Raw I\u002FQ capture for precise speeds and experimental spin |\n| Sample Rate    | 30 ksps                | Supports up to ~208 mph ball speed           |\n| Capture        | 4096 I\u002FQ samples       | ~136 ms around impact                        |\n| Trigger        | Sound (SEN-14262)      | ~10 µs hardware latency via HOST_INT         |\n| Min Ball Speed | 15 mph                 | Minimum valid ball speed threshold (35 mph for speed-triggered mode) |\n| DC Mask        | ~15 mph exclusion zone | Reject body movement and environmental noise |\n\nThese are applied automatically — the one-time flash configuration is handled\nby the setup script.\n\n### Python API\n\n```python\nfrom openflight.rolling_buffer import RollingBufferMonitor\n\nmonitor = RollingBufferMonitor()   # auto-detects the OPS243-A\nmonitor.connect()\nmonitor.start()\n\nprint(\"Swing when ready...\")\nshot = monitor.wait_for_shot(timeout=60)\nif shot:\n    print(f\"Ball Speed: {shot.ball_speed_mph:.1f} mph\")\n    print(f\"Est. Carry: {shot.estimated_carry_yards:.0f} yards\")\n\nmonitor.stop()\nmonitor.disconnect()\n```\n\n## Limitations\n\n- **Cosine error**: If ball doesn't travel directly toward\u002Faway from radar, measured speed will be slightly lower than actual\n- **Spin detection**: The live multitaper value is experimental and is not used for carry by default. Short indoor flight windows and multipath make individual readings unreliable; see [Rolling Buffer and Spin Detection](docs\u002Frolling_buffer_spin_detection.md).\n- **K-LD7 speed aliasing** (deprecated hardware): The K-LD7 max speed is 62 mph, so it's used only for angle\u002Fdistance, not speed\n\n## Hardware Diagnostic\n\nTo verify the OPS243, sound trigger, and legacy K-LD7 path:\n\n```bash\nuv run python scripts\u002Fhardware-test\u002Fdiagnose.py\n```\n\nThe diagnostic checks the OPS243 transport, rolling-buffer persistence,\nsoftware and hardware triggers, and any connected K-LD7 radars. IWR6843 builds\nuse the [operator guide's first-capture checks](docs\u002Fiwr6843\u002FREADME.md#verify-the-first-capture).\n\nMissing optional hardware (like the horizontal K-LD7) is reported as a skip rather than a failure. Pass `--require-all` to fail on skips, or `--no-interactive` to skip the sound-trigger prompt in unattended runs.\n\n## Project Structure\n\n```\nopenflight\u002F\n├── src\u002Fopenflight\u002F\n│   ├── ops243.py              # OPS243-A radar driver\n│   ├── launch_monitor.py      # Shot detection & club\u002Fball separation\n│   ├── server.py              # Flask server and shot orchestration\n│   ├── session_logger.py      # JSONL session logging\n│   ├── rolling_buffer\u002F        # OPS capture and signal processing\n│   ├── iwr6843\u002F               # Current angle radar\n│   ├── kld7\u002F                  # Legacy angle radar\n│   ├── sim\u002F                   # Simulator connector framework\n│   └── cloud\u002F                 # FlightWeb uploader\n├── ui\u002F                        # React frontend\n├── scripts\u002F                   # Utility & setup scripts\n├── docs\u002F                      # Documentation\n└── pyproject.toml\n```\n\n## Community\n\nJoin the **[OpenFlight Discord](https:\u002F\u002Fdiscord.gg\u002Fw8hhG4WVMN)** to ask build\nquestions, share results, and follow development.\n\n## Contributing\n\nContributions welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\nAreas of interest:\n\n- **Better spin detection**: A dechirped Doppler-sideband estimator is in development (`scripts\u002Fanalysis\u002Freplay_spin_dechirp.py`) — help validating it against launch-monitor truth data is especially welcome\n- **Mobile app**: Bluetooth connection to phone\n\n### Running Tests\n\n```bash\nuv run pytest tests\u002F -v\n```\n\n## Documentation\n\n- **[Parts List](docs\u002FPARTS.md)** — What to buy\n- **[Sound Trigger Wiring](docs\u002Fsound-trigger-wiring.md)** — How to wire the sound trigger\n- **[Raspberry Pi Setup](docs\u002Fraspberry-pi-setup.md)** — Full setup guide\n- **[Battery Monitoring](docs\u002Fbattery\u002FREADME.md)** — Provider architecture, UI states, and shared Pi support\n- **[Geekworm X1202\u002FX1206 Operator Guide](docs\u002Fbattery\u002Fgeekworm.md)** — Batteries, Pi setup, native telemetry, and warnings\n- **[IWR6843 Operator Guide](docs\u002Fiwr6843\u002FREADME.md)** — Wire, flash, mount, aim, and calibrate the angle radar\n- **[LIS3DH Inclinometer Setup](docs\u002Finclinometer\u002FREADME.md)**: Add enclosure-level compensation to IWR6843 tilt\n- **[OPS243 USB → GPIO UART Migration](docs\u002Fops243-uart-migration.md)** — Required before adding the IWR6843\n- **[IWR6843 Firmware Developer Guide](firmware\u002FREADME.md)** — Build the firmware from source (not needed to flash the prebuilt image)\n- **[Simulator Connectors](docs\u002Fsimulator\u002FREADME.md)** — Stream shots to GSPro, OpenGolfSim, and others\n- **[Cloud Sync](docs\u002Fcloud-sync.md)** — Push filtered sessions to FlightWeb\n- **[Rolling Buffer & Spin Detection](docs\u002Frolling_buffer_spin_detection.md)** — Production capture and experimental spin details\n- **[Dechirped-Sideband Spin Replay](docs\u002Fspin-dechirp-replay.md)** — Next-gen spin estimator test bench\n- **[Camera and YOLO Experiments](docs\u002Fyolo-performance-tuning.md)** — Optional, non-production vision work\n- **[Legacy K-LD7 Setup](docs\u002Fkld7.md)** — Existing K-LD7 builds only\n- **[K-LD7 Ball Detection Theory](docs\u002Fkld7-ball-detection-theory.md)** — How angle detection works (deprecated hardware)\n- **[K-LD7 Session Review](docs\u002Fkld7-session-review.md)** — Offline review workflow for session JSONL files (deprecated hardware)\n- **[Observability & Log Shipping](docs\u002Fobservability.md)** — Ship logs to Grafana Cloud\n- **[Contributing Guide](CONTRIBUTING.md)** — How to contribute\n- **[Changelog](docs\u002FCHANGELOG.md)** — Version history\n\n## License\n\nGNU Affero General Public License v3.0 or later (AGPL-3.0-or-later) - see LICENSE file.\n\n## Acknowledgments\n\n- [OmniPreSense](https:\u002F\u002Fomnipresense.com\u002F) for the OPS243-A radar and documentation\n- The golf hacker community for inspiration\n","OpenFlight 是一个基于 Doppler 雷达的开源 DIY 高尔夫发射监测器（Launch Monitor），用于实时测量球速、杆速、撞击系数、起飞角、杆身路径及预测飞行距离。核心硬件采用 OPS243-A 多普勒雷达（主测速）与可选 TI IWR6843 毫米波雷达（提供角度数据），运行于树莓派 5，支持触控界面与声触发捕获。系统采用自研信号处理与弹道建模，兼顾精度与低成本（约 400–556 美元）。适用于家庭练习场、高尔夫爱好者自主搭建高性价比训练设备，或嵌入式雷达应用开发者进行雷达数据采集与运动分析原型开发。",2,"2026-08-20 02:30:05","trending"]