Dennis Frie Just another user Thread OP

Build Log DIY Headtracker (Easy build, No drift, OpenSource)



A couple of fellow FPV-friends complained about their headtrackers - mainly drift problems and bad resolution. One showed a video with the problem, and my comment "that looks really bad, even I can make that a lot better", ended up costing me a bit of time.



I have choosen to use 3 axis- accelerometer, gyro and magnetometer, as that's the only way to account for drift in all directions.



Flight video from Gabek

Skywalker X8 FPV the "white one" (7 min 8 sec)



Quick video from absolute-zero:

DIY Opensource Headtracker (0 min 53 sec)



The hardware used is pretty simple, you just need an Arduino and a sensorboard.



Arduino Nano:

11.99$ shipped:

or:

12.28$ shipped:

or:

16.90$ shipped:





Sensor board (9-axis IMU):

18.30$ shipped:



33.49$ shipped:

or:

29.51$ shipped:



Perhaps this one is the same?

19.67$ shipped:



That's about 30$ total



Code and GUI can be found at google code

http://code.google.com/p/open-headtracker/



And that's it.



The project is made as user-friendly as possible, and only little technical knowledge should be necessary. All necessary settings can be changed from a graphical user interface - making it easy for everyone to use.



All good ideas for improvement is more than welcome



Connection diagram/pinout:





Connection diagram for Pro mini

(made by typicalaimster)





The hardware used:





Assembled hardware - just missing connections to RC-transmitter





Early test-version. Plug-n-play in FF9 transmitter.





Graphical user interface





- GUI showing advanced settings too:





GUI for magnetometer calibration:





Tests with PPM expansion (this part is not done):

PPM in from FF9 (red), PPM out from tracker (blue):





