Skip to content

Using the NatNet Bridge

Code Repository: NatNet Client

  • C++ base client for NatNet
  • Option 1: Python integration via Pybind11, Python callback function (e.g., saves MoCap data to a .txt file)
  • Option 2: ROS1 TF broadcaster
  • Handles clean shutdown with Ctrl+C

Project Structure

SampleClient/
├── build/                      # Compiled output (.so, binaries)
├── include/pybind11/           # Local copy of Pybind11 headers
├── NatNetBaseClient.cpp/hpp    # Base client logic
├── NatNetPythonClient.cpp/hpp  # Python client with callback
├── NatNetROSClient.cpp/hpp     # Optional ROS TF broadcasting
├── mainPythonBindings.cpp      # Pybind11 binding code
├── simple_callback.py          # Example Python script
├── makefile                    # (Option 1) build config using Make
├── CMakeLists.txt              # (Option 2) build config using CMake

Build Options

Before building or running the clients, extend the library path so the system can find the required NatNet shared libraries:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/user/NatnetBridge_4_1/lib

Requirements:

  • g++
  • Python 3.6+ (adapt makefile for other versions)
  • ROS (optional, only needed for TF support)

This generates:

  • build/SampleClientBase.so → pure C++ client
  • build/SampleClientROS1TF.so → C++ ROS TF broadcaster
  • build/SampleClientPythonCallback.so → Python client module
cd SampleClient
mkdir -p build && cd build
cmake ..
make

The same targets will be generated in build/.

To clean manually (or add your own clean target):

rm -rf build/

Offset Calibration (Automatic)

When the client starts, it automatically performs a one-time time offset calibration between the MoCap system time and the local (or ROS) time.
The offset is calculated by comparing the local wall time to the timestamp provided by the NatNet frame data (fTimestamp), and using the minimum observed difference (to minimize network jitter effects).

If ROS is enabled, it uses ros::Time::now() for synchronization.

This offset is then added to all future fTimestamp values to align them to the local system or ROS clock.

Example output:

[TimeSync] Final Offset = 1743752052.394101 s (min = 1743752052.387872, latency = 0.006230)

Usage

  1. Open simple_callback.py and set the IP addresses:

    SERVER_IP = "192.168.1.6"   # IP of Motive server
    LOCAL_IP  = "192.168.1.20"  # IP of your machine
    

  2. Run the script:

    python3 simple_callback.py
    

    You should see mocap data being written to PythonCallback_MocapData.txt.

    Example output per line:

    135,1.2520,2,torso,0.230,-1.324,0.980,0.000,0.707,0.000,0.707
    

If you want to broadcast the marker transforms as ROS TF messages, run the ROS-enabled client after building:

cd build
./SampleClientROS1TF