sci / sonar

sonar lobby

two-way ranging between phones

Open this page on two or more phones and join the same room. Each phone chirps in its own turn and listens to everyone, itself included. The phones share no clock, and they don't need one: each times both chirps on its own clock, and the difference of differences is the distance between them.

Pick a room code, then join. Everyone who joins the same code is in the same lobby.
distances
Join on two phones. Their distance appears here after a couple of rounds, as the median of the last 15 with its spread.

How two phones measure each other

Timing of one round between phones A and B A's clock B's clock A chirps B chirps t_AA t_AB t_BA t_BB t_AB − t_AA t_BB − t_BA
One round. Each bracket is measured on one phone's clock, so neither depends on when the other phone's clock started. A's bracket is longer than B's by twice the travel time between them.
d = (c/2)·[(t_AB − t_AA) − (t_BB − t_BA)] + (s_A + s_B)/2

This is the BeepBeep scheme (Peng et al. 2007). Everything a phone adds to the timing cancels: when its clock started, how long its speaker takes to play, how long its microphone takes to deliver. Each of those affects both arrivals in a bracket equally, or both brackets equally. Two things remain. The first is s, each phone's own speaker-to-microphone spacing, which its self-hearing adds and the formula gives back. The second is the difference in crystal rates, a few tens of parts per million, which over one 300 ms slot is a few millimetres. What comes out is the mean of the two speaker-to-microphone paths between the phones, so read it to the nearest centimetre or two of the phones' edges.

Taking turns. The lobby gives each phone a 300 ms slot in a round, in join order. Each chirp is 10 ms long, sweeping 17–19.8 kHz, which fits phones sampling at 44.1 or 48 kHz. Neighbouring slots sweep in opposite directions, so a phone whose speaker is slow to start is not mistaken for the next one. Each phone looks for each chirp where the schedule says it should be, takes the first arrival rather than the loudest one so that a reflection off a wall does not win, and refines it to a fraction of a sample.

The network carries no audio. Phones send only their arrival times, a few numbers per round, through one small room on the server. Network delay only has to be good enough to keep the slots apart. Every phone syncs to the room's clock by timing round trips, which is accurate to tens of milliseconds, well inside a slot. All the precision comes from the sound.

What this part does. It measures distances between pairs of phones, for up to twelve phones in a room. With five phones a round takes 1.5 s and measures ten distances. The next part fits every distance together into a map of where the phones are. After that comes multistatic sonar: every phone hearing every other phone's echoes off whatever moves in the room.

To try it

Put two phones a measured distance apart, a metre or two, speakers unobstructed. Join the same room on both, and leave the screens on, because a locked phone stops listening. Set each phone's spacing to the distance between its bottom speaker and the microphone the browser uses, usually 1–3 cm on the bottom edge. The distance settles after a few rounds. Move one phone and watch it follow.

Sources

  1. C. Peng, G. Shen, Y. Zhang, Y. Li, K. Tan, "BeepBeep: a high accuracy acoustic ranging system using COTS mobile devices," SenSys (2007). doi:10.1145/1322263.1322265
  2. G. L. Turin, "An introduction to matched filters," IRE Trans. Inf. Theory 6(3), 311–329 (1960). doi:10.1109/TIT.1960.1057571

signal path: sonar.js, shared with the single-phone sonar · lobby: one Durable Object per room · sci