Monado OpenXR Runtime
hydra_driver.c File Reference

Razer Hydra prober and driver code. More...

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xrt/xrt_prober.h"
#include "os/os_hid.h"
#include "os/os_time.h"
#include "math/m_api.h"
#include "util/u_debug.h"
#include "util/u_device.h"
#include "util/u_misc.h"
#include "util/u_time.h"
#include "util/u_logging.h"
#include "hydra_interface.h"
Include dependency graph for hydra_driver.c:

Data Structures

struct  hydra_controller_state
 
struct  hydra_state_machine
 The details of the Hydra state machine in a convenient package. More...
 
struct  hydra_system
 A Razer Hydra system containing two controllers. More...
 
struct  hydra_device
 A Razer Hydra device, representing just a single controller. More...
 

Macros

#define HYDRA_TRACE(d, ...)   U_LOG_XDEV_IFL_T(&d->base, d->sys->log_level, __VA_ARGS__)
 
#define HYDRA_DEBUG(d, ...)   U_LOG_XDEV_IFL_D(&d->base, d->sys->log_level, __VA_ARGS__)
 
#define HYDRA_INFO(d, ...)   U_LOG_XDEV_IFL_I(&d->base, d->sys->log_level, __VA_ARGS__)
 
#define HYDRA_WARN(d, ...)   U_LOG_XDEV_IFL_W(&d->base, d->sys->log_level, __VA_ARGS__)
 
#define HYDRA_ERROR(d, ...)   U_LOG_XDEV_IFL_E(&d->base, d->sys->log_level, __VA_ARGS__)
 
#define SET_INPUT(NAME)
 

Enumerations

enum  hydra_input_index {
  HYDRA_INDEX_1_CLICK , HYDRA_INDEX_2_CLICK , HYDRA_INDEX_3_CLICK , HYDRA_INDEX_4_CLICK ,
  HYDRA_INDEX_MIDDLE_CLICK , HYDRA_INDEX_BUMPER_CLICK , HYDRA_INDEX_JOYSTICK_CLICK , HYDRA_INDEX_JOYSTICK_VALUE ,
  HYDRA_INDEX_TRIGGER_VALUE , HYDRA_INDEX_POSE , HYDRA_MAX_CONTROLLER_INDEX
}
 
enum  hydra_button_bit {
  HYDRA_BUTTON_BIT_BUMPER = (1 << 0) , HYDRA_BUTTON_BIT_3 = (1 << 1) , HYDRA_BUTTON_BIT_1 = (1 << 2) , HYDRA_BUTTON_BIT_2 = (1 << 3) ,
  HYDRA_BUTTON_BIT_4 = (1 << 4) , HYDRA_BUTTON_BIT_MIDDLE = (1 << 5) , HYDRA_BUTTON_BIT_JOYSTICK = (1 << 6)
}
 
enum  hydra_sm_state { HYDRA_SM_LISTENING_AFTER_CONNECT = 0 , HYDRA_SM_LISTENING_AFTER_SET_FEATURE , HYDRA_SM_REPORTING }
 The states of the finite-state machine controlling the Hydra. More...
 

Functions

static void hydra_device_parse_controller (struct hydra_device *hd, uint8_t *buf)
 Parse the controller-specific part of a buffer into a hydra device. More...
 
static struct hydra_devicehydra_device (struct xrt_device *xdev)
 
static struct hydra_systemhydra_system (struct xrt_tracking_origin *xtrack)
 
static uint8_t hydra_read_uint8 (uint8_t **bufptr)
 
static int16_t hydra_read_int16_le (uint8_t **bufptr)
 
static int hydra_system_read_data_hid (struct hydra_system *hs, timepoint_ns now)
 
static int hydra_system_enter_motion_control (struct hydra_system *hs, timepoint_ns now)
 Switch to motion controller mode. More...
 
static int hydra_system_update (struct hydra_system *hs)
 Update the internal state of the Hydra driver. More...
 
static void hydra_device_update_input_click (struct hydra_device *hd, timepoint_ns now, int index, uint32_t bit)
 
static xrt_result_t hydra_device_update_inputs (struct xrt_device *xdev)
 
static xrt_result_t hydra_device_get_tracked_pose (struct xrt_device *xdev, enum xrt_input_name name, int64_t at_timestamp_ns, struct xrt_space_relation *out_relation)
 
static void hydra_system_remove_child (struct hydra_system *hs, struct hydra_device *hd)
 
static void hydra_device_destroy (struct xrt_device *xdev)
 
int hydra_found (struct xrt_prober *xp, struct xrt_prober_device **devices, size_t device_count, size_t index, cJSON *attached_data, struct xrt_device **out_xdevs)
 Probing function for Razer Hydra devices. More...
 

Variables

static const uint8_t HYDRA_REPORT_START_MOTION []
 
static const uint8_t HYDRA_REPORT_START_GAMEPAD []
 

Detailed Description

Razer Hydra prober and driver code.

Author
Rylie Pavlik rylie.nosp@m..pav.nosp@m.lik@c.nosp@m.olla.nosp@m.bora..nosp@m.com
Jakob Bornecrantz jakob.nosp@m.@col.nosp@m.labor.nosp@m.a.co.nosp@m.m

Portions based on the VRPN Razer Hydra driver, originally written by Rylie Pavlik and available under the BSL-1.0.

Macro Definition Documentation

◆ SET_INPUT

#define SET_INPUT (   NAME)
Value:
do { \
(hd->base.inputs[HYDRA_INDEX_##NAME].name = XRT_INPUT_HYDRA_##NAME); \
} while (0)

Enumeration Type Documentation

◆ hydra_sm_state

The states of the finite-state machine controlling the Hydra.

Function Documentation

◆ hydra_device_get_tracked_pose()

static xrt_result_t hydra_device_get_tracked_pose ( struct xrt_device xdev,
enum xrt_input_name  name,
int64_t  at_timestamp_ns,
struct xrt_space_relation out_relation 
)
static
Todo:
how do we report this is not (necessarily) the same base space as the HMD?

◆ hydra_device_parse_controller()

static void hydra_device_parse_controller ( struct hydra_device hd,
uint8_t *  buf 
)
static

Parse the controller-specific part of a buffer into a hydra device.

Todo:
the presence of this suggest we're not decoding the orientation right.

References hydra_read_int16_le(), and xrt_quat::math_quat_normalize().

◆ hydra_device_update_inputs()

static xrt_result_t hydra_device_update_inputs ( struct xrt_device xdev)
static
Todo:
report pose

◆ hydra_read_int16_le()

static int16_t hydra_read_int16_le ( uint8_t **  bufptr)
inlinestatic
Todo:
nothing actually defines XRT_BIG_ENDIAN when needed!

Referenced by hydra_device_parse_controller().

◆ hydra_system_enter_motion_control()

static int hydra_system_enter_motion_control ( struct hydra_system hs,
timepoint_ns  now 
)
static

Switch to motion controller mode.

References os_hid_device::os_hid_set_feature(), U_LOG_IFL_D, and hydra_system::was_in_gamepad_mode.

◆ hydra_system_update()

static int hydra_system_update ( struct hydra_system hs)
static

Update the internal state of the Hydra driver.

Reads devices, checks the state machine and timeouts, etc.

References os_monotonic_get_ns().

Variable Documentation

◆ HYDRA_REPORT_START_GAMEPAD

const uint8_t HYDRA_REPORT_START_GAMEPAD[]
static
Initial value:
= {
0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00}

◆ HYDRA_REPORT_START_MOTION

const uint8_t HYDRA_REPORT_START_MOTION[]
static
Initial value:
= {
0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00}