Use GPS & Accelerometer together?

Hi everyone (first post! Yay!)…

Anyway… I’m starting a litttle in-car project and will be initially using an AVR together with GPS and an accelerometer… I have figured out so far that for any truely accurate readings I’m going to need to combine the data from the accelerometer & the GPS unit to make sure that both keep each other in check… now the fundamental question is… how!? I will be needing a 3-axis accelerometer (to supply my G value as I won’t be traveling over a perfectly flat road all the time) and I know I can calculate acceleration, velocity & distance from the accelerometer and I know how…

What I can’t get my head around at the moment is a method to stop the accerlerometer drift by utilising GPS data (which would be speed etc). I have a feeling I’m missing something fundamental and that I’m just being stupid… can anybody give me any pointers?

You’re not missing anything fundamental - sensor fusion is a very complicated and difficult to understand field. Search the forums for a ‘kalman filter’ and you’ll see one solution to combining multiple sources of the same data. However, the kalman filter is a very advanced mathematical technique and not for the light-hearted.

An easy way to do what you are thinking of might be as follows: between every GPS position update, integrate the acceleration reading twice to get your change in position (starting at 0). Then, when your next GPS position arrives, compare the two and find the average (or perhaps a weighted average, depending on whether you trust your accelerometer or GPS more). Repeat for every GPS reading. This way, your accelerometer error is never carried forward for more than one GPS update (typically once a second), yet you are able to use the accelerometer readings between GPS updates to get smoother position data.

Thanks for the response Krogoth, your solution sounds pretty elegant and simple… I spent an afternoon reading about Kalman filters yesterday (and got lots of example code) but its definately not something I would look forward to implementing. Using GPS to remove the error-carried-forward sounds great… Now I have to wait for the hardware to arrive so I can test it out!

I think most of the commercial car navigation units use a GPS and a gyroscope + odometer hookup rather than an accelerometer. Integrating acceleration twice is kind of a horrible way to get position, you can do a lot better if you can count pulses from the car odometer (often available somewhere already in modern cars due to the car computer). Combining this with a direction estimated from the gyroscope, you can keep a fairly accurate position quite deep into urban canyons or tunnels where there’s no GPS reception.

Krogoth’s description is similar to a “complementary filter”… simpler to understand and implement than a Kalman filter.

I implemented a complimentary filter to combine accelerometer and gyroscopic data to obtain roll and pitch variables for a micro helicopter.

This is an example of the complimentary filter that was used. In the actual implementation all variables were scaled to be within the int range with the functions changed to work purely on ints for faster operation on a limited processor, I changed it all to doubles as it’s generally easier to get it running without all the unit conversions, in doubles first then start converting everything into the int or char range for speed.

It works by simply creating a filter structure as defined in compfilter.h and then sending the pointer to this filter structure to filter_comp_init to initialise the filter parameters. In my application I used an alpha of 0.5 however this is applicaiton depended and determines how fast the estimated values(your higher speed and drifty integrated sensor often a velocity or aceleration ie accelerometers) approaches the steady state values (your slow but non drifty sensor often position ie gps).

You then execute the filter_comp_step function everytime you get new data. Tell it the time since last update ‘dt’ current velocity ‘udot’ and current position ‘u’ and it will give you the filtered position output ‘y’.

compfilter.h

Filter * filter_comp_init(Filter *f, double alpha, double initVal);
double filter_comp_step(Filter *f, double u, double udot, double dt);

typedef struct filt{ 
    
    double alpha;     
    double u;     
    double y;     
     
} Filter;

compfilter.c

#include "compfilter.h"

Filter * filter_comp_init(Filter *f, double alpha, double initVal){
	 f->alpha = alpha;
	 f->u = 0;
	 f->y = initVal;
	 
	 return f;
}

double filter_comp_step(Filter *f, double u, double udot, double dt){
	 double y;
	 
	 y = f->y + ((f->N * (u - f->y)) + udot) * dt / 100;
	 f->u = u;
	 f->y = y;

	 return y;
}

gyro:
I implemented a complimentary filter to combine accelerometer and gyroscopic data to obtain roll and pitch variables for a micro helicopter.

i gather it worked acceptably? :) seriously though, would you mind sharing what accel and gyro you used? i'm using the sparkfun 5dof (3d accel; 2d gyro). i'd like to get roll and pitch for an r/c airplane. much appreciated.

Yeah I was able to clean up the readings reasonably well using the filter. It both sped up the reaction speed of my roll and pitch angles due to the integration of the gyros and removed steady state error by converging to the accelerometer roll and pitch values. One of the major problems faced on the helicopter was the vibrations coming through the sensors which required some tricky filtering, this shouldn’t be so much of a problem for an aeroplane.

I didn’t actually have anything to do with the hardware design for the IMU unit I just sent it commands and it sent back accelerometer and gyro readings. From memory it was an adxl chip for the accelerometers, from alanlogue devices. Can’t remember what gyro’s it used.

cool. thanks for the response. i’ll add this approach to my system and do some comparisons.