OpenXR Motion Compensation

DISCLAIMER: This software is distributed as-is, without any warranties or conditions of any kind. Use at your own risks!

Version: 0.2.6

This document contains instructions on how to use OpenXR motion compensation API layer.

Purpose of OpenXR Motion Compensation

When using a motion rig in combination with a VR headset (hmd) he movement of the rig causes the in-game camera to change along with your position in the real world. In simulations for example you're basically feel being pushed around inside the cockpit when the motion rig moves.
Motion compensation reduces or ideally removes that effect by locking the in-game world to the pose of the motion rig. This software aims to provide an API layer for motion compensation to be used with applications and hmds supporting the OpenXR standard.
To be able to do that, the software needs to be informed on the motion rig movement / position. This can be achieved using a tracker, which is either a physical object attached to the motion rig and tracked by the VR runtime (e.g. a motion controller or a vive puck) or a virtual tracker using data from the motion software driving the motion rig.

Limitations:

Contact

Feel free to join our Discord community or to send an e-mail to oxrmc@mailbox.org for feedback and assistance.

You can find the source code and the latest release or report issues on github.

If you are (or know someone) willing and able to support the software development (mostly C++, maybe some GUI stuff later on) side of the project, feel free to contact @BuzzteeBear on the Discord server to ask about ways to contribute.

Donations to the project are very welcome and can be made via Paypal.
On explicit user request you can also sponsor the project via GitHub Sponsors

Installation

Run installer executable

Just double click the installation executable called Install_OpenXR-MotionCompensation_<current_version>.exe and follow the instructions. A few hints regarding the installation process:

Conflict with other OpenXR API layers

There may be issues with other OpenXR API layers that are installed on your system. For the most part they can be solved by using the correct order of installation (because that implicitly determines the order in which the layers are loaded).
According to user feedback following constraints seem to be working:

Optional: Confirm correct installation

You can use the application OpenXR Explorer to verify the correct installation:

Update

To get OXRMC udpated, download and run the latest installation executable from Github. If you want to change the installation directory you have to uninstall the previous version first.

Uninstallation

To remove the OpenXR-MotionCompensation layer just use windows settings/control panel as you would do witgh any other application. During uninstallation you can choose to delete your configuration and log files in the appdata directory or to keep them for later use.

Configuration

Configuration files can be found at ...\Users\*<Your_Username>*\AppData\Local\OpenXR-MotionCompensation\OpenXR-MotionCompensation.log. After intial installtion this directory contains the default configuration file OpenXR-MotionCompensation.ini. You can make changes to that file to configure options you want to be the same for all OpenXR applications. Upon starting an OpenXR application with the API layer active for the first time, a configuration file named after the application is created in the same directory. You can use it to copy (partial) sections from the default configuration file whenever you want to make changes only for that application specifically.

Use of the Configuration file

What you can modify in a configuration file:

Sections in configuration file

Using a virtual tracker

To use a virtual tracker (as opposed to a physical device) set parameter tracker_type according to the motion software that is providing the data for motion compensation on your system:

Calibrate virtual tracker

To enable OXRMC to correlate translation and rotation of the rig to the virtual space correctly when using a virtual tracker, you have to provide the information where the center of rotation (cor) of your motion rig is positioned and which way is forward. This can be done with the following steps:

  1. Calculate, measure or estimate the distance between your headset and the center of rotation of your motion rig in forward/backward, up/down and left/right direction (I was told most 6 dof rigs rotate around the bottom of the seat but your mileage may vary).
  2. Enter the offset values in the config file
  3. Start the OpenXR application of your choice
  4. Bring your motion rig in neutral position
  5. Sit in your rig
  6. put your headset on and face forward (~ direction surge). Potential rotation of the hmd on roll and pitch angle is ignored for the calculation
  7. issue the calibration command by activating the center shortcut. You can also do this implicitly by activating motion compensation if you haven't (re)calibrated since last loading of the configuration.

Saving and the cor location

