Go Down

### Topic: Guide to gyro and accelerometer with Arduino including Kalman filtering (Read 622361 times)previous topic - next topic

#### Lauszus

#300
##### May 27, 2012, 04:34 pm
@jasmine_hossam
Check out Pololu's library for Arduino:
https://github.com/pololu/L3G4200D

And also see Sparkfun's example code for the device: http://dlnmh9ip6v2uc.cloudfront.net/datasheets/Sensors/Gyros/3-Axis/L3G4200D_Example.zip (http://www.sparkfun.com/products/10612).

Regards
Lauszus

#### ea123

#301
##### May 28, 2012, 12:18 pm
Hi,
here is my implementation of Kalman filter and a comparison with raw sensor and complementary filter
in roll/pitch angle estimation:

#### Lauszus

#302
##### May 28, 2012, 01:46 pm
@ea123
Looks really nice

#### Jase_MK

#303
##### May 30, 2012, 04:45 pm
Hi all. Been lurking for a while and reading this thread with interest.

I'm putting together a data logger for my car and have managed to find a reasonably priced 9DOF unit. From what I can see, using the Kalman filter (or similar alternative) only works to calculate a angular position if you're not accelerating. Surely if a car is accelerating, braking or cornering hard then accelerometer readings used as part of the algorithm for calculating pitch and roll is going to generate duff results?

Similarly, I'm not sure how to measure something simple such as g-forces generated due to cornering. Simply taking an accelerometer reading on the x-axis will give an incorrect result due to the fact that the car will be experiencing some roll and therefore the sensor won't be flat. If I knew the angle of roll, I could correct this reading using some simple trig, but this takes us back to the original problem of not being able to calculate pitch/roll whilst the IMU is experiencing significant acceleration (other than gravity).

Hmmmm
/strokes chin...

Apologies if I've misunderstood things or missed this coming up earlier in the thread.

#### Lauszus

#304
##### May 30, 2012, 08:58 pm
@Jase_MK
Sorry, but you misunderstand the whole point of a Kalman filter or similar. The whole point of a Kalman filter or similar is to filter out any noise i.e. acceleration from a car etc. So if you tune your filter properly it will filter out all the noise from the accelerometer! To get the total amount of g-force, you just have to calculate the length of the force vector, as I did in the code.

Regards
Lauszus

#### Jase_MK

#305
##### May 31, 2012, 12:02 am
OK, thanks. So using the Kalman filter, or similar, I can use my IMU readings to calculate angular position (pitch, roll), even if the car is accelerating about all over the place. I think I need to read the thread again from the start and try out some code and see what happens.

Thanks

#### Lauszus

#306
##### May 31, 2012, 12:06 am
@Jase_MK
Yes exactly
Okay, do that - I think the best way to "learn" how it works is to see the effect of the filter yourself.
Try to upload the Arduino code provided and use the Processing program I created to see a visual representation of the data.

Regards
Lauszus

#### Jase_MK

#307
##### May 31, 2012, 12:15 am
Will do. My IMU is in the post so I shall get playing asap.

Thanks again

#### Lauszus

#308
##### May 31, 2012, 12:23 am
@Jase_MK
Just write me again if you need further assistance!

Regards
Lauszus

#### George64

#309
##### May 31, 2012, 12:09 pm
Hello,

Pretty new to the forum and to using the Arduino Uno with the SLM303.

I'm trying to build a tilt compensated compass with an nmea string as out. This string is going to be input for my boat network so my tiller pilot will be able to better steer a course. Quite a project....

The code I have so far:
Code: [Select]
`#include <Wire.h>#include <LSM303.h>LSM303 compass;void setup() {  Serial.begin(9600);  Wire.begin();  compass.init();  compass.enableDefault();    // Calibration values. Use the Calibrate example program to get the values for  // your compass.  compass.m_min.x = -397; compass.m_min.y = -284; compass.m_min.z = -464;  compass.m_max.x = 150; compass.m_max.y = 287; compass.m_max.z = 227;    /* Output van Calibrate  M min X: -397 Y: -284 Z: -464   M max X: 150 Y: 287 Z: 227  */}/* Oorspronkelijke codevoid loop() {  compass.read();  int heading = compass.heading((LSM303::vector){0,-1,0});  Serial.println(heading);  delay(500);} *//*----------------------------------------------------------------------------        1   2   3 4   5 6        |   |   | |   | | \$--HDG,x.x,x.x,a,x.x,a*hh<CR><LF>------------------------------------------------------------------------------Field Number: 1. Magnetic Sensor heading in degrees2. Magnetic Deviation, degrees3. Magnetic Deviation direction, E = Easterly, W = Westerly4. Magnetic Variation degrees5. Magnetic Variation direction, E = Easterly, W = Westerly6. Checksum */char nmeastr[17]; // HCHDG,000.00,,,,*int checksum;char hs[6]; // 000.00void loop() {  strcpy(nmeastr,"HCHDG,");    //dtostrf(FLOAT,WIDTH,PRECSISION,BUFFER);  compass.read();  dtostrf(compass.heading(), 5, 0, hs);  //Serial.print("hs ");  //Serial.print(hs);  //Serial.println();      strcat(nmeastr,hs);  strcat(nmeastr,",,,,");    //add a checksum  checksum=0;  for (int n=0; n < strlen(nmeastr); n++) {    checksum ^= nmeastr[n];  }    Serial.print("\$");  Serial.print(nmeastr);  Serial.print("*");  Serial.print(checksum, HEX);  Serial.println();    /* 5hz == 200 */  delay(500);}`

