Examples ======== These examples may help you get started with PyHeadTracker. You can find more `here `__. Supperware ---------- This example demonstrates how to use the Supperware Head Tracker with PyHeadTracker and send the orientation data via OSC to the `IEM SceneRotator `__. .. code-block:: python import pyheadtracker as pht osc_send = pht.out.IEMSceneRotator(ip="127.0.0.1", port=7000) ht = pht.supperware.HeadTracker1( device_name="Head Tracker 1", device_name_output="Head Tracker 2", refresh_rate=50, compass_on=True, orient_format="q", ) ht.open(compass_force_calibration=False) ht.zero() while True: try: orientation = ht.read_orientation() if isinstance(orientation, pht.Quaternion): osc_send.send_orientation(orientation) # Print the quaternion values for debugging print( f"WXYZ: {orientation[0]:7.2f} {orientation[1]:7.2f} {orientation[2]:7.2f} {orientation[3]:7.2f}", end="\r", ) except (EOFError, KeyboardInterrupt): print("\nClosing connection.") ht.close() break Camera-based tracking --------------------- This example demonstrates how to use the MediaPipe Face Landmarker for webcam-based head tracking with PyHeadTracker. The orientation data is sent via OSC to the `IEM SceneRotator `__. .. code-block:: python import pyheadtracker as pht scenerotator_send = pht.out.IEMSceneRotator(ip="127.0.0.1", port=7000) roomencoder_send = pht.out.IEMRoomEncoder(ip="127.0.0.1", port=7001, mode="listener") ht = pht.cam.MPFaceLandmarker(0, orient_format="ypr") ht.open() ht.zero() while True: try: pose = ht.read_pose() if pose is not None: orientation = pose["orientation"] position = pose["position"] else: continue if isinstance(orientation, pht.YPR): scenerotator_send.send_orientation(orientation) if isinstance(position, pht.Position): roomencoder_send.send_position(position) if isinstance(orientation, pht.YPR) and isinstance(position, pht.Position): print( f"Yaw: {orientation.yaw:.2f}, Pitch: {orientation.pitch:.2f}, Roll: {orientation.roll:.2f} | X: {position.x:.2f}, Y: {position.y:.2f}, Z: {position.z:.2f}", end="\r", ) except (EOFError, KeyboardInterrupt): print("\nClosing connection.") ht.close() break openXR ------ In this example, we use the openXR bindings to retrieve head tracking data from a head mounted display, while rendering a dummy OpenGL scene. Orientation data is sent via OSC to the `IEM SceneRotator `__ and position data to the `IEM RoomEncoder `__. .. code-block:: python import pyheadtracker as pht from OpenGL import GL import xr from xr.utils.gl import ContextObject from xr.utils.gl.glfw_util import GLFWOffscreenContextProvider scenerotator_send = pht.out.IEMSceneRotator(ip="127.0.0.1", port=7000) roomencoder_send = pht.out.IEMRoomEncoder(ip="127.0.0.1", port=7001, mode="listener") with ContextObject( instance_create_info=xr.InstanceCreateInfo( enabled_extension_names=[ # A graphics extension is mandatory (without a headless extension) xr.KHR_OPENGL_ENABLE_EXTENSION_NAME, ], ), context_provider=GLFWOffscreenContextProvider(), ) as context: # Create a head tracker using OpenXR ht = pht.hmd.openXR(context) eye_colors = [ (0, 1, 0, 1), # Left eye green (0, 0, 1, 1), # Right eye blue (1, 0, 0, 1), # Third eye blind ] run_idx = 0 try: for frame_index, frame_state in enumerate(context.frame_loop()): for view_index, view in enumerate(context.view_loop(frame_state)): run_idx += 1 if run_idx == 20: ht.zero() GL.glClearColor(*eye_colors[view_index]) GL.glClear(GL.GL_COLOR_BUFFER_BIT) orientation = ht.read_orientation(frame_state) position = ht.read_position(frame_state) if orientation is not None: scenerotator_send.send_orientation(orientation) orientation_ypr = pht.utils.quat2ypr(orientation).to_degrees() print( f"Yaw: {orientation_ypr[0]:7.2f} {orientation_ypr[1]:7.2f} {orientation_ypr[2]:7.2f}", end="\r", ) if position is not None: roomencoder_send.send_position(position) # print( # f"XYZ: {position.x:7.2f} {position.y:7.2f} {position.z:7.2f}", # end="\r", # ) except (EOFError, KeyboardInterrupt): print("\nClosing connection.")