Vrui on Oculus Rift DK2

I know, the Oculus Rift DK2 is obsolete equipment, but nonetheless — there are a lot of them still out there, it’s still a decent VR headset for seated applications, I guess they’re getting cheaper on eBay now, and I put in all the work back then to support it in Vrui, so I might as well describe how to use it. If nothing else, the DK2 is a good way to watch DVD movies, or panoramic mono- or stereoscopic videos, in VR.

Figure 1: Using an Oculus Rift DK2 headset with a pair of Vive controllers -- because why not?

Figure 1: Using an Oculus Rift DK2 headset with a pair of Vive controllers — because why not?

Prerequisites

Here’s what you need to get started: a genuine Oculus Rift DK2 VR headset with tracking camera and all cables (duh), a computer with a decent CPU and graphics card running some version of Linux, vendor-supplied drivers for your graphics card, the Vrui VR toolkit, version 4.2 or newer, and the last released Linux version of Oculus’ run-time/SDK, 0.5.0.1-beta (if you can’t find that run-time for download anywhere, look below).

Software Installation

If you don’t have Linux on your computer yet, I recommend using the current 64-bit release of Linux Mint with the MATE desktop environment. It’s easy to install, well-supported, and overall no-nonsense. If you have an Nvidia or AMD graphics card, install appropriate vendor-supplied drivers through the Driver Manager in the control panel. Here is a video showing the entire installation process for Linux Mint 17, starting from a blank PC: From-scratch AR Sandbox Software Installation. You can stop watching the video after Vrui has been installed (unless you also want to build an AR Sandbox while you’re at it).

If you don’t want to watch the video, the easiest way to install Vrui is to download its automatic installation script and run it. From a terminal window, run ($ indicates the terminal prompt):

$ cd ~
$ wget http://idav.ucdavis.edu/~okreylos/ResDev/Vrui/Build-Ubuntu.sh
$ bash Build-Ubuntu.sh

and then enter your password once or twice, as prompted. If everything succeeds, you will be greeted by a window with a spinning globe. If you are using Fedora Linux instead of Linux Mint or Ubuntu, replace Build-Ubuntu.sh with Build-Fedora.sh above.

The last step is to download and install the final Linux version of Oculus’ run-time/SDK. It is still available from Oculus’ web site, but it is a little hard to find. Here’s how:

  1. Go to Oculus’ front page, http://oculus.com.
  2. Scroll all the way to the bottom of the page, and click on “Downloads” under the “Developers” heading.
  3. On the “Downloads” page, first select “PC” from the left-side drop-down list (which starts out on “All categories”). This populates the right-side drop-down list with different PC SDK versions. Afterwards, select “0.5.0.1-beta” from the right-side drop-down list.
  4. The page will now list different download options. Click on the “Details” button next to “Oculus SDK for Linux (Experimental) V0.5.0.1-beta.”
  5. On the SDK download page, check the license check box, and then click the “Download” button to download the run-time/SDK.
  6. When your web browser asks you what to do with the SDK package, select “Open with Engrampa Archive Manager (default)” (or use whatever archive manager is offered to you), and press OK.
  7. The only component of the run-time/SDK that’s actually needed is the stand-alone tracking driver, ovrd, which is buried in ovr_sdk_linux_0.5.0.1/Service/OVRServer/Bin/Linux/x86_64/ReleaseStatic. Click through to that location, select ovrd, press the “Extract” button, de-select “Re-create folders” in the file selection dialog that pops up, and store ovrd somewhere. You can later copy ovrd into a system location such as /usr/local/bin.
  8. Once you have ovrd extracted, you can throw away the rest of the SDK package.

Hardware Setup

Now connect your Rift DK2. Place the tracking camera somewhere (I like putting it on the top edge of my monitor) and plug it in, then plug in the Rift’s power, USB, and HDMI cables. Connect the camera’s synchronization cable to the Rift’s break-out box.

The Rift’s display might already light up at this point, but either way, open your display configuration panel (if you have an Nvidia graphics card, open nvidia-settings). In nvidia-settings, go to “X Server Display Configuration” and select “Oculus VR Inc. Rift DK2 (…)” from the “Selection” drop-down list. Then select “X screen 0” from the “Configuration” drop-down list, and set the resolution to 1080×1920, and the refresh rate to 75 Hz. Set the orientation to “No Rotation.” Finally, click on your main display in the “Layout” panel, select “Make this the primary display for the X screen,” and press the “Apply” button. Your main screen should turn black momentarily; once it comes back, select “OK” in the “Confirm Mode Switch” dialog that pops up. Other display configuration panels might show different options, but all should allow you to enable the Rift’s display as a desktop extension, and set its resolution and refresh rate to their native values (1080×1920, 75 Hz, no rotation).

