├── FreeIMU_yaw_pitch_roll └── FreeIMU_yaw_pitch_roll.ino ├── FreePIE Script └── FreeIMU Headtracking.py └── README.md /FreeIMU_yaw_pitch_roll/FreeIMU_yaw_pitch_roll.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | //#define DEBUG 11 | #include "DebugUtils.h" 12 | #include "CommunicationUtils.h" 13 | #include "FreeIMU.h" 14 | #include 15 | #include 16 | 17 | float ypr[3]; // yaw pitch roll 18 | 19 | // Set the FreeIMU object 20 | FreeIMU my3IMU = FreeIMU(); 21 | 22 | void setup() { 23 | Serial.begin(115200); 24 | Wire.begin(); 25 | 26 | delay(5); 27 | my3IMU.init(); // the parameter enable or disable fast mode 28 | delay(5); 29 | } 30 | 31 | void loop() { 32 | my3IMU.getYawPitchRoll(ypr); 33 | Serial.print(ypr[0]); 34 | Serial.print(","); 35 | Serial.print(ypr[1]); 36 | Serial.print(","); 37 | Serial.println(ypr[2]); 38 | 39 | delay(10); 40 | } 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /FreePIE Script/FreeIMU Headtracking.py: -------------------------------------------------------------------------------- 1 | ### CONFIGURATION ### 2 | 3 | # Watch input and output values 4 | DEBUG = True 5 | 6 | # Output mode 7 | OUTPUT_FREETRACK = False 8 | OUTPUT_TRACKIR = True 9 | 10 | # Keybindings 11 | KEY_CENTER = Key.Pause # Center orientation to current position 12 | KEY_TOGGLE_ON_OFF = Key.End # Toggle headtracking on or off 13 | 14 | # Calibration multipliers 15 | TRACKIR_MULTIPLIER = 10 16 | FREETRACK_MULTIPLIER = 0.001 17 | 18 | ### THE CODE ### 19 | 20 | def update(): 21 | global yaw 22 | yaw = freeImu.yaw 23 | global pitch 24 | pitch = freeImu.pitch 25 | global roll 26 | roll = freeImu.roll 27 | 28 | def updateTrackIR(): 29 | trackIR.yaw = (yaw - centerYaw) * TRACKIR_MULTIPLIER 30 | trackIR.pitch = (pitch - centerPitch) * TRACKIR_MULTIPLIER 31 | trackIR.roll = (roll - centerRoll) * TRACKIR_MULTIPLIER 32 | 33 | if DEBUG: 34 | diagnostics.watch(trackIR.yaw) 35 | diagnostics.watch(trackIR.pitch) 36 | diagnostics.watch(trackIR.roll) 37 | 38 | def updateFreeTrack(): 39 | freeTrack.yaw = (yaw - centerYaw) * -FREETRACK_MULTIPLIER # Inverted 40 | freeTrack.pitch = (pitch - centerPitch) * FREETRACK_MULTIPLIER 41 | freeTrack.roll = (roll - centerRoll) * FREETRACK_MULTIPLIER 42 | 43 | if DEBUG: 44 | diagnostics.watch(freeTrack.yaw) 45 | diagnostics.watch(freeTrack.pitch) 46 | diagnostics.watch(freeTrack.roll) 47 | 48 | def center(): 49 | global centerYaw 50 | centerYaw = yaw 51 | global centerPitch 52 | centerPitch = pitch 53 | global centerRoll 54 | centerRoll = roll 55 | 56 | if starting: 57 | enabled = True 58 | centerYaw = freeImu.yaw 59 | centerPitch = freeImu.pitch 60 | centerRoll = freeImu.roll 61 | 62 | global yaw 63 | yaw = 0.0 64 | global pitch 65 | pitch = 0.0 66 | global roll 67 | roll = 0.0 68 | freeImu.update += update 69 | 70 | def do_update(): 71 | if OUTPUT_FREETRACK: 72 | updateFreeTrack() 73 | 74 | if OUTPUT_TRACKIR: 75 | updateTrackIR() 76 | 77 | if DEBUG: 78 | diagnostics.watch(yaw) 79 | diagnostics.watch(pitch) 80 | diagnostics.watch(roll) 81 | 82 | if enabled: 83 | do_update() 84 | 85 | if keyboard.getKeyDown(KEY_CENTER): 86 | center() 87 | 88 | if keyboard.getPressed(KEY_TOGGLE_ON_OFF): 89 | enabled = not enabled 90 | center() 91 | do_update() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino Headtracker 2 | 3 | By using an Arduino and an appropriate IMU you can for very little money build yourself an excellent headtracker similar to products such as TrackIR. 4 | 5 | You can see a short demo video of my own build here: https://www.youtube.com/watch?v=QpO1Wty3F3I 6 | 7 | This repo contains both the Arduino code and the FreePIE script to get your headtracker working. 8 | 9 | ## Hardware 10 | 11 | Below is the hardware I used, you can substitute with your own parts as you see fit. 12 | 13 | * Arduino Nano 14 | * GY-85 9DOF IMU 15 | 16 | I prefer the Arduino Nano due to the combination of formfactor and the USB port but any Arduino should work. I have ordered a couple of cheaper MPU-6050 IMUs to try if they work well, as that would cut the hardware cost in half, but they have not arrived so I can not yet vouch for them. 17 | 18 | Wire up the IMU to the Nano over the I2C bus, try to orient the IMU in a way that makes sense. Preferrably the X axis should point towards your screen once the headtracker has been mounted. 19 | 20 | When you've verified that the software works you can mount it on top of a headset or something similar. 21 | 22 | ## On the Arduino 23 | 24 | Before you load the provided sketch you need to install the FreeIMU library for Arduino, found here: https://github.com/Fabio-Varesano-Association/freeimu 25 | 26 | For this to work with the GY-85 IMU I had to open the `arduino\libraries\FreeIMU\FreeIMU.h` file, comment out the original version (I think it was `#define FREEIMU_v04`) and uncommend the following line: 27 | 28 | ```c++ 29 | #define FREEIMU_v03 30 | ``` 31 | 32 | The `FreeIMU_yaw_pitch_roll` sketch provided in this repo is very close to the original example from the FreeIMU library with the output changed to comma-separated values. Upload it to your Arduino and verify the output through the serial monitor. You should see a lot of values rolling by similar to this: 33 | 34 | ``` 35 | 145.49,31.35,0.91 36 | ``` 37 | 38 | ## On the PC 39 | 40 | Download and install FreePIE from here: http://andersmalmgren.github.io/FreePIE/ 41 | 42 | Configure the FreeIMU plugin to the COM port of your connected Arduino headtracker, and load up the `FreeIMU Headtracking.py` script. Configure it to your liking and run it by pressing F5. If you have `DEBUG` set to true you can see both the input and output values under the Watch tab at the bottom 43 | 44 | ## Games 45 | 46 | The games listed below have been tested with this setup and should hopefully work well. 47 | 48 | ### Assetto Corsa 49 | 50 | I found the following settings to behave very well in this game: 51 | 52 | ```python 53 | OUTPUT_TRACKIR = True 54 | TRACKIR_MULTIPLIER = 10 55 | ``` 56 | 57 | You might want a different multiplier but this felt natural for my setup with regards to size and distance to the monitor. 58 | 59 | ### ARMA 2 60 | 61 | For some reason I have not been able to get ARMA 2 to work with TrackIR, however the following worked for me: 62 | 63 | ```python 64 | OUTPUT_FREETRACK = True 65 | FREETRACK_MULTIPLIER = 0.001 66 | ``` 67 | 68 | This worked nicely when flying helicopters or driving cars. --------------------------------------------------------------------------------