← all builds

From-Scratch Build · Robotics Networking

Motion-Capture to ROS Bridge

A room of infrared cameras can pin down where an object is to within a millimetre — but that data is locked inside the capture software. This build is the bridge: a ROS package that pulls tracking data out of an optical motion-capture system, publishes it as ROS topics, and re-exposes it over raw UDP for any external program to read. Built from scratch to learn real-time data plumbing.

ROSMotion captureNatNet VRPNUDP socketsroslaunch

What it is

Getting tracking data out of the room

An optical motion-capture system surrounds a space with cameras and tracks reflective markers in real time. It knows the position and orientation of every "rigid body" to sub-millimetre precision — but it speaks its own protocols, and the rest of a robotics setup speaks ROS.

This package is the translator. It connects to the capture software, turns each tracked body into a ROS topic, and — crucially — also opens UDP sockets so a machine outside the ROS network entirely can subscribe to the same live positions. One bridge, two ways out.

The core idea I wanted to learn: real-time data is only useful if everything that needs it can reach it. Bridging a proprietary capture feed into both ROS topics and plain UDP means a robot, a logger and a remote server can all act on the same ground truth.

The stack

Tools under the hood

Two capture protocols, ROS in the middle, UDP on the way out. Here is what each piece does.

protocol · fast

NatNet

The higher-rate path — around 120 Hz with unicast support and fine-grained configuration. Harder to set up, but the option when you need every frame.

protocol · simple

VRPN

The easy path — fewer options, around 50 Hz, and far quicker to launch. The right choice when speed of setup beats raw rate.

middleware

ROS

Each tracked rigid body becomes a ROS topic, so any ROS node in the system can subscribe to live pose data.

transport

UDP sockets

The topics are also exposed as UDP sockets, letting external servers outside ROS read the same stream directly.

orchestration

roslaunch files

Launch files wire up the chosen client and the UDP layer, with parameters for server IP, node count and namespace.

generation

Node generator

A script spins up one publishing node per rigid body, so the number of UDP outputs scales to how many bodies you track.

How it works

From cameras to a UDP socket

The data takes a clear path from the capture room to any consumer:

  1. Cameras track live

    The motion-capture system locates each marker set and computes rigid-body poses in real time.

  2. Client connects live

    A NatNet or VRPN client subscribes to the capture software's stream over the network.

  3. Publish to ROS live

    Each rigid body is republished as a ROS topic that any node can subscribe to.

  4. Expose over UDP live

    A generated node per body opens a UDP socket, mirroring the pose data outside ROS.

  5. External read live

    A remote server reads the UDP sockets and uses the live positions however it needs.

  6. Multicast / broadcast WIP

    Wider NatNet distribution modes — flagged as work in progress in this build.

Running it

One launch, your choice of path

Everything comes up through a single launch file with sensible defaults you can override:

In my rebuild I focused on the UDP fan-out: generating one publishing node per rigid body so an off-ROS machine can read exactly the bodies it cares about.

Reflection

What rebuilding it taught me