When laying flat on the table, it produces:
Quote
\$HCHDG,  207,,,,*59
\$HCHDG,  211,,,,*5E
\$HCHDG,  213,,,,*5C
\$HCHDG,  209,,,,*57
\$HCHDG,  213,,,,*5C
\$HCHDG,  211,,,,*5E
\$HCHDG,  210,,,,*5F
\$HCHDG,  215,,,,*5A
\$HCHDG,  212,,,,*5D
\$HCHDG,  207,,,,*59
\$HCHDG,  208,,,,*56
\$HCHDG,  208,,,,*56
\$HCHDG,  208,,,,*56
\$HCHDG,  211,,,,*5E
\$HCHDG,  210,,,,*5F
\$HCHDG,  210,,,,*5F
\$HCHDG,  207,,,,*59
\$HCHDG,  217,,,,*58
\$HCHDG,  215,,,,*5A
\$HCHDG,  211,,,,*5E
\$HCHDG,  211,,,,*5E
\$HCHDG,  209,,,,*57
\$HCHDG,  212,,,,*5D
\$HCHDG,  210,,,,*5F
\$HCHDG,  209,,,,*57
\$HCHDG,  210,,,,*5F
\$HCHDG,  211,,,,*5E
\$HCHDG,  212,,,,*5D
\$HCHDG,  211,,,,*5E
\$HCHDG,  210,,,,*5F

As you can see, not a stable course to steer The video shows the issue I'm facing when it comes to stable ocurse
http://youtu.be/3XHxAKu6n7E

I know I should do some filtering, and this is where I got to this topic and also got stuck on how to get the kalman filter to this code. I'd like some help on how I can put the filter in place so the course gets more stable.

#### Lauszus

#310
##### May 31, 2012, 05:46 pm
Hi,
I don't have any experience with magnetometers - I know that Sparkfun called it a compass sensor, but it's really a magnetometer.

Have you check out this application note:
http://www.sparkfun.com/datasheets/Sensors/Magneto/Tilt%20Compensated%20Compass.pdf

Also check out this library I found:
https://github.com/pololu/LSM303

I don't know if that is the library you are already using? But it look like it? Have you tried to run the example sketch (https://github.com/pololu/LSM303/blob/master/LSM303/examples/Heading/Heading.ino) and see how that went?

Remember that any magnetic field will affect your reading, so keep away all electronics - my friend had a big problem with his until he realized that his laptop's harddrive affected his magnetometer a lot!

Sorry that I can't help you no more - I have no experience with magnetometers. If it were me would properly try the example sketch provided in the library and then read the application note to understand what was going on
I don't think you can use the Kalman filter I provided. You need another type of filter - try google for "ahrs magnetometer" and see what you can find.

Regards
Lauszus

#### George64

#311
##### May 31, 2012, 06:31 pm

The code from https://github.com/pololu/LSM303 is the code I use for the compass function. The output shown is the result of a minor addition I did to create nmea output.

I'll google "ahrs magnetometer" to see if it can help. Part of the learning curve

George

#### Lauszus

#312
##### May 31, 2012, 11:16 pm
Okay. I will try to talk with my teammate tomorrow as he is currently building a quadrocopter, so he has some experience with magnetometers, and then ask him for good links and so on.

Regards
Lauszus

#### George64

#313
##### Jun 01, 2012, 07:24 am
Thanks Lauszus, that woud be great!

Been searching using the keywords you suggest, however I did not find a solution that would fit my needs. Sites I found suggest to use some sort of Kalman filter. Will also do more digging.

Cheers, George

#### tkj

#314
##### Jun 02, 2012, 09:41 am
Dear George.

This is Thomas, Lauszus' teammate. As Lauszus sure enough introduced me I am building a Quadrocopter. To do this you need a 9DOF sensor, which means a 3-angled accelerometer, gyro and magnetometer.
To combine all the sensor data I use a DCM algorithm - Direct Cosine Matrix - which then gives me the orientation of the board in x, y and z rotational degrees.

With the orientation I am then also able to get the tilt compensated heading by combining the magnetometer data and the orientation values.

On the Arduino, which I am not using for this project though, it can be done with the following code: https://dev.qu.tu-berlin.de/projects/sf-razor-9dof-ahrs/wiki/Tutorial
If that doesn't work out for you because of it being to advanced then have a look at the smaller version of the code here: http://code.google.com/p/sf9domahrs/

Let me know if you can get it working.

Best Regards
Thomas Jespersen

Go Up