Skip to main content
The FreePIE UDP tracker receives head tracking data over UDP network protocol from FreePIE scripts or any compatible application. This enables wireless tracking, integration with other software, or using devices that aren’t directly supported by OpenTrack.

How It Works

Any application can send orientation data to OpenTrack by broadcasting UDP packets to a specified port. The data format is simple: three rotation angles (yaw, pitch, roll) sent as floating-point values. This makes FreePIE UDP ideal for:
  • Smartphone IMU apps
  • Custom tracking solutions
  • VR/AR headset integration
  • Wireless IMU devices
  • Bridge from other tracking software
FreePIE is a programmable input emulator originally designed for VR and motion control. The UDP receiver in OpenTrack follows the same protocol, making it compatible with FreePIE scripts and similar tools.

Requirements

Software

  • OpenTrack with FreePIE UDP tracker
  • Data source (one of):
    • FreePIE with tracking script
    • Smartphone app (e.g., FreePIE IMU for Android)
    • Custom application sending UDP data
    • Another OpenTrack instance (for remote tracking)

Network

  • Both devices on same network (or route between them)
  • Firewall allowing UDP traffic on configured port
  • Low-latency network connection (WiFi or wired)
No special hardware required beyond what your data source needs (e.g., smartphone with gyro/accelerometer).

Setup Instructions

1

Configure OpenTrack

In OpenTrack tracker settings:
UDP Port: 5555 (or your chosen port)
Axis X Index: 0 (yaw)
Axis Y Index: 1 (pitch)  
Axis Z Index: 2 (roll)
The axis indices determine which incoming data channel maps to which rotation.
2

Configure Firewall

Allow UDP traffic:Windows Firewall:
# Allow OpenTrack to receive UDP
netsh advfirewall firewall add rule name="OpenTrack UDP" dir=in action=allow protocol=UDP localport=5555
Linux (ufw):
sudo ufw allow 5555/udp
Or add exception in your firewall GUI.
3

Find Your PC's IP Address

Your data source needs to know where to send data:Windows:
ipconfig
# Look for IPv4 Address under your active connection
Linux:
ip addr show
# or
hostname -I
Note the IP address (e.g., 192.168.1.100).
4

Configure Data Source

Option A: FreePIE (PC):Install FreePIE and create a script:
# Example FreePIE script
from System.Net import IPEndPoint, IPAddress
from System.Net.Sockets import UdpClient

if starting:
    client = UdpClient()
    endpoint = IPEndPoint(IPAddress.Parse("192.168.1.100"), 5555)

# Get data from source (e.g., Android sensor)
yaw = android[0].yaw
pitch = android[0].pitch  
roll = android[0].roll

# Send to OpenTrack
data = struct.pack('fff', yaw, pitch, roll)
client.Send(data, len(data), endpoint)
Option B: Smartphone App:
  1. Install “FreePIE IMU” or similar app
  2. Enter PC’s IP address: 192.168.1.100
  3. Enter Port: 5555
  4. Start sending data
Option C: Custom Application: Send UDP packets with 12 bytes (3 x float32):
import socket
import struct

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

yaw, pitch, roll = 0.0, 0.0, 0.0  # Your tracking data
data = struct.pack('fff', yaw, pitch, roll)
sock.sendto(data, ('192.168.1.100', 5555))
5

Test Connection

  1. Start OpenTrack with FreePIE UDP tracker
  2. Start your data source
  3. Move your tracking device
  4. Verify OpenTrack receives data (check output window)
If not working:
  • Verify IP address and port
  • Check firewall settings
  • Ensure both devices on same network
  • Test with localhost (127.0.0.1) first
6

Adjust Axis Mapping

If rotations are wrong:
  1. Change axis indices (try different combinations)
  2. Use angle offsets to adjust zero point:
    Add Yaw: 0 degrees
    Add Pitch: 0 degrees  
    Add Roll: 0 degrees
    
  3. Test until movements match expectations

Configuration Options

Network Settings

OptionDefaultDescription
UDP Port5555Port to listen on for incoming data
Choose a port between 1024-65535. Avoid commonly used ports. Default 5555 works well.

Axis Mapping

OptionDefaultDescription
Axis X Index0Which data channel for yaw (0-2)
Axis Y Index1Which data channel for pitch (0-2)
Axis Z Index2Which data channel for roll (0-2)

Angle Offsets

OptionDefaultDescription
Add YawOffset added to yaw (heading)
Add PitchOffset added to pitch (elevation)
Add RollOffset added to roll (bank)
The incoming UDP packet contains 3 float values. Axis indices determine which value maps to which rotation:
  • Index 0: First float in packet
  • Index 1: Second float in packet
  • Index 2: Third float in packet
If your rotations are mixed up, try different index combinations:
  • Common: X=0, Y=1, Z=2 (yaw, pitch, roll)
  • Alternative: X=2, Y=1, Z=0 (roll, pitch, yaw)

UDP Protocol Details

Packet Format

The FreePIE UDP protocol is straightforward:
Byte 0-3:   float32 - First rotation value
Byte 4-7:   float32 - Second rotation value  
Byte 8-11:  float32 - Third rotation value
Total: 12 bytes
  • Endianness: Little-endian (standard on x86/ARM)
  • Units: Degrees (not radians)
  • Range: Typically -180 to +180 degrees

Example Packet

import struct

yaw = 45.0    # degrees
pitch = -10.0 # degrees
roll = 5.0    # degrees

packet = struct.pack('<fff', yaw, pitch, roll)
# '<' = little-endian, 'fff' = three floats
# Result: 12 bytes ready to send via UDP

Sending Data

