Add a 'Implémentation Cosma — antenne Kogger' section to the page that ties the
abstract protocol (DS-TWR / SS-TWR / addressed) shown in the animations to the
concrete hardware driver used in the Cosma project (cosma-tech/kogger_acoustic
Antenna), and to the new wrapper poulpe/kogger-transpondeur-continu that turns
a Kogger antenna into a permanent slave transponder in a single start() call.
Add a 'Sources' section listing all four related repos (this page, wrapper,
upstream driver location, log decoder).
Update README similarly with a 'Hardware companion repo' section so the
ping-pong-ping repo no longer reads as standalone — it's the protocol
explainer, kogger-transpondeur-continu is the hardware glue.
Reported by Flag 2026-04-27 ('as-tu mis un lien...').
113 lines
7.2 KiB
Markdown
113 lines
7.2 KiB
Markdown
# 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
|
||
```
|
||
|
||
## Hardware companion repo
|
||
|
||
For the Kogger USBL hardware described in the page :
|
||
|
||
- **Wrapper Python "transpondeur continu"** : `poulpe/kogger-transpondeur-continu` on Gitea — high-level wrapper around the upstream `cosma-tech/kogger_acousticAntenna` driver that puts a Kogger antenna in permanent slave-transponder mode in a single `start()` call. Composes address filter + echo filter + TDMA sync slot + permanent response window + Python callbacks for received pings. No modification of the upstream driver.
|
||
- **Driver upstream** : `cosma-tech/kogger_acousticAntenna` on GitHub (private). Active checkout on Pi 184 `cosma-auv2` at `/home/pi/dev/swarm-vehicle/src/drivers/kogger_acousticAntenna/`. Snapshot included read-only in the wrapper repo for reference.
|
||
- **Log decoder** (post-acquisition USBL frame parsing for analysis) : `floppyrj45/cosma-nav/extract/decode_kogger.py` on Gitea.
|
||
|
||
## 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.
|