Go Down

Topic: Arduino 3DOF Head Tracker (Read 39911 times) previous topic - next topic


Feb 11, 2009, 12:28 am Last Edit: Feb 11, 2009, 12:29 am by mluckham Reason: 1
Obvious - so why was I trying to use the media tag  :-[


Good progress today.  It outputs rotation in degrees-per-second units, and pitch/roll/vertical angle in degrees.

All credit for pitch/roll goes to the post at http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208368036 see Post #3, the method works great.

Code: [Select]

// gyro range in degrees - this gyro is +/- 300 degrees/second

float rdegreeunits = 1024.0 / GYRO_RANGEDEGREESPERSECOND;      // 1.706 A/D units per degree-per-second (which is the output from the gyro)

// accelerometer calibration - output the filtered values while pointing and rolling the device to its extremes
// GMAX maximum reading (+1g) GMIN minimum (-1g)
// gyro range in G (gravity acceleration) - the gyro is jumpered to use low range which is +/- 1.5 G

#define XGMAX 272
#define XGMIN -283
float xg_constant = 0;
float xg_b = 0;

#define YGMAX 284
#define YGMIN -273
float yg_constant = 0;
float yg_b = 0;

#define ZGMAX -556
#define ZGMIN 0
float zg_constant = 0;
float zg_b = 0;

float xgs;
float ygs;
float zgs;

float rdegreespersecond = 0.0;
float pitchdegrees = 0.0;        // angle of X-axis to the ground
float rolldegrees = 0.0;         // angle of Y-axis to the ground
float thetadegrees = 0.0;        // angle of Z-axis to the ground

Code: [Select]

    // scale the gyro A/D value to degrees per second - gyro already outputs those units, so this just scales for the 0-1023 A/D range
    rdegreespersecond = rfilt / rdegreeunits;      // printed output looks about right
    // scale the accelerometer values to pitch and roll
    //     see (http://tom.pycke.be/mav/69/accelerometer-to-attitude)
    //     but these calculations are from jmknapp's post at http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1208368036
    //  gx = kX + b
    //  where k = 2 / (xrange) = 2 / (272-(-283) = 0.0036
    //        b = 1 - k * xmax = 1 - 0.0036 * 272 = 0.0208
    //        X is the accelerometer reading
    //  if the device is held still and reasonably level during calibration, it will produce output like this:
    //    0,91,89,178   (0 deg/sec rotation, 91 deg pitch, 89 deg roll, 178 deg from vertical
    //  how great is that!

    xg_constant = 2.0 / float(XGMAX-XGMIN);
    xg_b = 1 - xg_constant * XGMAX;
    xgs = xg_constant * xfilt + xg_b;

    yg_constant = 2.0 / float(YGMAX-YGMIN);
    yg_b = 1 - yg_constant * YGMAX;
    ygs = yg_constant * yfilt + yg_b;

    zg_constant = 2.0 / float(ZGMAX-ZGMIN);
    zg_b = 1 - zg_constant * ZGMAX;
    zgs = zg_constant * zfilt + zg_b;

    pitchdegrees = atan2( xgs, sqrt( sq(ygs) + sq(zgs) ) ) * 57.296 + 90;     // pitch angle of x-axis relative to ground
    rolldegrees = atan2( ygs, sqrt( sq(xgs) + sq(zgs) ) ) * 57.296 + 90;      // roll angle of y-axis relative to ground
    thetadegrees = atan2( sqrt( sq(xgs) + sq(ygs) ), zgs ) * 57.296;          // angle of z-axis relative to gravity

    PrintTerms( int(rdegreespersecond), int(pitchdegrees), int(rolldegrees), int(thetadegrees) );

I posted the PDE at http://www.sunsys.net/arduino_images/ if anyone is interested.

Next I'll get back to trying to understand what's going on in Zitron's gyro drift filter.


I found SelmaDAQ which lets you run Excel and live graphs of the Arduino CSV output.



By the way, since I "fixed" the calculation of offsets (see code above) the gyro drift appears to be gone.

I did not need to apply any of the filtering (gAlpha calculations) to achieve that.

Assuming I am correct in this, there is a difference between your offset calculation (which averages many hundreds of samples, read as quickly as possible) and mine (which reads many hundreds of sample, over a fixed time interval - 5 seconds).


You may be interested in this paper http://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-696.pdf which describes use of current MEMS devices for inertial navigation ("strap-down INS") and the negative impact that the relatively large errors of today's MEMS devices has on that application.

I came across this while looking for solutions to obtaining speed and distance from acceleration.  My current code for this is:

Code: [Select]

      old_accel = xaccel;
      xaccel = xfilt * xg_per_unit * SPEEDUNITS;
      xdeltav += (xaccel - old_accel)/2;
      xspeed += xdeltav;
      xdistance += xspeed;

See my code submissions previously for the meaning of the variables.

The calculations seem to work out, but even very tiny amounts of tilt cause the appearance of acceleration due to gravity.  I somehow need to factor this out, perhaps by using the pitch, roll, and vertical values calculated earlier to measure the amount of tilt and do some calculation to remove it from the acceleration xfilt.  Or perhaps by simply ignoring small variables (+/- 2 or 3 degrees) of tilt.


Feb 16, 2009, 06:05 am Last Edit: Feb 16, 2009, 06:06 am by big93 Reason: 1
lol sorry if i'm coming out of nowhere, but where did you stumble on those part's you showed in your first post? i'm looking for an inexpensive gyro or accelerometer... i'm on a budget lol



See this: http://www.rcgroups.com/forums/showpost.php?p=11217504&postcount=20


Thanks for the paper, interesting reading!

I had to use some high pass filter for my gyro because not only does it need to be calibrated at the start, it will drift slowly due to temperature, voltage changes. If you have a better quality gyro, it might not be a huge problem.

As far as the sampling is concerned, I think the number of samples is less important than how long you sample. So your method is probably better, I was lazy so I used a simple for loop!



I think you are right about the gyro quality, I have used a different one in our FRC group and it does drift.  In fact it also features a temperature output - which seems like a useless thing, but I suppose it could be used to calculate a temperature-compensation value.


There is another paper in the DIY Segway project about using gyro and accelerometer together to improve accuracy, without sacrificing speed or needing to compensate for drift.  Both high-pass and low-pass filters are used, in something he calls a 'complementary filter'.

Go to http://web.mit.edu/first/segway/#misc, click on Technical Documentation, download the segspecs.zip file, open filters.pdf.


Here is my Visual Studio 2005 project which interfaces the Arduino to Flight Simulator X, to control the cockpit camera - pitch, roll, and rotation.

It communicates with FSX using SimConnect which is supplied on the FSX SDK - that is found on the FSX Deluxe CD.  

http://www.sunsys.net/arduino_images/Cockpit Camera.zip


Zitron, If you want to help me put together a board ill Order 2 and send you one for free...

I thought about making an arduino shield, but the i would prefer to have it as small as possible and just run a wire since its going to be on top of your head or glasses.

We can use the LIS302DL - $12.95 sparkfun
and the LISY300AL Single axis Gyro - $11.95 sparkfun

that lisy300al should give you about 100x better capabilities of controlling drift.



Thanks for the offer, but I have no prior experience in designing PCBs, so I'm not sure how I can help. You are free to use any code that's posted by me however you want though.



I would just attach the gyro and accelerometer carrier boards together on some prototyping board, perhaps even to each other, and package them in a little box or inside the brim of a hat?  Speaking of hats - use a Lilypad Arduino?  Or an Arduino Mini?

I've had problems with static hanging my computer, particularly it happens while loading code into the Arduino but at other times also.  Static buildup must be worse with a longer cable, make sure to use shielded wiring to the head part.

How about adding a Sparkfun bluetooth device and wirelessly sending the gyro/accel readings to the computer?

Documentation for the ones I use recommend positioning the devices as close as possible to the microcontroller - let us know what happens with longer wiring runs.


How about if i build it. ill send you one and you can code it?


any one building the head tracker and camera mount for sale? I would love to build something like this myself... but dont have much time to learn how to program and do the electronics necessary for this...

if you can private message me with a price... thanks.

Go Up