Initial archive: ping-pong-ping demo (USBL DS-TWR + SS-TWR + passive OWR)
Self-contained HTML demo with two interactive canvas animations: - Animation 1: DS-TWR principle (mobile-mobile, both sides know distance) - Animation 2: USV master + N AUVs, SS-TWR active + passive OWR for non-target listeners Realistic AUV operating params (1-2 kt cruise, 5-700 m range). Includes README documenting the protocol, design decisions taken during the 2026-04-27 design conversation between Flag and Poulpe, deployment routing (Gateway Caddy + Core Caddy path-based), and TODO for future iterations. Live: https://laboratoire.freeboxos.fr/ping-pong-ping/
This commit is contained in:
104
README.md
Normal file
104
README.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# Ping-Pong-Ping
|
||||
|
||||
Interactive HTML demo + reference notes for **acoustic distance ranging** between USBL nodes (USV master ↔ AUV slaves). Built collaboratively between Flag and Poulpe on 2026-04-27 from a single design conversation.
|
||||
|
||||
**Live demo** : https://laboratoire.freeboxos.fr/ping-pong-ping/
|
||||
|
||||
---
|
||||
|
||||
## What this archives
|
||||
|
||||
A self-contained `index.html` (no framework, no external assets) that explains and animates two acoustic ranging schemes used in underwater positioning:
|
||||
|
||||
1. **DS-TWR** (Double-Sided Two-Way Ranging) — symmetric ping/pong/ping where **both** sides learn the distance without clock synchronization. Used when the two nodes are peers (mobile-mobile, swarm coopératif).
|
||||
2. **SS-TWR + passive OWR** (Single-Sided Two-Way Ranging + One-Way Ranging by passive listeners) — asymmetric scheme used when **only the master needs the distance**, with the bonus that any other AUV in acoustic range can compute its own distance to the master from the same single ping.
|
||||
|
||||
Both animations run continuously, with realistic AUV operating parameters (1–2 kt cruise speed, 5–700 m range, c = 1500 m/s).
|
||||
|
||||
## The protocol — short version
|
||||
|
||||
### DS-TWR (animation 1)
|
||||
```
|
||||
A → B : ping1
|
||||
B → A : pong (B encodes turnaround_B in the pong frame)
|
||||
A → B : ping2 (A encodes turnaround_A in the ping2 frame)
|
||||
|
||||
A side : TOF = (round_trip_A − turnaround_B) / 2
|
||||
B side : TOF = (round_trip_B − turnaround_A) / 2
|
||||
distance = TOF · c
|
||||
```
|
||||
No clock sync required. Each side measures only local deltas.
|
||||
|
||||
### SS-TWR + passive OWR (animation 2)
|
||||
```
|
||||
USV → AUVi (addressed) : ping (frame carries target ID 0xAi + send timestamp)
|
||||
|
||||
AUVi receives → match ID → responds:
|
||||
AUVi → USV : pong (encodes turnaround_AUVi)
|
||||
|
||||
All other AUVj receive the same ping (medium is shared):
|
||||
AUVj computes distance passively : (T_recv_local − T_send_USV) · c
|
||||
|
||||
USV side (active TWR for AUVi) : TOF = (round_trip − turnaround_AUVi) / 2
|
||||
AUVj side (passive OWR) : TOF = T_recv_local − T_send_USV
|
||||
```
|
||||
**One ping → N range fixes.** The medium remains free between cycles.
|
||||
|
||||
### Required infrastructure for OWR
|
||||
The passive AUVs must share a **time reference** with the USV. Two practical options:
|
||||
|
||||
- **GPS-disciplined oscillators** synchronized at the surface before mission launch, with bounded drift (typically < 1 µs over a few hours for OCXO-grade clocks).
|
||||
- **Send-timestamp embedded in the ping frame** : the USV writes its clock value `T_send` in the ping payload, every receiver reads it and compares to its own `T_recv`. Subject to the same clock-drift caveat.
|
||||
|
||||
DS-TWR (animation 1) does **not** need this — that's its main feature. SS-TWR + passive OWR (animation 2) trades the synchronization requirement for much faster scan rates.
|
||||
|
||||
## Design decisions taken in the conversation
|
||||
|
||||
These reflect the iterative refinement during the conversation, summarized so the rationale isn't lost:
|
||||
|
||||
| Decision | Why |
|
||||
|---|---|
|
||||
| **Two animations, not three** | Initially the multi-AUV section had a Broadcast (BC-DS-TWR) mode with N pongs in staggered slots. Flag judged it "relou" — addressed sequential is conceptually simpler, no slot collisions, and combined with passive OWR it's faster anyway. Dropped. |
|
||||
| **SS-TWR (not DS-TWR) for multi-AUV** | In the iUSBL setup (USV tracks AUVs), only the USV needs the distance. The third leg (ping2) is dead weight. Switched the multi-AUV animation to SS-TWR, kept DS-TWR for the principle demo where the symmetry matters. |
|
||||
| **Passive OWR for non-target AUVs** | Originally non-target AUVs were drawn as "✗ ignore". Flag pointed out they can use the ping passively. Each ping now produces N range fixes (1 active + N−1 passive). |
|
||||
| **Realistic AUV speeds (1–2 kt) and ranges (5–700 m)** | First version had AUVs moving at ~140 kt over 5 km — physically impossible. Recalibrated to typical coastal AUV ops. |
|
||||
| **No DS-TWR-vs-SS-TWR speedup table** | Removed cycle-time comparison readouts to avoid clutter. The "fluidity" is visible directly. |
|
||||
| **No ID match alarm** | Replaced "✗ ignore" red alert with "📡 passive OWR" cyan badge, since non-target AUVs are useful, not ignored. |
|
||||
|
||||
## File structure
|
||||
|
||||
```
|
||||
ping-pong-ping/
|
||||
├── index.html # self-contained demo (HTML + CSS + JS, no externals)
|
||||
├── README.md # this file
|
||||
└── deploy.sh # one-shot push to Core Caddy webroot
|
||||
```
|
||||
|
||||
`index.html` contains two `<canvas>` animations driven by independent IIFEs, prose sections explaining each scheme, and worked numerical examples.
|
||||
|
||||
## Deploy
|
||||
|
||||
The page is served from Core (`192.168.0.82`) via Caddy on the path `laboratoire.freeboxos.fr/ping-pong-ping/`.
|
||||
|
||||
Routing layers :
|
||||
|
||||
- **Core Caddyfile** (`/docker/caddy/Caddyfile` on `.82`) : `handle /ping-pong-ping { redir /ping-pong-ping/ 307 }` + `handle_path /ping-pong-ping/* { root * /srv/www/ping-pong-ping; file_server }`
|
||||
- **Gateway Caddyfile** (`/etc/caddy/Caddyfile` on LXC 103, `.128`) : `handle /ping-pong-ping/* { reverse_proxy 192.168.0.82:80 }` — note `handle` (not `handle_path`) to **preserve the prefix** when forwarding to Core's path-based block. Otherwise Core sees `/` and falls into the catchall.
|
||||
|
||||
To re-deploy after an edit :
|
||||
|
||||
```bash
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
## TODO / future work
|
||||
|
||||
- [ ] Add a 3rd animation showing **2D positioning** — currently distance only is animated. AUVs equipped with USBL micro-arrays could also compute their bearing-to-USV; the page mentions this in passing but doesn't visualize it.
|
||||
- [ ] Show **clock drift visualization** in the OWR animation (the synchronization assumption is the load-bearing piece — worth illustrating).
|
||||
- [ ] **Compare with the real Kogger USBL frames** decoded in `floppyrj45/cosma-nav/extract/decode_kogger.py` (8 KB, K-Link `BB 55` protocol reverse-engineered). The 2026-04-08 La Ciotat dataset contained only setup/config frames, no acoustic fixes — when a dataset with real position responses lands, plug the numbers into this demo for end-to-end validation.
|
||||
- [ ] Add a **noise model** (USBL inherent precision is 0.5–2 % of slant range) so the plot dots scatter realistically around the truth curves.
|
||||
- [ ] **Multipath / NLOS** scenario : show what happens when an AUV's pong takes a bounced path. Worth its own panel.
|
||||
|
||||
## Credits
|
||||
|
||||
Conversation between Flag (concept, design feedback, iterative steering) and Poulpe (implementation, deployment, prose) on 2026-04-27 in Discord `#ping-pong-ping`. Archived for future reference and iteration.
|
||||
Reference in New Issue
Block a user