Virtual Reality
So, for my Build 18 project this year, my partner Alex and I wanted to do something cool and awesome. I had a few ideas floating around, and I had seen Nirav Patel's post on the subject of virtual reality gaming with the PNI SpacePoint Fusion. Alex thought it was a good idea, and so we ran with it. As it turns out, PNI has a nice student sponsorship program if you get in touch with the right people, and they were willing to send me their USB version of the SpacePoint Fusion (a discontinued product?!) as long as I did a writeup about it! So, here goes
Tutorial Notes
Components Needed
Nirav's original design only called for one SpacePoint Fusion and a nifty portable projector that went on top of his Wii Zapper. I personally wanted to see if we could get away with both head and gun inputs and couple that with a head-mounted display.
SpacePoint Fusion by PNI Corporation: Apparently has best 1:1 orientation information out there! They recently discontinued the USB version, but you might be able to get an old one if you ask nicely enough.
Wii Remote (Wiimote)
Don't skimp on quality! I bought a Chinese knockoff on eBay (that included a nunchunk and sheath for $18) that seemed to work fine on a Wii, but NEVER WORKED VIA BLUETOOTH ON A COMPUTER!. When it's only a buck or two more, just go for the real one! (this applies to more than just gaming products)
I got one “used” on Amazon (for $12 plus shipping), and it looks/feels better than the “new” one that I got from China…
Display (HMD, or projector)
Video quality is not great on a budget (640×480 for ~$250). But, it's a ton cooler to have your screen stay with you as you move around
Setting up the Software
Nirav used Ubuntu, but I took the long and frustrated route of seeing if it worked in OS X as well (see the FAQ's for more info). Long story short, it didn't work, and developing in Ubuntu ended up being a much faster process!
Compile Cube and LibHID
#Allow all dependencies to be installed as well. Installs SDL & dependencies, OpenGL, Zlib, libpng
sudo apt-get install g++ libusb-dev libsdl1.2-dev libsdl-sound1.2-dev libsdl-mixer1.2-dev libsdl-image1.2-dev libenet-dev
Also, you need to install libhid from source (the Ubuntu package didn't work for me). Download from
here
cd ~/Downloads
tar .zxvf libhid-0.2.--.tar.gz
cd libhid-0.2.--
./configure
make
sudo make install
#Add -fpermissive to the end
CXXOPTFLAGS=-Wall -O3 -fsigned-char -fomit-frame-pointer -fpermissive
Modifying Cube Source Code
Set udev rules
On first start, I got a bunch of errors from libhid about not seeing the SpacePoint unless I ran the process using sudo. After reading Nirav's tutorial again, I saw his note on the end about setting the udev rules correctly.
On most modern Linux distros, you can fix this by setting a udev rule for the device. In Ubuntu Karmic Koala, saving the following as /etc/udev/rules.d/45-spacepoint.rules , running sudo service udev restart , and then unplugging and replugging in the device should fix it:
# PNI SpacePoint Fusion
SYSFS{idVendor}=="20ff", SYSFS{idProduct}=="0100", MODE="0664", GROUP="admin"
Set up Wii Remote
All this does is map buttons on the Wii Remote to buttons on the keyboard
-
-
Create a config file located in /etc/cwiid/wminput
To run this file below:
sudo wminput -c fps_config2
- fps_config2
# Fps config for wminput by kyrlian
# needs plugin nunchuk_kb
#File is located
#custom buttons
Wiimote.A = KEY_ENTER
Wiimote.B = BTN_LEFT
Wiimote.Up = KEY_UP
Wiimote.Down = KEY_DOWN
Wiimote.Left = KEY_LEFT
Wiimote.Right = KEY_RIGHT
Wiimote.Minus = KEY_PAGEDOWN
Wiimote.Plus = KEY_PAGEUP
Wiimote.Home = KEY_ESC
Wiimote.1 = KEY_TAB
Wiimote.2 = KEY_ESC
Nunchuk.C = KEY_SEMICOLON
Nunchuk.Z = KEY_SPACE
#plugin for nunchuk stick
Plugin.nunchuk_kb.Up = KEY_UP
Plugin.nunchuk_kb.Down = KEY_DOWN
Plugin.nunchuk_kb.Left = KEY_LEFT
Plugin.nunchuk_kb.Right = KEY_RIGHT
FAQ's
Can't you get this working with more modern games?
Your game needs to have direct inputs for yaw, pitch, and ideally roll for both the camera and the gun in order to get this working right! Trust me, mapping YPR to relative knob/mouse/WASD inputs is not the way you want to go. I suspect that most games have this sort of functionality available, it's just not as well documented because people don't want to mod the camera view that often.
Strafing using a knob is so 20th century! Why can't I walk around my room and have the SpacePoint figure out where I've moved?
Oh, it'll happen someday. In the meantime, a good buzzword is “dead reckoning”
Wikipedia,
robotics tutorial and “Kalman filters”, both of which are very difficult mathematical problems. In this case, the SpacePoint Fusion allows you to acquire the raw accelerometer, gyroscope, and magnemometer data for doing your own tinkering, but their Kalman filters for deriving orientation data is likely very patented or kept a trade secret…and that's just for orientation! Deriving relative motion is much more complex using just motion data, which is why a lot of robotics platforms use encoders and they still aren't that accurate. :)
Won't this work on multiple platforms?
Yes, but library support varies. Libraries in Linux tend to be the most simplest to interface with and often free to use. I couldn't get libhid to compile on
OS X in the limited time that I had, but it'd probably work if I tried hard enough. You could also make this work using libusb, but you'll have to write your own code for that. Also, Wiimote plugins for
OS X were feature-limited (>.<) and never seemed to let me tweak it as I wanted to. In Ubuntu it's as simple as a text file with CWiid. If you do want to port this to other platforms, it can be done, and I wish you the best of luck! Write me a comment on the blog post and let me know how it went!
Extensions
Finally found a tutorial for using this with Source (Valve's engine for games like TF2, Portal, etc)!
Head Tracking
Future Ideas
AR Markers