Python:
import socket
import struct
import time

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_address = ('192.168.1.100', 5555)

while True:
    yaw, pitch, roll = get_rotation_data()  # Your function
    packet = struct.pack('fff', yaw, pitch, roll)
    sock.sendto(packet, server_address)
    time.sleep(0.02)  # 50Hz update rate
C/C++:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int sock = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(5555);
inet_pton(AF_INET, "192.168.1.100", &addr.sin_addr);

float data[3] = {yaw, pitch, roll};
sendto(sock, data, sizeof(data), 0, 
       (struct sockaddr*)&addr, sizeof(addr));
JavaScript (Node.js):
const dgram = require('dgram');
const client = dgram.createSocket('udp4');

const buffer = Buffer.allocUnsafe(12);
buffer.writeFloatLE(yaw, 0);
buffer.writeFloatLE(pitch, 4);
buffer.writeFloatLE(roll, 8);

client.send(buffer, 5555, '192.168.1.100');

Use Cases

Smartphone Tracking

Use your phone’s gyro/accelerometer as a wireless head tracker.Apps:
  • FreePIE IMU (Android)
  • SensorUDP (iOS/Android)
  • Custom app with gyro API

Remote Tracking

Track on one PC, send data to another PC running the game.Example:
  • Laptop with webcam for tracking
  • Desktop PC for gaming
  • Send tracking data over LAN

Custom Hardware

Interface custom tracking hardware:
  • ESP32 with IMU (wireless)
  • Custom VR headset
  • Modified game controller
  • Experimental sensors

Software Bridge

Bridge from other tracking software:
  • Convert SteamVR tracking to OpenTrack
  • Relay from mobile tracking apps
  • Integrate with Unity/Unreal projects
  • Custom processing pipeline

Troubleshooting

  • Verify IP address is correct
  • Check port number matches (5555)
  • Test firewall is allowing UDP
  • Ensure both devices on same network/subnet
  • Try localhost (127.0.0.1) first to verify OpenTrack
  • Use Wireshark to verify packets are being sent
  • Change axis index mapping
  • Try all combinations (6 possibilities)
  • Check if data source sends radians vs degrees
  • Verify data source coordinate system
  • Use angle offsets if axes are correct but rotated
  • Use wired connection instead of WiFi
  • Reduce update rate if network congested
  • Close bandwidth-heavy applications
  • Use 5GHz WiFi if available
  • Check for network packet loss
  • Enable filtering in OpenTrack filter settings
  • Reduce data source noise (sensor fusion)
  • Increase update rate for smoother interpolation
  • Use Accela filter in OpenTrack
  • Check for packet loss
  • Issue is with data source (gyro drift)
  • Use sensor fusion in data source
  • Add magnetometer for yaw stability
  • Recenter view regularly in OpenTrack
  • Not an issue with UDP receiver itself

Advantages and Limitations

Advantages

  • Wireless tracking possible
  • Very flexible - any data source
  • Network-based (can track remotely)
  • Simple protocol, easy to implement
  • No special hardware required
  • Cross-platform compatible
  • Low CPU usage
  • Great for prototyping

Limitations

  • Network latency (WiFi ~20-50ms)
  • Rotation only (no position)
  • Requires separate data source
  • Network reliability affects tracking
  • Must configure firewall
  • Quality depends on data source
  • Possible packet loss

Smartphone Apps

Android

  • FreePIE IMU: Original FreePIE companion app
  • SensorUDP: Sends various sensor data via UDP
  • IP Webcam: Can send motion data alongside video

iOS

  • SensorLog: Logs and streams sensor data
  • UDP Sender: Generic UDP data sender
  • Custom apps using Core Motion API
Most apps let you configure IP address, port, and update rate. Use 50-100Hz for smooth tracking.

ESP32 Wireless IMU Example

#include <WiFi.h>
#include <WiFiUdp.h>
#include <Wire.h>
#include <MPU6050.h>

const char* ssid = "YourWiFi";
const char* password = "YourPassword";
const char* udpAddress = "192.168.1.100";
const int udpPort = 5555;

WiFiUDP udp;
MPU6050 mpu;

void setup() {
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) delay(500);
  
  Wire.begin();
  mpu.initialize();
}

void loop() {
  float yaw, pitch, roll;
  // Get rotation from MPU6050 (implement sensor fusion)
  
  uint8_t buffer[12];
  memcpy(buffer, &yaw, 4);
  memcpy(buffer + 4, &pitch, 4);
  memcpy(buffer + 8, &roll, 4);
  
  udp.beginPacket(udpAddress, udpPort);
  udp.write(buffer, 12);
  udp.endPacket();
  
  delay(20); // 50Hz
}

Comparison with Other Trackers

FeatureFreePIE UDPHATirePointTracker
Tracking typeRotation onlyRotation only6DOF
ConnectionUDP/WiFiSerial/USBUSB camera
WirelessYesOptionalNo
LatencyMedium (20-50ms)Low (20ms)Very Low (10ms)
FlexibilityVery HighMediumLow
DIY friendlyYesYesSome
CostVariesVery LowLow-Medium

Tips for Best Results

  1. Network: Use wired Ethernet or 5GHz WiFi for lowest latency
  2. Update Rate: 50-100Hz is sweet spot (more = higher bandwidth)
  3. Filtering: Enable filtering in OpenTrack to smooth network jitter
  4. Data Source: Use good sensor fusion algorithm for stable orientation
  5. Local First: Test on localhost before trying wireless
  6. Firewall: Add permanent firewall rule instead of temporary
  7. QoS: Enable QoS on router to prioritize UDP tracking packets

See Also

Build docs developers (and LLMs) love