At this point, the power LED on the top of the Rift should glow solid blue, and the Rift’s screen should show your desktop’s background image.

Next, open a new terminal window and run Oculus’ tracking driver, ovrd, without any command line options. If everything worked, it should display a bunch of log messages, and end with

[TrackingManager] Broadcasting new HMD count = 1
CameraFactory::inspectCamera ends successfully

If it shows a final HMD count of zero (or simply crashes), the driver was not able to find the Rift’s display. As a first step, try logging out and logging back in, and then restarting ovrd. Some desktop environments do not properly update all internal display state, specifically EDID blocks, after a display is hot-plugged, and need to be re-initialized this way.

Running Vrui Applications

Vrui comes pre-configured to work with an Oculus Rift DK2. All Rift-specific settings are contained in the “RiftDK2” section in Vrui’s main configuration file, /usr/local/etc/Vrui-4.2/Vrui.cfg. There a many, many options to tweak and fine-tune Vrui to your taste, but the defaults should already do a decent job. To run any Vrui application in the Rift, append “-rootSection RiftDK2” (sans quotes) to its command line, such as:

$ VisionTest -rootSection RiftDK2

If you now put on the headset, you should see a standard vision test chart floating 20 feet (6m) in front of you. Go ahead, see how good your eyes are! (Just kidding; unless you’re legally blind, your vision will be limited by the Rift’s display, not by your eyes.) To exit the application, press Esc.

The virtual environment inside the Rift might look choppy as you move your head. If this happens, it’s probably because OpenGL is syncing to the wrong display’s vertical retrace pulse. Using the Nvidia driver, there’s a way to select the syncing display. Open nvidia-settings, and look underneath the “GPU 0 – (…)” heading. There should be an entry for “Oculus VR Inc. Rift DK2”, prefixed by a display name such as DFP-1. Note this display name, and then enter into the same terminal window from which you run Vrui applications:

$ export __GL_SYNC_DISPLAY_DEVICE=DFP-1

(note that there is a double underscore before GL_…, and replace DFP-1 with whatever nvidia-settings tells you the correct display name is). If you run a Vrui application from the same terminal window afterwards, it should look smooth. You can double-check by measuring a running Vrui application’s frame rate. While the mouse is on the Rift’s screen, press Win+Scroll Lock to enter “burn mode” (Vrui will print “Entering burn mode” to the terminal). Wait a few seconds, and press Win+Scroll Lock again to leave burn mode. Vrui will print the average frame rate and the minimum/maximum frame time range. The average frame rate should be close to 75 fps, and both ends of the frame time range should be close to 13.333 ms.

Using Vrui Applications in the Rift

As the Rift DK2 does not come with 6-DOF tracked input devices, Vrui’s default input setup uses the mouse for interaction (but see Figure 1 for alternative options). Once any Vrui application is started, move the mouse over to the Rift’s screen (usually to the right of your main screen), at which point a mouse cursor should show up in the Rift. As you move the mouse, you’ll notice it’s mapped to a spherical shell around you. Start another Vrui example program, the same virtual globe that greeted you earlier:

$ ShowEarthModel -noscale -norotate -rootSection RiftDK2

Move the mouse over to the Rift’s screen. You can rotate the globe by dragging with the left mouse button, or pan the globe in the virtual screen plane by dragging with the middle mouse button. You can zoom in or out either by dragging up/down with the left and middle mouse buttons together, or by rolling the scroll wheel.

Pressing and holding the right mouse button opens any Vrui application’s main menu. Here, you can change rendering modes, such as drawing the globe transparently or showing the mantle-core boundary, or reset the view through the “View” submenu of the Vrui system menu.

If you open a dialog window, say by selecting “Show Render Dialog” from the main menu, you can interact with it with the left mouse button. As you drag the dialog by its title bar, you’ll notice it’s also mapped to a spherical shell. To close a dialog, select the “X” button in its top-right corner. If you accidentally move a dialog out of reach, you can bring it underneath the mouse cursor by selecting the dialog’s name in the “Dialogs” submenu of the Vrui system menu.

For a more detailed introduction to Vrui’s mouse-based user interface, read “Using Vrui Applications” in Vrui’s online HTML documentation.

Watching Movies