8 channel PPM in, 12 channel PPM out (this part is only :





Constant frame-rate (red: FF9 PPM in, blue headtracker PPM out)





Headtracker sensor plots, raw, filtered etc:







A quick test-video can be found here. It's hard to show if a headtracker works well or not, so it's just a quick test-video.

https://dl.dropbox.com/u/3947315/Videogdp.3gp



Short description of the more technical stuff

----------------------------------------------------------

Headtracker:

The sensors are sampled with 128 samples/sec. As we have 9 sensors, we get 128 * 9 = 1152 measurements/samples every second (more than plenty for a headtracker). The sampling-rate is controlled by timer0, that will set a flag high - indicating that the sensors should be read and new angles etc. calculated (timer0 running in CTC-mode, using compare-register A). While it should be possible to make all the calculations etc. within the interrupt, it's not recommended. A lot of heavy/slow calculations are done, and in case of timing-problems, we just want it to skip a sample and continue (should never happen, but just in case).

If you turn on DEBUG you will get a lot of extra information, be able to see timing-problems etc. (please note, using serial.print is time comsuming and will in mast cases give timing-problems. Rarely a real problem when debugging, but be aware that it will change the samplerate a bit.)



Accelerometer:

The accelerometer data is converted to G-force. Not really necessary, but more convenient to work with. The total G-vector is calculated, and the angle calculated by using the total vector-length and the G-force in each direction.



Gyro:

The gyro indicates the angular change in degrees/sec. All axes accounts for tilt etc and data is continously integrated, to give an estimation of the angle.



Magnetometer:

The magnetometer is compensated for tilt (x- y-direction), and the final x and y values used to calculate the magnetic heading.



Filter:

The filter is a basic complementary filter, and an optional lowpass filter. The weight for gyro/accelerometer/magnetometer can be sat in the GUI, and lowpass filter changed.





PPM

Please note that only PPM-out is activated as default. PPM-mixing etc. need some work.

The PPM in/out is a bit tricky, as we can only do one thing at a time. Oh - and we only have one 16 bit timer available. Timer1 (16 bit timer) is used to generate the PPM output. It's set to change pin at interrupt to get an accurate hardware-timed pin-change. The compare-interrupt will set the next compare-match.



PPM-in is detected by pin-change interrupt (higher priority than timer1 compare interrupt). It will use the time from timer1, and detect if the timer have been reset.

----------------------------------------

A few notes:



Use of Serial output

The headtracker uses a lot of slow calculations with floating points, cos, sin atan etc. Furthermore the sampling frequency is pretty high. Using Serial.print is great for getting info, data etc. - but it requires time. As it's running "on the edge", you can only print a few characters without loosing a sample. It's programmed to just skip a sample in case of timing problems, but just be sure to note this when testing.



Updating variables

All variables stored in EEPROM have to be changed in the GUI or by changing this:

// If the device have just been programmed, write initial config/values to EEPROM:

if (EEPROM.read(0) != 42) {



But as all settings saved in EEPROM can be changed from GUI I'll suggest that, as it's a lot easier.

----------------------------------------

Using the GUI:



The GUI have been changed quite a bit since first versions, and is hopefully pretty intuitive.



PPM channels

Used to set the PPM-channel pan/tilt and roll is assigned t0



Center

The center position of the servo



End

Servo travel end.



Gain

The gain determines how much the servo should move for a given head-movement. Default is 170 which pretty much gives 1:1 (90 degrees head-movement = 90 degrees servo movement).





All the "advanced settings"

- - - -

LP filter at tilt/roll [%]

Lowpass-filter of the final tilt/roll output.

1 = max lowpass/time constant. Will give very smooth, but also very slow change.

100 = lowpass off.



LP filter at pan [%]

Lowpass-filter of the final pan output.

1 = max lowpass/time constant. Will give very smooth, but also very slow change.

100 = lowpass off.



Gyro weight on tilt/roll [%]

How much do we thrust the gyro compared to the accelerometer on the tilt/roll axis? Accelerometer is noisy and should only be used to slowly compensate for drift.

100 = only use gyro.

0 = only use accelerometer



Gyro weight on pan [%]

How much do we thrust the gyro compared to the magnetometer on the pan-axis? The gyro is a lot more accurate, so magnetometer should only be used to slowly compensate drift.

100 = only use gyro

0 = only use magnetometer



Servo pulse variation

In short: Servo travel adjustment.



Used to set the max variation of the pulse-width in the PPM signal. The unit is microseconds*2 - matching the Atmega timer



Servo center

In short: Servo neutral position



Used to set the center/default length of the pulse-width in the PPM signal. The unit is microseconds*2 - matching the Atmega timer



Tilt and roll gain

Gain of the servo. You decide if you want to turn the head 10 degrees or 360 degrees to get full travel.



Pan gain

Gain of the servo. You decide if you want to turn the head 10 degrees or 360 degrees to get full travel.



Reverse (Tilt, roll and Pan)

used to inverse the servo direction.

----------------------------------------



General questions:



Can I use other Arduino versions?

Sure, all Arduino boards should have the necessary pins available (as far as I know). I have choosen Arduino Nano as it's cheap, small, have FTDI onboard and the regulator can handle a bit higher current, compared to Arduino Pro etc. But pick whatever you prefer/have available.



Can I use other sensors?

It should be pretty easy to use other sensors, as long as it's I2C. Update the sensor-init, sensor-reading and the sensor-configuration and you should more or less be good to go. I'll maybe add support for another IMU later.



Can I buy a headtracker from you?

No, it's meant as a DIY project. It's easy to make, and it should be pretty straight forward. I like to develope, but care little about sale etc.



Can I sell this?

Feel free. I can imagine a few people would like to buy a nice ready-made unit, but it would be great to know if you use my software/work. But in general it's uploaded with no strings attached.



What about copyright/license etc?

It's uploaded as OpenSource, and I expect it to be used and abused - don't really see much sense in "protecting" my work. So feel free to use it for whatever purpose.







Quick guide

Okay, quick little "start guide" for those not familiar with Arduino



You should have:

1 x Arduino Nano or similar

1 x IMU/sensor board

First, lets assemble some hardware. It's pretty straight forward.



The connections are:

Sensorboard Arduino

Vcc_in -> 5 volt

GND -> Ground/GND

SCL -> A5

SDA -> A4



Transmitter Arduino

PPM_IN -> D9

V_out -> V_in

Ground -> Ground/GND



And that's it.



The placement of the board is pretty much up to you. But please remember that the magnetometer is pretty sensitive. Even small currents nearby will cause a magnetic field. If it's a constant field, chances are you can calibrate it, but please be aware of this problem.



The board can be placed on top of Arduino, on buttom, on the side or just where-ever you want by using long wires.



The pins match pretty good, so you can just connect it directly. The only pin that doesn't match is ground.



Quick pictures of the easy configuration. Please note that I haven't tested if the positions close to the electronic is a problem.



Placed underneath the Arduino board:





On the side:





On top:





The only wire needed for the sensor-board is ground:

(Here just shown as a quick test with nothing soldered but fully working)





Choose your preferred location and solder the sensorboard.

Download Arduino IDE from http://arduino.cc/hu/Main/Software (should be version 1 or higher)

Connect your Arduino board

If the driver is installed automatic, just continue. If not, select the folder called "Driver" inside the Arduino IDE folder

Download the latest headtracker-software from http://code.google.com/p/open-headtracker/

Open Arduino IDE (the program), Select file -> Open, find the headtracker software downloaded and open the file DIY_headtracker.ino

You should now have a window looking pretty much like this:



Go to tools -> Board and select "Arduino Nano w/Atmega328

Go to tools -> Serial port -> Select the com-port used by Arduino (you should remember the port-number for later use in the GUI).

Press the left-arrow in Arduino IDE to upload, or select file -> Upload, or press Ctrl + u.

Hopefully it starts to upload the firmware. It should flash the LED's quickly for

a while, and stop when the upload/programming is complete.



Magnetometer calibration Now let's start with calibrating the magnetometer. Open the file Magnetometer_cal_v0_02 included in the folder.

- Set the com-port to match the one found/used in Arduino IDE. Press connect. If the program crash, you have must likely selected a wrong com-port or the com-port is used by another program such as Arduino IDE.

- Press "Start plot" and you should see live-data being plotted.

- Everytime you do a calibration, you have to press "Set offset to 0".

- Now place the headtracker as shown on the pictures, and press "set" when the headtracker is on the position as shown.

- When all 3 positions have been set, you should have the offset

- Press "Save" to upload the offset-settings to the headtracker.



And that should be the magnetometer calibration, and hopefully you will never have to see it again

Now find the file Headtracker_GUI_v0_04.exe in the file downloaded from google-code and open it.

Set the com-port to match the one found/used in Arduino IDE. Press connect. If the program crash, you have must likely selected a wrong com-port or the com-port is used by another program such as Arduino IDE.

Press the button "start plot". If everything works, you will see 3 live graphs with pan/tilt/roll.

Set the necessary settings - remember to press "calibrate gyro".



Hopefully that's it, and you are ready to go.



Some known limitations: The sensorboard must be orientated with the components up.

Nothing in the GUI is "idiot proof". It will accept more or less everything and just do it.

(If you look at the code) The sensorboard's magnetometer have 2 axis swapped. This is a hardware problem. Not anything to worry about, but the magnetometer z/y axis is swapped.

Support for PPM-in etc. is not done. Only PPM-output is supported atm.



Few pictures from other peoples build:



SpookiePower







SubSonic:









Jalves:





BlueAngel











Absolute-Zero





Donations kindly received from:

- Guy1a

- Gabek

- typicalaimster

- ChilternFlyer

- Quadzimodo Time for a new DIY and OpenSource-projectA couple of fellow FPV-friends complained about their headtrackers - mainly drift problems and bad resolution. One showed a video with the problem, and my comment "that looks really bad, even I can make that a lot better", ended up costing me a bit of time.I have choosen to use 3 axis- accelerometer, gyro and magnetometer, as that's the only way to account for drift in all directions.Flight video from GabekQuick video from absolute-zero:The hardware used is pretty simple, you just need an Arduino and a sensorboard.Arduino Nano:11.99$ shipped: http://www.dealextreme.com/p/nano-v3...-118037?item=8 or:12.28$ shipped: https://www.hobbyking.com/hobbyking/s...ler_Board.html or:16.90$ shipped: http://www.dealextreme.com/p/arduino...0-81877?item=2 Sensor board (9-axis IMU):18.30$ shipped: http://www.dealextreme.com/p/gy-85-6...arduino-148436 33.49$ shipped: http://www.ebay.com/itm/ws/eBayISAPI...E:L:OC:US:3160 or:29.51$ shipped: http://www.goodluckbuy.com/gy-85-sen...u-sensor-.html Perhaps this one is the same?19.67$ shipped: http://www.goodluckbuy.com/nine-axis...3l-module.html That's about 30$ totalCode and GUI can be found at google codeAnd that's it.The project is made as user-friendly as possible, and only little technical knowledge should be necessary. All necessary settings can be changed from a graphical user interface - making it easy for everyone to use.All good ideas for improvement is more than welcomeConnection diagram/pinout:Connection diagram for Pro mini(made by typicalaimster)The hardware used:Assembled hardware - just missing connections to RC-transmitterEarly test-version. Plug-n-play in FF9 transmitter.Graphical user interface- GUI showing advanced settings too:GUI for magnetometer calibration:Tests with PPM expansion (this part is not done):PPM in from FF9 (red), PPM out from tracker (blue):8 channel PPM in, 12 channel PPM out (this part is only :Constant frame-rate (red: FF9 PPM in, blue headtracker PPM out)Headtracker sensor plots, raw, filtered etc:A quick test-video can be found here. It's hard to show if a headtracker works well or not, so it's just a quick test-video.Short description of the more technical stuff----------------------------------------------------------The sensors are sampled with 128 samples/sec. As we have 9 sensors, we get 128 * 9 = 1152 measurements/samples every second (more than plenty for a headtracker). The sampling-rate is controlled by timer0, that will set a flag high - indicating that the sensors should be read and new angles etc. calculated (timer0 running in CTC-mode, using compare-register A). While it should be possible to make all the calculations etc. within the interrupt, it's not recommended. A lot of heavy/slow calculations are done, and in case of timing-problems, we just want it to skip a sample and continue (should never happen, but just in case).If you turn on DEBUG you will get a lot of extra information, be able to see timing-problems etc. (please note, using serial.print is time comsuming and will in mast cases give timing-problems. Rarely a real problem when debugging, but be aware that it will change the samplerate a bit.)The accelerometer data is converted to G-force. Not really necessary, but more convenient to work with. The total G-vector is calculated, and the angle calculated by using the total vector-length and the G-force in each direction.The gyro indicates the angular change in degrees/sec. All axes accounts for tilt etc and data is continously integrated, to give an estimation of the angle.The magnetometer is compensated for tilt (x- y-direction), and the final x and y values used to calculate the magnetic heading.The filter is a basic complementary filter, and an optional lowpass filter. The weight for gyro/accelerometer/magnetometer can be sat in the GUI, and lowpass filter changed.Please note that only PPM-out is activated as default. PPM-mixing etc. need some work.The PPM in/out is a bit tricky, as we can only do one thing at a time. Oh - and we only have one 16 bit timer available. Timer1 (16 bit timer) is used to generate the PPM output. It's set to change pin at interrupt to get an accurate hardware-timed pin-change. The compare-interrupt will set the next compare-match.PPM-in is detected by pin-change interrupt (higher priority than timer1 compare interrupt). It will use the time from timer1, and detect if the timer have been reset.----------------------------------------The headtracker uses a lot of slow calculations with floating points, cos, sin atan etc. Furthermore the sampling frequency is pretty high. Using Serial.print is great for getting info, data etc. - but it requires time. As it's running "on the edge", you can only print a few characters without loosing a sample. It's programmed to just skip a sample in case of timing problems, but just be sure to note this when testing.All variables stored in EEPROM have to be changed in the GUI or by changing this:// If the device have just been programmed, write initial config/values to EEPROM:if (EEPROM.read(0) != 42) {But as all settings saved in EEPROM can be changed from GUI I'll suggest that, as it's a lot easier.----------------------------------------The GUI have been changed quite a bit since first versions, and is hopefully pretty intuitive.Used to set the PPM-channel pan/tilt and roll is assigned t0The center position of the servoServo travel end.The gain determines how much the servo should move for a given head-movement. Default is 170 which pretty much gives 1:1 (90 degrees head-movement = 90 degrees servo movement).- - - -Lowpass-filter of the final tilt/roll output.1 = max lowpass/time constant. Will give very smooth, but also very slow change.100 = lowpass off.Lowpass-filter of the final pan output.1 = max lowpass/time constant. Will give very smooth, but also very slow change.100 = lowpass off.How much do we thrust the gyro compared to the accelerometer on the tilt/roll axis? Accelerometer is noisy and should only be used to slowly compensate for drift.100 = only use gyro.0 = only use accelerometerHow much do we thrust the gyro compared to the magnetometer on the pan-axis? The gyro is a lot more accurate, so magnetometer should only be used to slowly compensate drift.100 = only use gyro0 = only use magnetometerIn short: Servo travel adjustment.Used to set the max variation of the pulse-width in the PPM signal. The unit is microseconds*2 - matching the Atmega timerIn short: Servo neutral positionUsed to set the center/default length of the pulse-width in the PPM signal. The unit is microseconds*2 - matching the Atmega timerGain of the servo. You decide if you want to turn the head 10 degrees or 360 degrees to get full travel.Gain of the servo. You decide if you want to turn the head 10 degrees or 360 degrees to get full travel.used to inverse the servo direction.----------------------------------------Sure, all Arduino boards should have the necessary pins available (as far as I know). I have choosen Arduino Nano as it's cheap, small, have FTDI onboard and the regulator can handle a bit higher current, compared to Arduino Pro etc. But pick whatever you prefer/have available.It should be pretty easy to use other sensors, as long as it's I2C. Update the sensor-init, sensor-reading and the sensor-configuration and you should more or less be good to go. I'll maybe add support for another IMU later.No, it's meant as a DIY project. It's easy to make, and it should be pretty straight forward. I like to develope, but care little about sale etc.Feel free. I can imagine a few people would like to buy a nice ready-made unit, but it would be great to know if you use my software/work. But in general it's uploaded with no strings attached.It's uploaded as OpenSource, and I expect it to be used and abused - don't really see much sense in "protecting" my work. So feel free to use it for whatever purpose.Okay, quick little "start guide" for those not familiar with ArduinoYou should have:1 x Arduino Nano or similar1 x IMU/sensor boardHopefully that's it, and you are ready to go.Some known limitations:Few pictures from other peoples build:SpookiePowerSubSonic:Jalves:BlueAngelAbsolute-ZeroDonations kindly received from:- Guy1a- Gabek- typicalaimster- ChilternFlyer- Quadzimodo Images View all Images in thread Views: 25287





Views: 3558





Views: 3477





Views: 22548





Views: 22370





Views: 22327





Views: 22293





Views: 22471





Views: 23615





Views: 22618



