Virtual Reality development on the Raspberry Pi, in Python.
Status: *** Experimental ***
A (hopefully) frictionless way to get started creating your own virtual reality worlds in Python on a Raspberry Pi with an Oculus Rift.
VR Zero adds a number of features on top of pi3d and solves the headaches of configuring a Pi 3 for VR development in Python.
VR Zero includes:
- Default input event handling for Keyboard, Mouse, Joypad and the Rift for moving and altering the view of the player avatar.
- Known good HDMI configuration settings for the Oculus Rift DK1 and DK2.
- An OpenHMD Debian package, OpenHMD is used to read the rotational sensor reading from the Rift.
- Python bindings for the native OpenHMD library with supporting udev config for non-root access to USB device
- An OpenGL ES barrel shader for correcting lens distortion (as can be found in official Oculus SDK's)
- XBox Joypad configuration.
- A handful of VR demos (screenshots and a video of the demos can be found below).
VR Zero is for fun and learning, so don't expect huge gaming PC like frame rates, some of the demos peak at around 25-30 FPS on a Pi 3.
The API will in no doubt change, boiler plate code may lessen, faster Pi hardware will be released and HMD's will get cheaper... (hopefully) :)
Below is some example bare-bones code:
from vrzero import engine import pi3d engine.init() # ... # Do your pi3d setup for: shaders, environment cubes, sprites, textures, models etc # ... def update(): # Do your Pi3D scene state updates only here def draw(): # Do your Pi3D drawing # This function get's called twice, once for each eye in a single frame # don't do scene state udates here. engine.on_update = update engine.on_render = draw engine.start()
The complete code of a fully functioning demo, the Pi Tea Pot, is include inline in the Demo section below.
A central feature of VR Zero is the player avatar, which is made up of a 'body' and a 'head'.
The body is moved in response to certain keyboard, joypad and mouse events. The head is moved in response to certain joypad, mouse and headm mounted display (HMD) events from the Rift.
Essentially, controlling the player avatar feels just like playing a first person shooter.
The body can be positioned using the vrzero API.
VR zero setups sensible defaults for handling the input events from attached devices.
The keyboards controls movement, the default mappings are the classic: WSAD, SPACE for 'jump' and ENTER for 'action'.
The mouse controls looking (and direction of travel when moving). Mouse button 1 is 'action' and mouse button 2 is 'jump'.
An Xbox controller controls movement and view using the left and right stick respectively. The 'A' button is 'action' and the 'B' button is jump.
Head Mounted Display
The OpenHMD library is used to read the HMD sensor data. VR Zero automatically rotates the pi3d Steroscopic camera in response to HMD readings.
Please see the demos below for how to control the player avatar programatically, for example, demos/forest.py shows how to correctly set the players avatar's Y position when using a height field for terrain.
Although a single apt-get install would be nice, it's currently a bit of a stretch. But once all parts are installed (ideally onto a fresh Raspbian Jessie, tested with 2016-05-27), then it's happy days from there.
Install the package dependencies:
sudo apt-get update sudo apt-get install -y libhidapi-libusb0 xboxdrv sudo pip3 install pi3d==2.14
Clone and install VR Zero along with a pre-made OpenHMD Debian package:
git clone https://github.com/WayneKeenan/python-vrzero cd python-vrzero sudo python3 setup.py install sudo dpkg -i install/openhmd_0.0.1-1_armhf.deb sudo apt-get install -f sudo ldconfig
Settings for: root-less USB (HMD) access and and XBox Joypad:
sudo cp config/83-hmd.rules /etc/udev/rules.d/ sudo cp config/xboxdrv.init /etc/init.d/xboxdrv sudo cp config/xboxdrv.defaults /etc/default/xboxdrv
If have a Rift DK1 or you want to test using a HDMI monitor then run:
sudo cp config/config_DK1.txt /boot/config.txt
If you have a Rift DK2 then run:
sudo cp config/config_DK2.txt /boot/config.txt
Run these commands, the first enables the root-less USB udev config setup earlier and the 2nd command disables BluetoothLE, which is currently needed to stop OpenGL ES hanging:
sudo udevadm control --reload-rules sudo systemctl disable hciuart
The demos need to be run using Python 3 and can be executed as script from the
demos folder, e.g.:
cd python-vrzero/demos ./abbey.py
All of the demos, other than the Minecraft inspired demos/blockworld.py, are ports of standard Pi3D demos to VR Zero.
The complete source of the Tea Pot demo is extremely small, so it's replicated below:
Below is the minimal code for this Teapot demo.
Note that all camera movement (user input) and stereoscopic rendering with len distortion correction is taken care for you. You can move and look around with any attached keyboard (move only), mouse (look only), joypad (move + look) and HMD (look only)
from vrzero import engine import pi3d engine.init() shader = pi3d.Shader("uv_reflect") flat_shader = pi3d.Shader("uv_flat") ectex = pi3d.loadECfiles("textures/ecubes","sbox") myecube = pi3d.EnvironmentCube(size=900.0, maptype="FACES", name="bfa", y=50.0) myecube.set_draw_details(flat_shader, ectex) pi3d.opengles.glDisable(pi3d.GL_CULL_FACE) # load bump and reflection textures bumptex = pi3d.Texture("textures/floor_nm.jpg") shinetex = pi3d.Texture("textures/stars.jpg") # load model mymodel = pi3d.Model(file_string='models/teapot.obj', name='teapot', y=5.0, z=10.0) mymodel.set_shader(shader) mymodel.set_normal_shine(bumptex, 16.0, shinetex, 0.5) def update(): mymodel.rotateIncY(0.41) mymodel.rotateIncZ(0.12) mymodel.rotateIncX(0.23) def draw(): myecube.draw() mymodel.draw() engine.on_update = update engine.on_render = draw engine.start()
Demos - Video
You can see the demos in action on YouTube here:
- pi3d developers
- pygame developers
- OpenHMD developers
- Xbox controller driver developers
- RaspberryPi forum users
In principle VR HMD's other than the Rift can be supported, thanks to the device agnostic OpenHMD.
Also, a Pi3 with a connected Rift and XBox 360 dongle can run 'untethered' (i.e. portable, not chained to a desk) using a single USB battery pack such as this one
Interestingly, as both pi3d and OpenHMD support Android then a port of VR Zero to Android is probably doable.