Vrui has a bare-bones video player among its example programs. It’s based on the Xine engine, and can play complete DVDs or regular video files in a variety of formats. To use it, you first need to install the Xine engine and video player front-end and its codecs, and the libxine development library. This is left as an exercise for the reader.

After installing libxine, go to the source code directory for Vrui’s example programs, ~/src/Vrui-4.2-<release>/ExamplePrograms if you installed via the Build-*.sh scripts, and run:

$ make INSTALLDIR=/usr/local
$ sudo make INSTALLDIR=/usr/local install

This should now build the VruiXine application and install it into /usr/local/bin. Afterwards you can watch a DVD in the Rift via

$ VruiXine dvd:/ -rootSection RiftDK2

(playing encrypted DVDs requires the libdvdcss package), or a standard video file via

$ VruiXine <video file name> -rootSection RiftDK2

VruiXine is controlled through several dialog windows, which you can call up through the “Dialogs” submenu of Vrui’s system menu:

  • The “Stream Settings” dialog controls video format details, such as stereo modes and layouts and crop borders to mask out unwanted padding areas present in some video formats.
  • The “Screen Control” dialog lets you switch between different screen types (window, theater, half sphere, full sphere) and adjust each screen type’s settings.
  • The “DVD Navigation” dialog lets you navigate through DVD menus or chapters, has a volume slider on the right, and an “Eject” button to load a different video file.
  • The “Playback Control” dialog has a scrub bar to select the playback location, and buttons to skip forward and backwards in 10 second increments.

Before turning on stereo mode when watching stereoscopic video files, be sure to crop out any padding areas around the real video frame, usually indicated as green borders (these are due to some issue with Xine’s raw frame decoder, which I haven’t figured out yet). Drag the cropping sliders until all green pixels just disappear, and then round up all crop borders to the next larger even value (to correctly account for sub-sampled chroma planes). If you don’t crop out the padding areas, the left/right views in stereo videos will not line up correctly, and there will be pain.

VruiXine also offers several tool classes, under the “VruiXine” submenu of Vrui’s tool selection menu, that can be used to bind playback functions directly to input device buttons, such as keyboard keys or controller buttons, through Vrui’s standard tool binding mechanism. For example, to bind the pause function to the “p” key, press and hold “p”, which will pop up the tool selection menu, and move the mouse to highlight “Pause” in the “VruiXine” submenu (without pressing any mouse buttons, or letting go of the “p” key). Once there, let go of the “p” key. Afterwards, press “p” once to pause the current video, and press “p” again to resume playback.

VruiXine routes audio output through the default sound device. Use the desktop environment’s sound control panel to route audio to the appropriate speakers or headphones.

Fine-tuning Vrui

As said before, Vrui has many configuration options available through its main configuration file, /usr/local/etc/Vrui-4.2/Vrui.cfg. You can tweak Vrui either by directly editing that file, or by creating a personal “patch” configuration file, ~/.config/Vrui-4.2/Vrui.cfg. Any settings found in that file will be merged into Vrui’s configuration whenever a Vrui application starts. For example, to change the default background color from black to dark blue, you would create a Vrui.cfg with the following contents:

section Vrui
    section RiftDK2
        backgroundColor (0.0, 0.0, 0.25)
    endsection
endsection

One setting you might want to change early on is the position of your tracking camera. If you configure the actual elevation of your camera above your floor, then the real floor and virtual floor inside Vrui applications will line up. As this is a system setting, it’s best edited inside the main configuration file:

section Vrui
    ...
    section RiftDK2
        ...
        section OVRDAdapter
            ...
            cameraTransform translate (0.0, -39.37, 50.0) \
                            * rotate (1.0, 0.0, 0.0), 90.0
        endsection
       ...
    endsection
    ...
endsection

In this example, the third component of the translate vector, 50.0, is the camera’s elevation above the floor in inches. Adjust this to your actual camera height, and leave the rest of the values alone (the rotation at the end flips the coordinate system from Oculus’ standard of Y up to Vrui’s standard of Z up).

Configuring IPD and Eye Relief

With head-mounted VR, it is important to configure the headset to each user’s facial structure to reduce eye strain and avoid nausea. Here is a video of me talking about that in detail at this year’s VRLA Summer Expo: How VR Works: A Perceptual Point of View.

In Vrui, users viewing VR screens (either fixed or head-mounted ones) are represented as so-called “viewers,” which have two eyes defined as 3D points. This gives a large degree of flexibility for cases such as asymmetric eye positions, but in general configuration boils down to inter-pupillary distance (IPD) and eye relief, i.e., lens-eye distance.

