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
.txtfile) - 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++ clientbuild/SampleClientROS1TF.so→ C++ ROS TF broadcasterbuild/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
-
Open
simple_callback.pyand set the IP addresses:SERVER_IP = "192.168.1.6" # IP of Motive server LOCAL_IP = "192.168.1.20" # IP of your machine -
Run the script:
python3 simple_callback.pyYou 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