DeviceManager Programmer Notes - HipsterSloth/PSVRTracker GitHub Wiki

Device Manager

This container class updates all of the specific device managers for PSVRTracker. Specifically the TrackerManger and the HMDManager. The DeviceManager class is also front end for OS specific device queries and events. It routes device connection/disconnection events to the child device managers.

Members

DeviceManagerConfig

This class contains the following configuration properties:

  • Tracker Reconnect Interval
    • How often to poll to see if the connected tracker list changed
    • Only considered when not using the platform API to get tracker hotplug events
  • Tracker Poll Interval
    • How often to poll connected trackers for new video frames
  • HMD Reconnect Interval
    • How often to poll to see if the connected HMD list changed
    • Only considered when not using the platform API to get tracker hotplug events
  • HMD Poll Interval
    • How often to poll connected HMDs for new IMU data
  • Platform API Enabled Flag
    • Used to disable the usage of the Platform API layer (fall back to polling instead of hotplug callbacks)
    • Really only used as a debugging option

IPlatformDeviceAPI

Each OS has a specific implementation managing device hotplug notifications. The startup method for this interface registers an IDeviceHotplugListener (which the DeviceManager implements). Currently there is only an PlatformDeviceAPIWin32 implementation of this interface. Other OSes have to use polling to test for device connection/disconnection.

This interface also has a get_device_property() method that is used to fetch device property strings.

Tracker Manager

The TrackerManager class is responsible for managing all connected Sony tracking cameras that PSVRTrackercares about (i.e. the PS4Camera). On a regular interval it polls all connected tracking cameras and extracts any tracking projections it can find. These tracking projections are used to compute an optical tracking pose for each HMD.

More details can be found in TrackerManager Programmer Notes

HMD Manager

The HMDManager class is responsible for managing all connected Sony Head Mounted displays that PSVRTracker cares about (PSVR). The HMD manager will add and remove HMD entries as new HMDs are add or removed from the system. Connected HMDs are polled regularly for IMU sensor data. The HMD manager will also compute an HMD pose using sensor fusion of the optical tracking pose with the IMU sensor data.

More details can be found in HMDManager Programmer Notes

Functions

startup()

This method initializes the child device managers and the platform API. If any of the child managers fails initialization we fail startup of the DeviceManager.

update()

This method does the following:

  1. Sends off any newly received device hotplug events from the platform API
  2. Handles device connection/disconnection
  3. Polls the child device managers for new incoming data from devices
  4. Compute pose prediction for the HMDs
  5. Publishes updated controller and HMD state

See PSVRTracker Update Walkthrough for more details of the update flow.

handle_device_connected() / handle_device_disconnected()

Incoming device attach and detach events are forward on to the child device manager for actual processing.

DeviceTypeManager

All device managers inherit from this common base class which is responsible for doing the following book-keeping:

  • Maintain a ServerDeviceView list of connected devices
  • Managing connection / disconnection via polling
  • Polling connected devices on a regular interval

Members

Last Reconnect Time

The last time we checked to see if device connected or disconnected. This is only relevant if we don't have a device hotplug listener active. This shouldn't be too frequently (no more that once per second) since polling for device connection can be an expensive device enumeration query, particularly when using LibUSB.

Last Poll Time

The last time we polled all connected devices for new data. For controllers this means reading button and IMU data. For trackers this means polling for new video frames. For HMDs this means polling for new IMU data.

Device Views

A list of type ServerDeviceViewPtr. See DeviceManager-Programmer-Notes#ServerDeviceView class for more details.

Device List Dirty Flag

This flag gets set when the list of connected devices has changed. It's set by a hotplug notification or by device reconnect timer.

Functions

startup()

poll()

This function polls connected devices if the poll timer has elapsed. It also will update the connected device list if either the reconnect timer has elapsed or the device dirty list flag has been set.

See PSVRTracker Update Walkthrough for more details of the poll flow.

publish()

This function asks each connected device to send any unpublished state to the client API.

ServerDeviceViewPtr getDeviceViewPtr(int device_id)

Each connected device is identified by a device_id. This function can be used to retrieve a ServerDeviceViewPtr for the given device_id.

handle_device_connected() / handle_device_disconnected()

This callback will set the device list dirty flag which forces the device list to refresh on the next call to poll.

ServerDeviceView

The ServiceDeviceView class is an abstraction layer for different device types. It also holds data computed from raw device state (like filtered HMD pose). There are two derived classes: ServerTrackerView, and ServerHMDView.

Members

Has Unpublished State Flag

This flag says if the controller has recently polled state that hasn't yet been sent to the client. Once publish() has been called on the ServerDeviceView, this flag gets set to false until new data arrived.

Poll No Data Count

The number of sequential poll attempts made where no data was received from a device. This is usually a sign of USB bandwidth saturation. If a device has too many failed poll attempts, we will disconnect the device.

Sequence Number

Each batch of data received from a device is stamped by an increasing sequence number.

Last New Data Timestamp

The last time since we received new data from a device. This is used to compute an effective device update rate.

Device ID

A unique ID assigned to each connected device. This device_id is used as a handle by all external system to access device state. The DeviceTypeManager::getDeviceViewPtr() function is used to get an actual pointer to a ServerDeviceView given a device_id. Generally external systems shouldn't store pointers to a ServerDeviceView, but store device_ids instead.

Functions

open()

This function attempts to open a device using the given DeviceEnumerator. This is typically performed when the open device list has changed.

See Device Enumerator Programmer Notes for more details.

poll()

This function polls connected devices if the poll timer has elapsed. It also will update the connected device list if either the reconnect timer has elapsed or the device dirty list flag has been set.

See PSVRTracker Update Walkthrough for more details of the poll flow.

publish()

This function asks each connected device to send any unpublished state to any connected clients via the ServerNetworkManager.

matchesDeviceEnumerator()

When a device is opened we record the identifying information from the DeviceEnumerator used to open the device. When trying to determine if a device is already opened by a ServerDeviceView we check if the enumerator's device info matches a given ServerDeviceView using this function

getDevice()

This function returns a pointer to the internal IDeviceInterface pointer.

IDeviceInterface

All devices implement a derived version of this interface. This interface has all functionality shared by all devices. All controllers implement the IControllerInterface. All trackers implement the ITrackerInterface. All HMDs implement the IHMDInterface.

Functions

matchesDeviceEnumerator()

When a device is opened we record the identifying information from the DeviceEnumerator used to open the device. When trying to determine if a device is already opened by a IDeviceInterface we check if the enumerator's device info matches a given ServerDeviceView using this function.

open()

This function attempts to open a device using the given DeviceEnumerator. This is typically performed when the open device list has changed.

See Device Enumerator Programmer Notes for more details.

getIsReadyToPoll()

Some devices can only be polled for new sensor data when connected through certain hardware interfaces.

poll()

This function attempts to data from the device. For trackers this will be over USB or system camera APIs. For HMDs this will be over USB.

getMaxPollFailureCount()

Get the number of polling failure we're willing to accept no data from the device before we disconnect it

getDeviceType()

Returns what type of device this is with the CommonDeviceState::eDeviceType enumeration.

getSensorState()

Returns a block of CommonSensorState read from the device. You can look back at previously returned blocks of state using the lookBack index (0 means the most recently received state). This is useful for making predictions about future state. This CommonSensorState pointer can be cast to more specific device state depending on the device type (tracker or HMD).