To start, measure your IPD, for example using this method. Then create a new patch configuration file ~/.config/Vrui-4.2/Vrui.cfg, or edit an existing one, and insert the following sections and settings:

section Vrui
    section RiftDK2
        ...
        section HMDViewer
            # Eye positions depend on eye relief and viewer's IPD
            monoEyePosition (0.0, -2.2, 0.0)
            leftEyePosition (-1.25, -2.2, 0.0)
            rightEyePosition (1.25, -2.2, 0.0)
        endsection
        ...
    endsection
endsection

The numbers are in inches. As you can see, IPD is currently configured to 2.5″ (1.25″-(-1.25″)), and eye relief is configured to 0.9″: the pupils are positioned 2.2″ in front of the headset’s screen plane, and the lens-screen distance in the Rift DK2 is 1.3″. Adjust these settings to your parameters (or liking), and finally set the mono eye position to be the center between the left and right eyes.

Given that eye relief is very hard to measure, you might have to experiment with values until you get the field of view just right. You can test this by putting on the headset and looking around inside a larger virtual space; eye relief is correct when the environment appears stable, and no longer “warps” as you rotate your head left and right.

To simplify this iterative setup step, Vrui contains an in-application viewer configuration utility. To load it, append “-vislet ViewerConfiguration” (without quotes) to an application’s command line. In Vrui, vislets are small independent components that can be loaded into any Vrui applications.

Once started, go to the “Vislet” submenu of Vrui’s system menu, and select the “Viewer Configuration” vislet. This will open a dialog window with three sets of sliders. The first set adjusts the position of the “mono eye” in 3D, and has an explicit IPD slider. This is for the general symmetric case. In addition, there are two sets of sliders to set the left and right eye positions independently. You should only use these if you know your face is asymmetric, or if you can’t get a good configuration from the first slider set. Once you’ve found a good set of numbers, note them and enter them into the patch configuration file to make them permanent.

By default, units in the viewer configuration vislet are in Vrui physical units, which happen to be inches for the Rift DK2. You can change this via your patch configuration file. Insert a new section into the existing structure like this:

section Vrui
    section RiftDK2
        ...
        section Vislets
            section ViewerConfiguration
                unitName mm
                unitScale 1.0
            endsection
        endsection
    endsection
endsection

Now all positions and distances will be shown in millimeters.

Further Directions

After this basic installation, there are many places to go. You can install external 6-DOF tracked devices such as Razer Hydra controllers for an improved 3D user interface, or connect joysticks or gamepads. You can set up multiple windows, to be able to use a VR application in VR mode and desktop mode simultaneously, potentially by multiple people, for asymmetric collaboration. Or you can set up a mixed-reality capture system using a 3D camera like a Microsoft Kinect. Or you can install additional Vrui applications such as 3D Visualizer or LiDAR Viewer. Or you can start developing your own applications using the Vrui toolkit.

We’ll talk about all that later.