The current position and orientation of the cor is part of the configuration and can be saved to the (global or app-specific) config file. When your satisfied with the current setting you can set the config key use_cor_pos to 1. This causes the cor position to be loaded from the config file when calibrating instead of being determined using the hmd position and the offset values.
Note that this functionality may not work with all HMD vendors. Setting up the playspace in the VR runtime configuration of your hmd might help to get this working correctly. Rumor has it that some HMDs need to be started/initialized at the exact same location for the playspace coordinates to be consistent in between uses.
Feedback on success or failure of this functionality using different VR systems is very welcome and can be made via discord server of the project.

Running your application

  1. make sure your using OpenXR as runtime in the application you wish to use motion compensation in
  2. start application
  3. center the in-app view
  4. activate the motion controller you configured and mount it on your motion rig
  5. bring your motion rig to neutral position
  6. Reset the ingame view if necesary
  7. press the activate shortcut (CTRL + INSERT by default). This implicitly sets the neutral reference pose for the tracker

Graphical overlay

You can enable/disable the overlay using the toggle_overlay shortcut. It displays a marker in your headset view for:

Connection Loss

OXRMC can detect if a reference tracker isn't available anymore, if:

After detecting a loss of connection a configurable timeout period is used (connection_timeout), allopwing two possible outcomes:

Troubleshooting

Upon activating any shortcut you get audible feedback, corresponding to the performed action (or an error, if something went wrong). If you're getting 'error' or no feedback at all, check for error entries (search for keyword 'error') in the log file at ...\Users<Your_Username>\AppData\Local\OpenXR-MotionCompensation\OpenXR-MotionCompensation.log.

Recentering in-game view

If you recenter the in-app view during a session the reference pose is reset by default. Therefore you should only do that while your motion rig is in neutral position. It is possible (depending on the application) that this automatic recalibration is not triggered, causing the view and reference pose to be out of sync and leading to erroneous motion compensation. You should do the following steps to get this corrected again:

  1. deactivate motion compensation by pressing the activate shortcut
  2. bring your motion rig to neutral position. Face forward if yout using a virtual tracker
  3. recalibrate by pressing the center shortcut
  4. reactivate motion compensation by pressing the activate shortcut

Virtual tracker

When using a virtual tracker and the audible feedback says 'motion compensation activated' but you don't get motion compensation as you would expect Use the MmfReader App to make sure oxrmc is actually receiving data from the motion software.

  1. Find a way to feed your motion software with artificial rotational telemetry (e.g. Joystick mode in the Setup section of SRS, a sine wave generator for FlyPT Mover or Gamepad / DirectInput plugin for YawVR Game Engine.
  2. Calibrate your cor (ctrl+del by default) as described in here and activate motion compenation
  3. Find the right height
    1. start rolling fully to the right while keeping the head still (in reference to the seat) and check if your ingame position is moving.
    2. if your view is moved to the right, lower your cor position (ctrl+page down), if it's moving left lift it up (ctrl + page up)
    3. rinse & repeat until your in-game position does not move when rolling
  4. Set the forward distance
    1. start pitching fully backward do the same as for roll, but this time check if you're moved up or down in game
    2. if your position is rising move the cor backwards, if it's lowering move it forward
    3. rinse & repeat until your in-game position does not move when rolling
  5. Save your configuration (ctrl + shift + s), once you got your cor dialed in. That causes the new offset values as well as the current cor position to be written into the config file for later use.

Physical tracker

You can always request help on the Discord server

Additional Notes

MMF Reader

The software package includes a small app called MMF Reader which allows you to display the content of the memory mapped file used for virtual trackers. Just execute it from windows start menu or use the executable in the installation directory and select the kind of tracker you're using from the dropdown menu.

Logging

The motion compensation layers logs rudimentary information and errors in a text file located at ...\Users<Your_Username>\AppData\Local\OpenXR-MotionCompensation\OpenXR-MotionCompensation.log. After unexpected behaviour or a crash you can check that file for abormalities or error reports.

If you encounter repeatable bugs or crashes you can use the Windows Performance Recorder Profile (WPRP) tracelogging in combination with the configuration contained within scripts\Trace_OpenXR-MotionCompensation.wprp to create a more detailed protocol.

Tracelogging can become very useful to investigate user issues.

To capture a trace for the API layer:

You can send the trace file to the developer or use an application such as Tabnalysis to inspect the content yourself.

List of keyboard bindings

To combine multiple keys for a single shortcut they need to be separated by '+' with no spaces in between the key descriptors.

List of supported shortcut key names:

Name Key
SHIFT shift key
CTRL ctrl key
ALT alt key
LSHIFT left shift key
RSHIFT right shift key
LCTRL left ctrl key
RCTRL right ctrl key
LALT left alt key
RALT right alt key
0- 9 numerical key
A- Z alphbetical key
BACKQUOTE `~ key (US)
TAB tabulator key
CAPS caps lock key
PLUS + key (any country)
MINUS - key (any country)
OPENBRACKET [{ key (US)
CLOSEBRACKET ]} key (US)
SEMICOLON ;: key (US)
QUOTE '" key (US)
BACKSLASH \| key (US)
COMMA , key (any country)
PERIOD . key (any country)
SLASH /? key (US)
BACK backspace key
CLR clr key
RETURN return key
ESC esc key
SPACE space key
LEFT cursor left key
UP cursor up key
RIGHT cursor right key
DOWN cursor down key
INS ins key
DEL del key
HOME home key
END end key
PGUP page up key
PGDN page down key
NUM0 0 key on NUM
NUM1 1 key on NUM
NUM2 2 key on NUM
NUM3 3 key on NUM
NUM4 4 key on NUM
NUM5 5 key on NUM
NUM6 6 key on NUM
NUM7 7 key on NUM
NUM8 8 key on NUM
NUM9 9 key on NUM
NUMLOCK numlock key
NUMDIVIDE / key on NUM
NUMMULTIPLY * key on NUM
NUMSUBTRACT - key on NUM
NUMADD + key on NUM
NUMDECIMAL . key on NUM
NUMSEPARATOR separator key on NUM
F1 F1 key
F2 F2 key
F3 F3 key
F4 F4 key
F5 F5 key
F6 F6 key
F7 F7 key
F8 F8 key
F9 F9 key
F10 F10 key
F11 F11 key
F12 F12 key
PRTSC print screen key
SCROLL scroll lock key
PAUSE pause key
SELECT select key
PRINT print key
HELP help key
EXEC execute key
GAMEPAD_A A button on gamepad
GAMEPAD_B B button on gamepad
GAMEPAD_X X button on gamepad
GAMEPAD_Y Y button on gamepad
GAMEPAD_RIGHT_SHOULDER right shoulder button on gamepad
GAMEPAD_LEFT_SHOULDER left shoulder button on gamepad
GAMEPAD_LEFT_TRIGGER left trigger button on gamepad
GAMEPAD_RIGHT_TRIGGER right trigger button on gamepad
GAMEPAD_DPAD_UP digital pad up on gamepad
GAMEPAD_DPAD_DOWN digital pad down on gamepad
GAMEPAD_DPAD_LEFT digital pad left on gamepad
GAMEPAD_DPAD_RIGHT digital pad right on gamepad
GAMEPAD_START start button on gamepad
GAMEPAD_VIEW view button on gamepad
GAMEPAD_LEFT_THUMBSTICK_BUTTON left thumbstick pressed on gamepad
GAMEPAD_RIGHT_THUMBSTICK_BUTTON right thumbstick pressed on gamepad
GAMEPAD_LEFT_THUMBSTICK_UP left thumbstick up on gamepad
GAMEPAD_LEFT_THUMBSTICK_DOWN left thumbstick down on gamepad
GAMEPAD_LEFT_THUMBSTICK_RIGHT left thumbstick left on gamepad
GAMEPAD_LEFT_THUMBSTICK_LEFT left thumbstick right on gamepad
GAMEPAD_RIGHT_THUMBSTICK_UP right thumbstick up on gamepad
GAMEPAD_RIGHT_THUMBSTICK_DOWN right thumbstick down on gamepad
GAMEPAD_RIGHT_THUMBSTICK_RIGHT right thumbstick left on gamepad
GAMEPAD_RIGHT_THUMBSTICK_LEFT right thumbstick right on gamepad