WindTrack
Python interface to Interact with the Tracking
Motion Tracking
The WindSuite supports Optitrack and Vicon motion capture systems for tracking objects.
All the tracked objects can be accessed via the tracking module of the SDK, which provides a unified interface to access the tracking data regardless of the underlying motion capture system.
Callback
To access the Tracking data, users can register a callback function.
The given function will automatically be called each time a new Tracking data is available, with the new data passed as an argument to the function.
Note the type hint indicating that the callback function is passed a dictionary mapping object names to their tracking data.
This lets you iterate over all tracked objects and access their data in a structured way.
output
=== Tracking Data (2 objects) ===
Object: windprobe
Timestamp: 1770394277.5759277s
Position (world): (0.309, 0.040, 0.300) m
Rotation (world): w=0.983, x=-0.128, y=-0.130, z=-0.011
Velocity (world): (X:0.00, Y:0.00, Z:0.00) m/s | Norm : 0.00 m/s
Object: windshaper
Timestamp: 1770394277.5759277s
Position (world): (0.000, 0.000, 0.000) m
Rotation (world): w=1.000, x=0.000, y=0.000, z=0.000
Velocity (world): (X:0.00, Y:0.00, Z:0.00) m/s | Norm : 0.00 m/s
read_tracking.py
import os
import threading
from dotenv import load_dotenv
from windsuite_sdk import TrackingData, WindsuiteSDK
load_dotenv()
SERVER_IP_ADDRESS = os.getenv("SERVER_IP_ADDRESS", default="localhost")
def on_tracking_data(data: dict[str, TrackingData]) -> None:
"""
Callback for tracking data.
Args:
data: Dictionary mapping object names to their tracking data.
"""
print(f"=== Tracking Data ({len(data)} objects) ===")
for object_name, tracking_data in data.items():
print(f"Object: {object_name}")
print(f" Timestamp: {tracking_data.timestamp}s")
# Position
pos = tracking_data.position_meters_world_ref
print(f" Position (world): ({pos.x:.3f}, {pos.y:.3f}, {pos.z:.3f}) m")
# Rotation (quaternion)
rot = tracking_data.rotation_world_ref
print(
f" Rotation (world): w={rot.w:.3f}, x={rot.x:.3f}, y={rot.y:.3f}, z={rot.z:.3f}"
)
vel = tracking_data.velocity_mps_world_ref
norm = (vel.x**2 + vel.y**2 + vel.z**2) ** 0.5
print(
f" Velocity (world): (X:{vel.x:.2f}, Y:{vel.y:.2f}, Z:{vel.z:.2f}) m/s | Norm : {norm:.2f} m/s"
)
print()
stop_event = threading.Event()
def main() -> None:
"""Main function to run the WindSuite SDK example."""
base_url = f"http://{SERVER_IP_ADDRESS}"
print(f"Connecting to WindSuite server at {base_url}")
sdk = WindsuiteSDK(base_url=base_url)
sdk.register_tracking_callback(callback=on_tracking_data)
sdk.start_communication()
try:
freq_hz = 25
while not stop_event.wait(timeout=(1.0 / freq_hz)):
# ! DO WHATEVER
pass
except KeyboardInterrupt:
print("\nShutting down...")
stop_event.set()
finally:
sdk.fan_controller.set_intensity(0).apply()
sdk.cleanup()
print("SDK stopped")
if __name__ == "__main__":
main()