12 thoughts on “Vrui on Oculus Rift DK2

  1. This is great news! Does this mean Vrui is now combining the camera and IMU tracking using eg. a Kalman filter?

    Time to undust our DK2!

  2. Got spinning earth on my Linux box. Cool!

    … but don’t have DK2, but do have PSVR which I’m helping hack. How can I get full screen side-by-side stereoscopic for testing?

    Distortion characteristic somewhat like:
    https://github.com/gusmanb/PSVRFramework/issues/27

    End goal is tracking through PSMoveService, but that’s a little way off. We’re closer to ‘just’ orientation tracking with PSVRframework.

    • Are you asking how to render side-by-side stereo to your PSVR’s screen using Vrui?

      That’s easy; you need to know the screen’s resolution (1920×1080), and its position on your extended desktop, or the display name for the PSVR as used by Xrandr. To get around lack of tracking, you need to set up a “fake” tracking driver.

      Grab the newest Vrui-4.2-005 from my download site, and install it. There is a FakeHMD.cfg configuration file in /usr/local/etc/Vrui-4.2 which does that already, for Vive or Rift DK2. You can run a Rift DK2 faker like so:

      $ <Vrui application name> -rootSection RiftDK2 -mergeConfig FakeHMD

      To adapt it for PSVR, adjust the window position of HMDWindow, and then play with the distortion formulas.

      You can use the auto screen finder, too: in the HMDWindow section, there’s an empty outputName tag. Put a random string in there, and run the above command line with -vruiVerbose appended. That will list the names of all video outputs on your X server. Find the output or monitor name that looks like it could be the PSVR, and paste it after the outputName tag. Then set windowSize to (1920, 1080) and decorate to false, or windowFullscreen to true.

    • FYI just tried it, no luck.

      could get right the way up to the show eye test, but the HMD just shows a black screen, the camera light is on, and the HMD backlight is on, just no picture. moved my head around to see if it was tracking no luck.

      First terminal output:

      ovrd
      OVR::DeviceManagerThread – running (ThreadId=0x7fdb8a384700).
      OVR::DeviceManager – initialized.
      CameraFactory starts
      [TrackingManager] Entering tracking thread
      OVR::Linux::HIDDevice – Opened ‘/dev/hidraw4′
      Manufacturer:’Oculus VR, Inc.’ Product:’Rift DK2′ Serial#:’MSCE47R6K9DAKZ00T000′
      OVR::SensorDevice – Closed ‘/dev/hidraw4’
      OVR::Linux::HIDDevice – HID Device Closed ‘/dev/hidraw4’
      OVR::Linux::HIDDevice – HIDShutdown ‘/dev/hidraw4’
      [TrackingManager] Broadcasting new HMD count = 0
      CameraFactory::inspectCamera starts
      CameraDK2::Initialize starts
      CameraDK2::Initialize: sending GET_CUR
      IOCTL_OCUSBVID_EXECUTE_VIDEO_STREAMING_REQUEST probe GET_CUR succeeded
      PROBE SET_CUR to fmt 1 frm 1 int 166666 frmsiz 360960 xfersize 3000
      IOCTL_OCUSBVID_EXECUTE_VIDEO_STREAMING_REQUEST probe SET_CUR succeeded
      COMMIT SET_CUR to fmt 1 frm 1 int 166666 frmsiz 360960 xfersize 3000
      IOCTL_OCUSBVID_EXECUTE_VIDEO_STREAMING_REQUEST commit SET_CUR succeeded
      OVR::Linux::HIDDevice – Opened ‘/dev/hidraw4′
      Manufacturer:’Oculus VR, Inc.’ Product:’Rift DK2′ Serial#:’MSCE47R6K9DAKZ00T000′
      [TrackingManager] Broadcasting new HMD count = 1
      CameraFactory::inspectCamera ends successfully
      [ExternalCamera] Skipped 10 frames
      Reconstruct: Too much error 0.00286/0.001
      [TrackedHMD] Past frame reconstruction failed
      Reconstruct: Too much error 0.00273/0.001
      [TrackedHMD] Past frame reconstruction failed
      Reconstruct: Too much error 0.00273/0.001
      [TrackedHMD] Past frame reconstruction failed
      Reconstruct: Too much error 0.00273/0.001
      [TrackedHMD] Past frame reconstruction failed
      Reconstruct: Too much error 0.0013/0.001
      [TrackedHMD] Past frame reconstruction failed
      Reconstruct: Too much error 0.00112/0.001
      [TrackedHMD] Past frame reconstruction failed

      Second terminal output:

      VisionTest -rootSection RiftDK2
      Vrui: Unable to inhibit screen saver due to exception Vrui::ScreenSaverInhibitorDBus: Unable to inhibit screen saver
      240, 0.349066

      • I haven’t run into that before. It looks like ovrd is not posting any tracking data due to 3D reconstruction error being too high, but also not throwing an error.

        As a result, Vrui will not get any head position data, and render from whatever the initial head position was, which is most probably off in outer space. Hence the black screen. If you tried another Vrui application that surrounds you with 3D data, such as the Quake III viewer, you should see something, but the 3D environment will be locked to your head.

    • I’m not sure what you’re asking, but the answer is probably no. The relationships are as follows:

      • Vrui works with HTC Vive, using OpenVR’s Lighthouse tracking driver plug-in.
      • Vrui works with Oculus Rift DK2, using Oculus’ ovrd tracking driver.

      Meaning, the common ground here is Vrui, not Steam/SteamVR.

      • I was under the impression that the Vive controllers communicate directly with the Vive HMD. Do you have this HMD connected to the computer as well to make get this setup to work? (I believe I see it on the left in the picture actually)

        BTW, thanks for all your great posts. They’re very informative and thorough!

        • Yes, correct on both counts. There are separate radios to connect additional controllers (basically Steam controller dongles with replaced firmware), and I have two of them from my Vive DK1, but I haven’t yet tried whether I can get the tracking driver to work without a headset connected. It might work.

Please leave a reply!