FollowMe was a project for NIWC (Naval Information Warfare Center) to turn a Boston Dynamics Spot into a “human follower” that can be controlled from (and eventually track) a smartwatch. The full system had three pillars: smartwatch command/control, computer vision tracking, and Bluetooth direction finding.

FollowMe Robot

I will mainly go over my part: building and stress-testing a Bluetooth-based follower that tries to estimate where the user is (relative to Spot) using BLE radio measurements—especially useful when the user is out of the camera’s view.


The Bluetooth idea (in one paragraph)

If the user (or their smartwatch) periodically transmits BLE packets with a Constant Tone Extension (CTE), a receiver with an antenna array can sample IQ data across its antennas and estimate the signal’s Angle of Arrival (AoA). If we combine that angle with an approximate range estimate from RSSI (signal strength), we can synthesize a 3D position of the beacon and feed it into the robot’s follower controller.

That’s the dream. The reality is: real environments are brutal (multipath, interference, reflections, body-blocking), and with only one locator you don’t get true triangulation—so filtering and sanity checks matter a lot.


Hardware + tools I worked with

Receiver (on the robot)

Silicon Labs BG22 Antenna Array

Tag / beacon (carried by the user)

Dev stack


Pipeline: IQ → angle, RSSI → range, fuse → position

Bluetooth FollowMe Pipeline

1) AoA from IQ samples

Each BLE packet’s CTE gives phase-coherent IQ samples. Across an antenna array, phase differences encode the incoming wave direction. The estimator (Silicon Labs RTL / MUSIC-style approach) outputs:

I then applied a lightweight smoother to reduce one-frame spikes:

α^k=(1β)α^k1+βαk

(We used a fairly aggressive β=0.65 during bring-up just to make it usable in real-time.)

2) Range from RSSI (log-distance path loss)

RSSI-based ranging is inherently squishy, but it’s the simplest way to get a distance proxy:

ρ=10Ar10η

To keep it from going totally off the rails, I added an outlier rejection (e.g., ignore sudden RSSI jumps larger than a set threshold) and averaged across antenna elements to reduce fading noise.

3) Spherical → Cartesian

Once you have (ρ, θ, ϕ), convert into a position estimate in the locator frame:

x=ρsinϕcosθy=ρsinϕsinθz=ρcosϕ

That (x,y,z) becomes the “target point” for the follower controller (or for visualization on the robot’s map).

What worked vs what didn’t

What worked

What didn’t (and why we didn’t fully ship Bluetooth-following)