Skip to content
Sheridan Lund edited this page Mar 2, 2024 · 23 revisions

OpenGloves Input Methods

OpenGloves provides multiple ways to feed inputs to it:

  • USB Serial
  • Bluetooth Serial
  • Named Pipes

USB Serial and Bluetooth Serial require an external (or emulated) device, and inputs are encoded as a string with a newline as a delimiter.

Input via a Named Pipe uses a struct and input can be fed to it by other local processes on the PC.

Through An External Device

The driver uses a string consisting one or more keys (represented as one or more characters) and a value for each key.

The list of keys are specified below, along a description of what they encode for (note quotation marks are not included for keys):

"A"  whole thumb curl (default curl value for thumb joints) - scalar
"B"  whole index curl (default curl value for index joints) - scalar
"C"  whole middle curl (default curl value for middle joints) - scalar
"D"  whole ring curl (default curl value for ring joints) - scalar
"E"  whole pinky curl (default curl value for pinky joints) - scalar

"(AAA)" thumb joint 0 - scalar
"(AAB)" thumb joint 1 - scalar
"(AAC)" thumb joint 2 - scalar
"(BAA)" index joint 0 - scalar
"(BAB)" index joint 1 - scalar
"(BAC)" index joint 2 - scalar
"(BAD)" index joint 3 - scalar
"(CAA)" middle joint 0 - scalar
"(CAB)" middle joint 1 - scalar
"(CAC)" middle joint 2 - scalar
"(CAD)" middle joint 3 - scalar
"(DAA)" ring joint 0 - scalar
"(DAB)" ring joint 1 - scalar
"(DAC)" ring joint 2 - scalar
"(DAD)" ring joint 3 - scalar
"(EAA)" pinky joint 0 - scalar
"(EAB)" pinky joint 1 - scalar
"(EAC)" pinky joint 2 - scalar
"(EAD)" pinky joint 3 - scalar

"(AB)"  whole thumb splay - scalar
"(BB)"  whole index splay - scalar
"(CB)"  whole middle splay - scalar
"(DB)"  whole ring splay - scalar
"(EB)"  whole pinky splay - scalar

"F" joystick x component - scalar
"G" joystick y component - scalar
"H" joystick button - boolean

"I" trigger button - boolean
"J" A button - boolean
"K" B button - boolean

"L" grab - boolean
"M" pinch - boolean

"N" system button (opens SteamVR menu) - boolean

"O" calibration button - boolean

"P" trigger value - scalar

Brackets around the keys are required if the key contains multiple characters.

A specific packet does not have to contain all of the keys, and the driver will only update scalar inputs for keys that appear in the packet (more on boolean inputs below).

If a key encodes for a boolean value, a value does not have to be specified with the key in order to set it to true, but the value will be set to false if the key does not appear in the packet.

For example, a packet may look like: A256B110C0D1023IJ\n

A packet should end with a newline character.

Input via Named Pipe

Input can be fed to OpenGloves using a pipe with the name: \\.\pipe\vrapplication\input\glove\<version>\<left/right>.

Named pipes are versioned. You can see the structs corresponding to each version below. Each struct version will remain the constant.

// "\\.\pipe\vrapplication\input\glove\v1\<left/right>"
struct InputData {
  const std::array<std::array<float, 4>, 5> flexion;
  const std::array<float, 5> splay;
  const float joyX;
  const float joyY;
  const bool joyButton;
  const bool trgButton;
  const bool aButton;
  const bool bButton;
  const bool grab;
  const bool pinch;
  const bool menu;
  const bool calibrate;
};

// "\\.\pipe\vrapplication\input\glove\v2\<left/right>"
struct InputData {
  const std::array<std::array<float, 4>, 5> flexion;
  const std::array<float, 5> splay;
  const float joyX;
  const float joyY;
  const bool joyButton;
  const bool trgButton;
  const bool aButton;
  const bool bButton;
  const bool grab;
  const bool pinch;
  const bool menu;
  const bool calibrate;

  const float trgValue;
};

The flexion property is an 5 element array, with each element being a 4 element array. The 5 fingers have 4 joints that can be set. Note that the last joint of the thumb is not used, but remains there for parity with other fingers, but all others are used.

Finger Inputs

All finger inputs (splay and curl + joint curls) are scalar values. They range from 0 to the max analog value. This value is set in the settings file, or in steamvr.vrsettings when using the UI that ships with the driver on Steam.

For splay, half the max analog value is set as the finger being straight, without any splay, and decreasing towards 0 is splaying the finger to the left. The maximum value is 10 degrees, but can be changed. Please open a PR, or discuss with us if you want to change this.

If a curl of a joint is not specified, the curl for the whole hand is used. If your hardware does not need to utilise mutliple joints, just provide the curl of the whole finger, using the single character keys (A,B,C,D,E), and all joints will be updated.

<finger> joint 0 encodes for the carpometacarpal joint (this is typically only used by the thumb). It should most likely be left blank for any other finger.
<finger> joint 1 encodes for the bend at the metacarpophalangeal joint
<finger> joint 2 encodes for the bend at the proximal interphalangeal joint
<finger> joint 3 encodes for the bend at the distal interphalangeal joint (not present on thumb)

Named Pipes

When using named pipes, these joints are ordered 0-3 as the indices of the array inside the specific cell of a finger (thumb->pinky) Ensure you fill each finger joint with data, and that data is a float of 0-1. Use a normalization formula to adjust your hardware tracking. When Reading from the pipe, set your pipe to NON BLOCKING with the following code in C++ or a similar function for any other language. Important note: 0 is your fingers extend in game, 1 is curled into a fist.

 DWORD mode = PIPE_READMODE_BYTE | PIPE_NOWAIT;
 BOOL success = SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL);

Joint image

Driver Outputs

The driver will send these any (or none) of these keys back when it has received an input:

"A" - Thumb force feedback. Integer from 0-1000
"B" - Index force feedback. Integer from 0-1000
"C" - Middle force feedback. Integer from 0-1000
"D" - Ring force feedback. Integer from 0-1000
"E" - Pinky force feedback. Integer from 0-1000
"F" - Frequency of haptic vibration. Decimal
"G" - Duration of haptic vibration. Decimal
"H" - Amplitude of haptic vibration. Decimal

Refer here for more info on haptic vibrations: https://github.com/ValveSoftware/openvr/blob/master/samples/drivers/drivers/simplecontroller/src/controller_device_driver.cpp#L255