Files
ping-pong-ping/README.md
Poulpe a22f060268 docs: link to Kogger hardware companion repo
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...').
2026-04-27 22:13:38 +00:00

7.2 KiB
Raw Permalink Blame History

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 (12 kt cruise speed, 5700 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 + N1 passive).
Realistic AUV speeds (12 kt) and ranges (5700 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 :

./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.52 % 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.