VRTrack 1.0 – headtracking driver for the vr920 HMD
As I promised in New version of the vr920 headtracking driver coming soon here is the new version of my headtracking driver for the Vuzix VR920 iwear for Linux. It calculates yaw, pitch and roll from the accelerometer and magnetometer data (The device has got three of each). This makes a 3DOF tracking possible and allows you to look around in a 3D Scene. In example you can use the driver with my stereoscopic image viewer SIV. The driver averages the sensor readings with an improved algorithm, which gives a far smoother experience than with the initial driver version. The driver package consists of a daemon which can be run in the background and for convenience a basic control application that enables one to easily tweak the various driver settings and to callibrate the device. For general Information on how to use the device with Linux see: Vuzix VR920 with Linux and active 3D stereo.
The driver provides the trackingdata in different formats to the application using it. It always writes the data to /dev/headtracking. A line read from /dev/vrtrack consists of six floats that correspond a sensor reading in this format:
yaw pitch roll x y z
Yaw, pitch and roll are angles from 0 to 360 degrees. X, y and z are always zero for the vr920, since it only supports three degrees of freedom. These values are reserved for future devices which may support six degrees of freedom, in the hope to propose a standard for tracking devices.
The driver can scale the readings and invert the axes independantly to get the needed value range for the used application and a pleasant experience.
For maximum compatibility with existing applications there are four other modes of operation available that can be enabled separately:
- Joystick emulation
The driver emulates a joystick device /dev/input/jsX. The readings for yaw, pitch and roll are the X,Y and Z axis of the emulated joystick. This may be used to enable basic headtracking support in games that do not natively support headtracking.
- Mouse emulation
The driver emulates a joystick device /dev/input/mouseX. The readings for yaw and pitch are being translated to X and Y of the mouse device, so when you look right the mouse pointer moves to the right and when you look up the pointer moves upwards and vice versa. This may also be used to enable basic headtracking support in games that do not natively support headtracking. It can also be used to just control the mouse pointer of the window system. Controlling the viewport of the window system can also be a resonable purpose. With the new MPX extension in xorg this may be possible.
- UDP – network
In UDP mode the driver sends the tracking data via network as UDP unicast. The approach to send the data out via network makes the language used for writing the application independant from the language used for developing the driver. The packet sent to the clients contains the three angles, yaw, pitch and roll and x,y and z as 32 bit fixed point in Q16.16 format. This mode may i.e. used to control flightgear.
- Multicast – network
In multicast mode the driver sends the tracking data via network as UDP multicast, thus many clients may read the data, which makes parallelization more possible, i.e. one could use one machine for rendering and another machine for calculations. In addition to this, the approach to send the data out via network makes the language used for writing the application independant from the language used for developing the driver. The tracking data sent to the clients contains the three angles, yaw, pitch and roll and for easy usage a viewmatrix, one can directly use with scenegraph libraries. If you intend to develop an application using the headtracking of the VR920 see the file democlient.cpp included in the download for details on how to get the data into your application. This mode is used by the stereoscopic image viewer SIV.
Important note: During calibration make sure that the display of the device is displaying something. Since the displays not only showing a blue screen influences the sensor data (at least with my device) you’ll end with wrong calibration else. You may use i.e. nvidia-settings to ensure this. For detailed usage instructions see the readme included in the download.
I decided to publish the driver under the creative common noncommercial license. You may download the full source from here: vr920-driver(source) (5101 downloads ) , an x86_64 binary from here: vr920-driver(x86_64 binary) (4479 downloads ) , or an i686 binary from here: vr920-driver(i686 binary) (4655 downloads ) . An Archlinux PKGBUILD provided by Feilen is available here: aur.archlinux.org More binary/distribution specific formats may be available in the future. The x86_64 binary has been build on an up to date gentoo system, the i686 binary on ubuntu hardy. For the i686 binary you may install libconfig++ i.e. libconfig++8_1.3.2-2 from here: libconfig++ If none of the binaries works for you, you may have to build from source…
You need to have libusb, libconfig++, libfuse and libcurses installed on your system. For ubuntu users I included the small shell script ubuntu_install_deps.sh that installs the dependencies. Maybe it works also for for other Debian-based distributions. Gentoo users just have to make sure that libusb, ncurses, fuse, and libconfig have been emerged. Your kernel version has to be at least 2.6.31 and you must have cuse enabled in your kernel.
Footnote:
If you like the driver, feel free to link to www.mygnu.de. If you developed an application using the tracking data provided by the driver please leave a comment, because then I can review the application and eventually write about it. To request commercial licenses contact us at info(at)mygnu.de. Well, if you just want to support our work on MyGNU.de use the donate button 😉
best regards
Jürgen
March 3rd, 2011 at 12:50 am
[…] New version available here. […]
April 20th, 2011 at 5:43 am
My Development Environment is “ubuntu10.10”.I’ve downloaded “vrtrack-1.0-x86.tar.gz(106)”.I wanted to be headtracking by VR920.
But,I didn’t use “vrtrack” in the gz file.How to use it?Please teach me it!
April 20th, 2011 at 8:35 am
Hi zebi,
did you unpack the archive (tar -xzf vrtrack-1.0-x86.tar.gz)? For Ubuntu I included a small script (ubuntu_install_deps.sh) that installs the dependencies. Run this script as root. Afterwards just start the vrtrack executeable at the console (probably you need to be root to do this (rw access to /dev/cuse). If you start vrtrack in the foreground (vrtrack -f) you can read the console output. Then start vrcontrol for callibration. For details on the usage read the README.txt file included in the archive.
If you have got further problems, please do not hesitate to write again. In this case please include the problematic parts of the console output.
mithrandir
April 21st, 2011 at 6:54 am
Thank you, Could start!
By the way,Is this the driver can also get another angle of the magnetic data?
April 26th, 2011 at 4:29 pm
Sorry for the late reply, I have been away for the easter days. The driver uses the accelerometer data for pitch and roll and the magnetometer data for yaw. Or do you mean something different by “another angle of the magnetic data” ?
mithrandir
January 8th, 2012 at 4:26 pm
Hi. Do you reckon it’s possible to run this with the newer Wrap920 (considering it has similar inputs)?
I’ve tried using both your old and new driver with a Wrap920, a later version of the goggles. I changed the product id (0x002 becomes 0x014b) in the old driver’s source. This let me run the program and find the device but didn’t show any actual readings (0 everywhere). The later version runs on my system, but I can’t compile from source: it complains that
vrtrack.cpp:158:2: error: expected primary-expression before ‘struct’
vrtrack.cpp:158:2: error: ‘offsetof’ was not declared in this scope
and so on, which seems to have something tro do with fuse or cuse.
How can I enable cuse in my kernel (to compile the newer version)?
What changes apart from product id are needed in the source to fit this to the newer goggles?
My life is in your hands, mithrandir
January 8th, 2012 at 5:18 pm
Hi Alex,
the Wrap920 has a six degree of freedom head tracking, the VR920 only has three degrees of freedom. Thus I expect the device not to use the same data as the vr920. So just changing the the USB id will most likely not work. If it worked you could only get three degrees of freedom.
On my system I can compile the driver with fuse-2.8.6 without errors. I could try to compile your modified source, to see if I also get the error. Just attach the file to an e-mail and send it to the address in the impress or the one in the drivers source. Since you get readings, I assume you have /dev/vrcontrol and /dev/vrtrack. Thus cuse is enabled in your kernel.
To extend the driver for other devices I would need some technical specification (or reverse engineer the USB protocol) and a device to test. As you can see from the source of the newer driver I already prepared the data structures for six degrees of freedom, but was not able o continue due to the lack of a vusix device with the newer headtracking hardware. Sadly I do not own any other Vusix device than the VR920, and Vusix refused to support my driver development. They claim to assist in linux development on their homepage, but this is entirely wrong. They never supported my development in any way. So there is not much more I can do to help you with getting the device to work, unless Vusix changes its policy.
Sorry
mithrandir
January 18th, 2012 at 3:28 pm
Hi Alex,
I had quite the same problem, when trying to run the recent tracker module with the driver.
A made the following changes:
– Changed product id from 0x002 to 0x014b
– Changed the function call to read from the device:
ret = usb_interrupt_read(devh, 0x00000083, buf, 0x000002a, 1000);
Here it seams that the size of the message has changed.
– Added #include “stddef.h” to vrtrack.cpp
– Added -lfuse to the g++ call in Makefile:
g++ -Wall `pkg-config fuse –cflags –libs` -O2 -o $@ vrtrack.cpp -lpthread -lconfig++ -lusb -lfuse
With this changes the driver is compiling and running.
Unfortunately the data provided by the new tracker seams to differ from the old data. I did not figure out where to find which value. I just fond some correlation:
At offset 20, 22 and 24 (and also at 14, 16, and 18) I found some shorts that correlate with the angular velocity.
Hope I could help you.
imere
February 22nd, 2012 at 7:56 pm
Hi mithrandir, imere and alex, I ‘ve got myself a vuzix wrap 920 googles, and I’m also trying to understand how to obtain the acelerometer, magnetometer and gyro information from it.
The glasses are binded to /dev/hidrawX, and as imere mentioned you have to read 42 bytes (0x2a) instead of the 16 bytes (0x10) of the old vr920, here goes a hexdump from /dev/hidrawX
(hexdump -e ‘2/1 “%02x ” 12/2 ” %2d ” 16/1 ” %02x” “\n”‘ < /dev/hidraw2 )
01 80 -326 221 59 -213 -56 1020 18 -31 23 39 -84 76 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -326 221 59 -220 -50 1021 22 -36 21 36 -89 68 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -326 221 59 -220 -50 1021 22 -35 28 43 -88 76 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -326 221 59 -220 -50 1021 18 -33 22 37 -87 70 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -326 221 59 -220 -50 1021 23 -37 28 37 -90 75 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
note that all lines start with 01 80, and end with 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a, the structure goes like this:
1) 2 constant bytes 01 80
2) 12 integer (2bytes each)
3) 16 constant bytes
I was expecting 9 values (3x devices) instead of 12, hope you can comment on this
cheers
February 22nd, 2012 at 7:57 pm
a bit longer hexdump, so you can see which of these bytes are constant,
01 80 -332 218 51 -250 -53 1008 17 -33 26 39 -89 78 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -332 218 51 -250 -53 1008 20 -34 25 37 -91 77 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -332 218 51 -256 -58 1004 19 -35 28 38 -87 76 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -332 218 51 -256 -58 1004 21 -34 28 36 -81 76 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -332 218 51 -256 -58 1004 22 -36 25 38 -90 73 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -335 224 60 -256 -58 1004 21 -35 26 35 -82 74 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -335 224 60 -256 -58 1004 20 -32 27 39 -82 80 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -335 224 60 -256 -58 1004 23 -34 25 40 -83 76 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -335 224 60 -256 -58 1004 25 -36 29 45 -83 78 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -335 224 60 -237 -40 987 23 -32 27 44 -78 76 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
01 80 -335 224 60 -237 -40 987 18 -27 26 35 -68 79 9b 66 d6 30 fc fb 39 75 21 ae 82 c5 66 20 4a 4a
February 22nd, 2012 at 8:40 pm
Hi mithrandir, I would like to know how did you obtained these relations for the vr920:
acc.x = double(*(short*) (buf + 2));
acc.z = double(*(short*) (buf + 4));
acc.y = double(*(short*) (buf + 6));
mag.y = -double(*(short*) (buf + 8));
mag.z = -double(*(short*) (buf + 10));
mag.x = -double(*(short*) (buf + 12));
February 22nd, 2012 at 11:36 pm
Hi phuijse,
the major question is how the values change when you move the device. This way you can locate the values for the different axes. As far as I know the device has 6 degrees of freedom. Thus I would expect at least 6 values. 3 for rotation (yaw, pitch, roll) and 3 for translation. If all these values are of short type, this would make 12 int values. The VR920 had 3 values for the magnetometer (yaw) where one value is enough for this. This 3 values were necessary to compensate the influence of pitch and roll on the readings of the magnetometer in software. Assuming that this is now being done in hardware (this assumption bases upon the fact, that you only have 6 (12) values and the assumption, that still the short type is being used), the implementation for this device may be much easier than for the VR920.
To summarize, 6 readings are enough for 6DOF. Most probably the 12 int values you have got are 6 short values. Just try out how the values change when you rotate and translate the device. But since I cannot try it out this are just assumptions.
mith
March 14th, 2012 at 8:44 am
Hi,
the values seem to be 12×16-bit in this order: 3x magnetometer, 3x accelerometer, 3x low-sensitivity gyro, 3x high-sensitivity gyro.
The reading and real-time graphing code to read this is available here: https://github.com/HairyFotr/WrapReader
Check the graphs/ folder for some images and datasets.
March 17th, 2012 at 6:27 pm
This driver needs this patch in order to compile in Linux Ubunto:
diff -u vrtrack-1.0/Makefile vrtrack-1.0-yoda/Makefile
— vrtrack-1.0/Makefile 2011-03-01 02:23:32.000000000 +0000
+++ vrtrack-1.0-yoda/Makefile 2012-03-17 16:04:03.200921990 +0000
@@ -3,7 +3,7 @@
all : vrtrack vrcontrol multicastdemoclient JavaDemoClient
vrtrack : vrtrack.cpp
– g++ -Wall `pkg-config fuse –cflags –libs` -O2 -o $@ vrtrack.cpp -lpthread -lconfig++ -lusb
+ g++ -Wall `pkg-config fuse –cflags` -O2 -o $@ vrtrack.cpp `pkg-config fuse –libs` -lpthread -lconfig++ -lusb
vrcontrol : vrcontrol.cpp
g++ -O2 -o $@ vrcontrol.cpp -lcurses
diff -u vrtrack-1.0/vrtrack.cpp vrtrack-1.0-yoda/vrtrack.cpp
— vrtrack-1.0/vrtrack.cpp 2011-03-02 05:27:03.000000000 +0000
+++ vrtrack-1.0-yoda/vrtrack.cpp 2012-03-17 16:02:07.196919343 +0000
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include
#include
Rodrigo Ventura
ISR/IST
April 1st, 2012 at 1:09 pm
Guys,
I appreciate your effort on developing a Linux driver for wrap 920AR. I was wondering if there is any progress on that. Because I need to buy iWear VR920 or Wrap 920VR Bundle based on the availability of the linux (Ubuntu) driver.
Another thing is if we can team up, we may even work on developing this driver together. What do you think ?
Cheers
April 1st, 2012 at 1:18 pm
HairyFotr and Rodrigo,
You seem to be successful at streaming the 6DOF data in, so you already did what I’ve just suggested 🙂
My question is that are you satisfied with the raw data, have you ever tried to control a viewpoint in the virtual environment based on this data?
Thanks in advance
May 14th, 2012 at 12:42 pm
I want to continue from my last comment (http://www.mygnu.de/index.php/2009/03/vr920-headtracking-driver-for-linux/#comment-4088) here, because it is about this vrtrack software.
After changing the vendor und product ID to WRAP920/WRAP1200 this software works! 🙂
I am reading the buffer directly after recieving:
ret = usb_interrupt_read(devh, 0x00000083, buf, 0x0000020, 1000);
// Print out the returned buffer.
printf(“Data read:\n “);
for (int i = 0; i < ret; i++)
printf("%02hhx ", buf[i]);
printf("\n");
It is reading continuously but always prints out /reads the same values! Not matter if I move the goggles. If I swtich off and on the goggles and change the position, it is reading another value, but as well always the same.
Here is a log: http://nopaste.info/630579cb48.html
I dont know what is "cuse" for, but does it have something todo with cuse? Do I have to send to the goggles before reading?
May 14th, 2012 at 7:40 pm
Hi fabske,
as far as I know there are differences between the headtracking devices in the VR920 an the Wrap models. So it may be possible, that one has to send something to the device for the next reading. This has not been necessary with the VR920.
The /dev/cuse is for the userspace (the driver is in userspace) character device. If you do not have permissions for the device , the driver fails in creating the devices /dev/vrtrack and /dev/vrcontrol. From the first the tracking data can be read (besides from the other possibilities to read the data, UDP, mouse/joystick device, etc.). The second is for configuring and calibrating the driver. Thus I suggest to give the user running the driver permissions for /dev/cuse or to run the driver as root user. Please try this out and report afterwards if the behavior has changed. Since you print the buffer directly after reading, there should not be any connection, but at least it prevents the calibration tool from working.
Could you please print the return value of usb_interrupt_read? It contains the number of bytes read from the device. If nothing is returned from the device (zero or negative value), the buffer contains random memory values, that do not change once the driver has been started. Please include the device readings/data amount in the log.
After all the USB errors in your log do not look promising, I can not remember to have seen them with the VR920. So most probably the communication with the device has to be a bit different.
Jürgen
May 16th, 2012 at 4:23 pm
The driver is successfully reading from the device. Here you have a complete log: http://nopaste.info/2ec374dff8.html
I am turning around the goggles while reading, but I all the time get the same values 🙁
June 10th, 2014 at 6:23 pm
Hello,
I just came across your driver today. I noticed that you released it under the Creative Commons – Non-commercial license. I was wondering if you might be willing to relicense and or dual license your work under a different license, perhaps the GPL, AGPL, or Apache license. The problem is, that Debian does not allow things distributed under CC-By-Nc http://wiki.creativecommons.org/Version_3#Debian and I would love to see this become an actually supported device.
Thanks in advance,
Tim
February 23rd, 2015 at 3:45 pm
Sorry for the late answer, there will be a new release of the driver this will be under the GPL.
mith