openhmd
- Generic VR interface using OpenHMD¶
Classes and functions for using various VR devices (HMDs, controllers, and generic spatial trackers) through the OpenHMD driver interface.
OpenHMD is a free and open-source software (FOSS) project which aims to provide a driver interface for a variety of VR headsets, controllers and trackers. This interface is under heavy development (both with PsychXR and OpenHMD itself) so expect things to change without notice between releases of PsychXR.
This module isn’t a simple wrapper around OpenHMD. The design of this OpenHMD Python API is intended to be similar (to the extent that is feasible) to that of LibOVR. Therefore, using the OpenHMD API in PsychXR is quite different than using the C API. Where the C API uses getter and setter functions for nearly everything, the PsychXR interface uses classes and functions analogous to those in the LibOVR driver library. Unlike LibOVR, OpenHMD does not come with a compositor. Therefore, the user must implement their own system to present scenes to the display (ex. using Pyglet or GLFW). This requires considerably more effort on behalf of the user than LibOVR, but may offer greater flexibility for those that need it by removing the “black box” between the application and the display.
This library is only available if PsychXR was built with the environment variable ``PSYCHXR_BUILD_OPENHMD=1`` being previously set. Be aware that this module is currently in the alpha phase of development and may be incomplete and buggy.
Overview¶
Classes¶
OHMDDeviceInfo |
Information class for OpenHMD devices. |
Functions¶
OHMDDeviceInfo |
Information class for OpenHMD devices. |
success (int result) |
Check if a function returned successfully. |
failure (int result) |
Check if a function returned an error. |
getVersion () |
Get the version of the OpenHMD library presently loaded. |
create () |
Create a new OpenHMD context/session. |
destroy () |
Destroy the current context/session. |
probe () |
Probe for devices. |
isContextProbed () |
Check if probe() was called on the current context. |
getDeviceCount () |
Number of devices found during the last call to probe() . |
getError () |
Get the last error as a human readable string. |
getDevices (int deviceClass=-1, …) |
Get devices found during the last call to probe() . |
openDevice (device) |
Open a device. |
closeDevice (device) |
Close a device. |
getDevicePose (device) |
Get the pose of a device. |
lastUpdateTimeElapsed () |
Get the time elapsed in seconds since the last update() call. |
update () |
Update the values for the devices handled by a context. |
getDeviceParamf (device, int param) |
Get a floating point parameter from a device. |
setDeviceParamf (device, int param, value) |
Set a floating point parameter for a given device. |
getDeviceParami (device, int param) |
Get an integer parameter from a device. |
getString (int stype) |
Get a string from OpenHMD. |
getListString (int index, int type_) |
Get a device description string from an enumeration list index. |
getListInt (int index, int type_) |
Get an integer value from an enumeration list index. |
Details¶
Classes¶
-
class
psychxr.drivers.openhmd.
OHMDDeviceInfo
¶ Information class for OpenHMD devices.
OpenHMD supports a wide range of devices (to varying degrees), including HMDs, controller, and trackers. This class stores data about a given device, providing the user details (e.g., type of device, vendor/product name, capabilities like tracking, etc.) about it.
Instances of this class are returned by calling
getDevices()
. You can then pass instances toopenDevice()
to open them.-
deviceClass
¶ Device class identifier (int).
-
deviceFlags
¶ Device flags (int).
Examples
Check if a device has positional and orientation tracking support:
hmdInfo = getHmdInfo() flags = OHMD_DEVICE_FLAGS_POSITIONAL_TRACKING | OHMD_DEVICE_FLAGS_ROTATIONAL_TRACKING hasFullTracking = (self.c_data.deviceFlags & flags) == flags
-
deviceIdx
¶ Enumerated index of the device (int).
-
hasOrientationTracking
¶ True
if capable of tracking orientation (bool).
-
hasPositionTracking
¶ True
if capable of tracking position (bool).
-
isController
¶ True
if this device is a controller (bool).
-
isDebugDevice
¶ True
if a virtual debug (null or dummy) device (bool).
-
isHMD
¶ True
if this device is an HMD (bool).
-
isOpen
¶ Is the device open? (bool).
-
isTracker
¶ True
if this device is a generic tracker (bool).
-
manufacturer
¶ Device manufacturer name, alias of vendorName (str)
-
productName
¶ Device product name (str).
-
vendorName
¶ Device vendor name (str).
-
Functions¶
-
psychxr.drivers.openhmd.
success
(int result)¶ Check if a function returned successfully.
Parameters: result (int) – Return value of a function. Returns: True if the return code indicates success. Return type: bool
-
psychxr.drivers.openhmd.
failure
(int result)¶ Check if a function returned an error.
Parameters: result (int) – Return value of a function. Returns: True if the return code indicates failure. Return type: bool
-
psychxr.drivers.openhmd.
getVersion
()¶ Get the version of the OpenHMD library presently loaded.
Returns: Major (int), minor (int), and patch (int) version. Return type: tuple Examples
Get the version for the OpenHMD library:
major_version, minor_version, patch_version = getVersion()
-
psychxr.drivers.openhmd.
create
()¶ Create a new OpenHMD context/session.
Calling this will create a context, enumerate devices and open them. Only the first connected HMD will be opened, all other device types that are controllers or external trackers will be opened.
At this time only a single context can be created per session. You must call this function prior to using any other API calls other than
destroy()
.Returns: Returns value of OHMD_S_OK
if a context was created successfully, elseOHMD_S_USER_RESERVED
. You can check the result using thesuccess()
andfailure()
functions.Return type: int Examples
Create a new OpenHMD context, starting the session:
import sys import psychxr.drivers.openhmd as openhmd result = openhmd.create() # create a context if failure(result): # if we failed to create a context, exit with error sys.exit(1)
-
psychxr.drivers.openhmd.
destroy
()¶ Destroy the current context/session.
-
psychxr.drivers.openhmd.
probe
()¶ Probe for devices.
Probes for and enumerates supported devices attached to the system. After calling this function you may use
getDevices()
which will return a list of descriptors representing found devices.Returns: Number of devices found on the system. Return type: int
-
psychxr.drivers.openhmd.
isContextProbed
()¶ Check if
probe()
was called on the current context.Returns: True
if the context was probed since :func:create
was called.Return type: bool
-
psychxr.drivers.openhmd.
getDeviceCount
()¶ Number of devices found during the last call to
probe()
.This function returns the same number that was returned by the last
probe
call. If referencing devices by their enumerated index, values from0
togetDeviceCount() - 1
are valid.Returns: Number of devices found on this system that OpenHMD can use. Return type: int
-
psychxr.drivers.openhmd.
getError
()¶ Get the last error as a human readable string.
Call this after a function returns a code indicating an error to get a string describing what went wrong.
Returns: Human-readable string describing the cause of the last error. Return type: str
-
psychxr.drivers.openhmd.
getDevices
(int deviceClass=-1, bool openOnly=False, bool nullDevices=False)¶ Get devices found during the last call to
probe()
.Parameters: - deviceClass (int) – Only get devices belonging to the specified device class. Values can be
one of
OHMD_DEVICE_CLASS_CONTROLLER
,OHMD_DEVICE_CLASS_HMD
, orOHMD_OHMD_DEVICE_CLASS_GENERIC_TRACKER
. Set to-1
to get all devices (the default). - openOnly (bool) – Only get devices that are currently opened. Default is False which will return all devices found during the last probe call whether they are opened or not.
- nullDevices (bool) – Include null/debug devices.
Returns: List of
OpenHMDDeviceInfo
descriptors.Return type: Examples
Get all HMDs found on the system:
if probe(): # >0 if devices have been found all_devices = getDevices() only_hmds = [dev for dev in all_devices if dev.isHMD]
The same as above but using the deviceClass argument:
# assume we probed already only_hmds = getDevices(deviceClass=OHMD_DEVICE_CLASS_HMD)
- deviceClass (int) – Only get devices belonging to the specified device class. Values can be
one of
-
psychxr.drivers.openhmd.
openDevice
(device)¶ Open a device.
Parameters: device (OHMDDeviceInfo or int) – Descriptor or enumerated index of a device to open. Best practice is to pass a descriptor instead of an int.
-
psychxr.drivers.openhmd.
closeDevice
(device)¶ Close a device.
Parameters: device (OHMDDeviceInfo or int) – Descriptor or enumerated index of a device to close. Best practice is to pass a descriptor instead of an int.
-
psychxr.drivers.openhmd.
getDevicePose
(device)¶ Get the pose of a device.
Parameters: device (OHMDDeviceInfo or int) – Descriptor or enumerated index of a device to open. Best practice is to pass a descriptor instead of an int. Returns: Object representing the pose of the device. Return type: RigidBodyPose Examples
Get the position (vector) and orientation (quaternion) of a device:
myDevicePose = getDevicePose(myDevice) # HMD, controller, etc. pos, ori = myDevicePose.posOri
You can get the eye poses from the pose (assuming its an HMD):
import psychxr.tools.vrmath as vrmath leftEyePose, rightEyePose = vrmath.calcEyePoses(device, ipd=0.062)
These can be converted to eye view matrices:
leftViewMatrix = leftEyePose.viewMatrix rightViewMatrix = rightViewMatrix.viewMatrix
-
psychxr.drivers.openhmd.
lastUpdateTimeElapsed
()¶ Get the time elapsed in seconds since the last
update()
call.Returns: Elapsed time in seconds. Return type: float
-
psychxr.drivers.openhmd.
update
()¶ Update the values for the devices handled by a context.
Call this once per frame. If PsychXR is running in a background thread, it is recommended that you call this every 10-20 milliseconds.
-
psychxr.drivers.openhmd.
getDeviceParamf
(device, int param)¶ Get a floating point parameter from a device.
This calls to ohmd_device_getf on the specified device, retrieving the value requested by param.
Parameters: - device (OHMDDeviceInfo or int) – Descriptor or enumerated index of a device. Best practice is to pass a descriptor instead of an int.
- param (int) –
Symbolic constant representing the parameter to retrieve. Parameters can be one of the following constants (return type and length if applicable in parentheses):
OHMD_ROTATION_QUAT
(ndarray, length 4)OHMD_LEFT_EYE_GL_MODELVIEW_MATRIX
(ndarray, length 16)OHMD_RIGHT_EYE_GL_MODELVIEW_MATRIX
(ndarray, length 16)OHMD_LEFT_EYE_GL_PROJECTION_MATRIX
(ndarray, length 16)OHMD_RIGHT_EYE_GL_PROJECTION_MATRIX
(ndarray, length 16)OHMD_POSITION_VECTOR
(ndarray, length 3)OHMD_SCREEN_HORIZONTAL_SIZE
(float)OHMD_SCREEN_VERTICAL_SIZE
(float)OHMD_LENS_HORIZONTAL_SEPARATION
(float)OHMD_LENS_VERTICAL_POSITION
(float)OHMD_LEFT_EYE_FOV
(float)OHMD_LEFT_EYE_ASPECT_RATIO
(float)OHMD_RIGHT_EYE_FOV
(float)OHMD_RIGHT_EYE_ASPECT_RATIO
(float)OHMD_EYE_IPD
(float)OHMD_PROJECTION_ZFAR
(float)OHMD_PROJECTION_ZNEAR
(float)OHMD_DISTORTION_K
(ndarray, length 6)OHMD_UNIVERSAL_DISTORTION_K
(ndarray, length 4)OHMD_UNIVERSAL_ABERRATION_K
(ndarray, length 3)OHMD_CONTROLS_STATE
(ndarray, length is the value ofOHMD_CONTROL_COUNT
returned by the API)
- value (object) – Value to set, must have the same length as the what is required by the parameter.
Returns: Single floating-point value or array. The return value data type and size is automatically determined by the type of parameter.
Return type: float or ndarray
Examples
Get the horizontal and vertical screen size for a device:
physical_horiz_size = ohmd.getDeviceParamf( hmd_device, ohmd.OHMD_SCREEN_HORIZONTAL_SIZE) physical_vert_size = ohmd.getDeviceParamf( hmd_device, ohmd.OHMD_SCREEN_VERTICAL_SIZE)
Get the left eye model/view matrix:
left_modelview_matrix = ohmd.getDeviceParamf( hmd_device, ohmd.OHMD_LEFT_EYE_GL_MODELVIEW_MATRIX) # you may want to reshape it left_modelview_matrix = left_modelview_matrix.reshape((4, 4))
-
psychxr.drivers.openhmd.
setDeviceParamf
(device, int param, value)¶ Set a floating point parameter for a given device.
This calls to ohmd_device_setf on the specified device, passing the value specified by param.
Parameters: - device (OHMDDeviceInfo or int) – Descriptor or enumerated index of a device. Best practice is to pass a descriptor instead of an int.
- param (int) –
Symbolic constant representing the parameter to set. Parameters can be one of the following constants (parameter type and length if applicable in parentheses):
OHMD_EYE_IPD
(float)OHMD_PROJECTION_ZFAR
(float)OHMD_PROJECTION_ZNEAR
(float)OHMD_EXTERNAL_SENSOR_FUSION
(ndarray, length 10)
Examples
Set the eye IPD for the device used to compute view matrices:
ohmd.setDeviceParamf( hmd_device, ohmd.OHMD_EYE_IPD, 0.062) # in meters
-
psychxr.drivers.openhmd.
getDeviceParami
(device, int param)¶ Get an integer parameter from a device.
This calls to ohmd_device_geti on the specified device, retrieving the value requested by param.
Parameters: - device (OHMDDeviceInfo or int) – Descriptor or enumerated index of a device. Best practice is to pass a descriptor instead of an int.
- param (int) –
Symbolic constant representing the parameter to retrieve. Parameters can be one of the following constants (return type and length if applicable in parentheses):
OHMD_SCREEN_HORIZONTAL_RESOLUTION
(int)OHMD_SCREEN_VERTICAL_RESOLUTION
(int)OHMD_DEVICE_CLASS
(int)OHMD_DEVICE_FLAGS
(int)OHMD_CONTROL_COUNT
(int)OHMD_CONTROLS_HINTS
(ndarray, length is the value ofOHMD_CONTROL_COUNT
returned by the API)OHMD_CONTROLS_TYPES
(ndarray, length is the value ofOHMD_CONTROL_COUNT
returned by the API)
Returns: Single integer value or array. The return value data type and size is automatically determined by the type of parameter.
Return type: float or ndarray
Examples
Get the horizontal and vertical screen resolution for a device:
hres = ohmd.getDeviceParamf( hmd_device, ohmd.OHMD_SCREEN_HORIZONTAL_RESOLUTION) vres = ohmd.getDeviceParamf( hmd_device, ohmd.OHMD_SCREEN_VERTICAL_RESOLUTION)
-
psychxr.drivers.openhmd.
getString
(int stype)¶ Get a string from OpenHMD.
Parameters: stype (int) – Type of string data to fetch, either one of OHMD_GLSL_DISTORTION_FRAG_SRC
orOHMD_GLSL_DISTORTION_FRAG_SRC
.Returns: Result of the ohmd_gets
C-API call (int) and the description text (str).Return type: tuple
-
psychxr.drivers.openhmd.
getListString
(int index, int type_)¶ Get a device description string from an enumeration list index.
Can only be called after
probe()
.Parameters: Returns: The string description text (str).
Return type: