Setup Monado, libsurvive and OpenComposite for the Valve Index

This guide will walk you through installing the free VR stack on an Arch Linux system.

Important note: The following is a guide on how to bypass steamvr entirely. Make no mistake: this is not a SteamVR plugin, you will be entirely subverting the use of Valve’s SteamVR. In any case, it is still possible to go back to SteamVR.

It will focus on using a Valve Index HMD, lighthouses V2 and Valve Index knuckles. It will also assume you have a recent AMD GPU (Polaris and newer) running the latest stable mesa graphics stack.

This stack is composed of:

1. Initial setup

You will need to install libsurvive-git as well as monado-git (both available in the AUR), in this order. It’s important to install libsurvive first since otherwise monado won’t recognize it at build time and fail to use it for 6 degree of freedom (6dof) motion tracking.

After installing these packages, it is essential to run the following:

sudo setcap CAP_SYS_NICE=eip /usr/bin/monado-service

Should you be using an AMD GPU, you will also need to set your GPU power state to VR mode for an acceptable experience:

sudo sh -c 'echo "4" > /sys/class/drm/card0/device/pp_power_profile_mode'

2. Calibration

Make sure your lighthouses are powered on and in the “On” state (as opposed to “Sleep”).

Make sure your controllers, VR knuckles and VR trackers are powered off as they may disrupt the solve.

Plug in your HMD and place it on the floor at the center of your room, making sure it has an uninterrupted line of sight with the lighthouses.

Run the following:

survive-cli --steamvr-calibration

Wait approximately 20 to 30 seconds, then terminate the command with ^C.

Because of a bug, you will need to run the above command again, wait again around 20 to 30 seconds, then terminate the command with ^C.

2.1 Import the SteamVR calibration into libsurvive

If you find that the calibration isn’t working well enough for you (tracking is still inconsistent, it jumps a lot), you can try the following:

If you’re coming back here after following section 5, make sure to relink your openvrpaths file back to the SteamVR one, then back to the OpenComposite one once you’re done.

The above section 2 method attempts to import your OpenVR/SteamVR calibration into libsurvive’s config, bypassing the native lighthouse solving difficulties of libsurvive. Should you still notice tracking is poor it may actually be your OpenVR calibration at fault.

Plug in your HMD (plugging in the DisplayPort cable is optional, we are purely looking to have it attached by USB so it can track on the proprietary drivers) and run steamvr as you are best able (either on Windows or Linux).

Take your HMD while SteamVR is running and while the HMD icon is active green and gently carry it all around the room posing it in many different orientations your head would naturally assume while playing. SteamVR will produce a better quality solve that survive will naturally be able to import from this data.

If you primarily use Windows for your playspace it would be a good idea to simply import the lighthousedb.json file directly from your Windows install drive/partition, as it will feature the strongest solve and highest runtime usage.

Delete the existing libsurvive calibration:

rm ~/.config/libsurvive/config.json

Place again your headset in the middle of the room, on the floor, in direct line of sight with the lighthouses.

Run the calibration like this twice, waiting 20-30 seconds before stopping each run:

survive-cli --steamvr-calibration ~/.steam/steam/config/lighthouse/lighthousedb.json

3. Configure the OpenXR runtime

Edit this file: ~/.config/openxr/1/active_runtime.json, changing its contents to the following:

{
    "file_format_version": "1.0.0",
    "runtime": {
        "library_path": "../../../../../usr/lib64/libopenxr_monado.so"
    }
}

Please note that library_path must be a relative path from the ~/.config/openxr/1/ directory to the monado libopenxr file.

If you installed monado through the AUR, or via another system wide package, then the above should be set automatically at a system level in the file /usr/share/openxr/1/openxr_monado.json, if not please adjust it accordingly in the home folder.

4. Testing the tracking

Install xrgears (available in the AUR), then start the monado service with the following environment variables, like so:

XRT_COMPOSITOR_SCALE_PERCENTAGE=140 XRT_COMPOSITOR_COMPUTE=1 SURVIVE_GLOBALSCENESOLVER=0 SURVIVE_TIMECODE_OFFSET_MS=-6.94 monado-service

Then, in another terminal run:

xrgears

Make sure the tracking is working correctly, and that you experience the full 6dof (you can move around the room, not just rotate your head around a fixed point in space).

If everything is working correctly, move on, otherwise repeat the steps detailed in section 2.

At this point you might want to back up your libsurvive configuration:

cp ~/.config/libsurvive/config.json ~/.config/libsurvive/config.json.bak

You may shut down monado-service with ^C.

5. Setting up OpenComposite

OpenComposite cannot be installed as a system package, otherwise it won’t be picked up by the Steam runtime sandbox.

Clone the OpenOVR repository. The official repository is https://gitlab.com/znixian/OpenOVR

git clone https://gitlab.com/znixian/OpenOVR.git --recurse-submodules
cd OpenOVR
mkdir build
cd build
cmake ..
make -j16

If make fails, possibly after an update, you can try running make clean, then make -j16 again.

Back up your openvrpaths file:

cp ~/.config/openvr/openvrpaths.vrpath ~/.config/openvr/openvrpaths.vrpath.steamvr

Create a new file ~/.config/openvr/openvrpaths.vrpath.opencomp, with the following content:

{
    "config": [
        "/home/username/.local/share/Steam/config"
    ],
    "external_drivers": null,
    "jsonid": "vrpathreg",
    "log": [
        "/home/username/.local/share/Steam/logs"
    ],
    "runtime": [
        "/home/username/git/OpenOVR/build/"
    ],
    "version": 1
}

Please replace username in the paths above with your username, or otherwise make sure /home/username/ is replaced with your own home folder.

Also make sure that the path listed under runtime reflects the correct path of your OpenComposite build directory.

Make both files read only like this:

chmod 444 ~/.config/openvr/openvrpaths.vrpath.steamvr ~/.config/openvr/openvrpaths.vrpath.opencomp

Then link your new Open Composite file as your main openvrpaths file, like so:

ln -sf $HOME/.config/openvr/openvrpaths.vrpath.opencomp $HOME/.config/openvr/openvrpaths.vrpath

If later on you want to switch back to SteamVR, you can do so by linking openvrpaths.vrpath.steamvr back to openvrpaths.vrpath.

6. Running Steam games through the free VR stack

Set the following launch options for your Steam game:

XR_RUNTIME_JSON=/run/host/usr/share/openxr/1/openxr_monado.json PRESSURE_VESSEL_FILESYSTEMS_RW=$XDG_RUNTIME_DIR/monado_comp_ipc %command%

Turn on your Index knuckles first, then start the monado service:

XRT_COMPOSITOR_SCALE_PERCENTAGE=140 XRT_COMPOSITOR_COMPUTE=1 SURVIVE_GLOBALSCENESOLVER=0 SURVIVE_TIMECODE_OFFSET_MS=-6.94 monado-service

Finally, start your game from Steam.

NOTE: If your game doesn’t start, close steam and reopen it through the command line to see more logs. If there is an error related to libcjson.so.1 you will need to build Monado with the cmake option -DXRT_HAVE_SYSTEM_CJSON=off.

7. Setting up monado’s systemd socket

If you prefer, you can enable monado’s systemd socket so that whenever you’re running a VR application, monado-service is automatically started up, and shut down when you’re done.

To do so:

systemctl --user enable monado.socket

At this point you will need to tweak your game launch options to also include the environment variables you would normally pass to monado-service.

Change your game launch options to the following:

XRT_COMPOSITOR_SCALE_PERCENTAGE=140 XRT_COMPOSITOR_COMPUTE=1 SURVIVE_GLOBALSCENESOLVER=0 SURVIVE_TIMECODE_OFFSET_MS=-6.94 XR_RUNTIME_JSON=/run/host/usr/share/openxr/1/openxr_monado.json PRESSURE_VESSEL_FILESYSTEMS_RW=$XDG_RUNTIME_DIR/monado_comp_ipc %command%

Additional notes

Credits

Special thanks to @BabbleBones for helping with the setup and detailing all of the steps.

This guide was written by Gabriele Musco.