Two fixes for the visual confusion of 'A appears to send two pings back to back': 1. Add 600 ms (sim) guard interval between cycle N's tPing2Recv and cycle N+1's tPing1Send. Removes the visual hiccup where ping2 (end of cycle N) and ping1 (start of cycle N+1) collided as two consecutive A→B cyan pulses. 2. Distinguish ping2 from ping1 visually: ping1 = solid filled circle, ping2 = hollow ring (same cyan color). Legend updated. The user can now tell at a glance which transmission is which without relying on the small label text. Reported by Flag 2026-04-27, fixed same day.
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:
- 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).
- 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_sendin the ping payload, every receiver reads it and compares to its ownT_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/Caddyfileon.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/Caddyfileon LXC 103,.128) :handle /ping-pong-ping/* { reverse_proxy 192.168.0.82:80 }— notehandle(nothandle_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 :
./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-LinkBB 55protocol 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.