Real time Kalman filter on an ESP32 and sensor fusion.

  Рет қаралды 14,227

T.J Moir

T.J Moir

Күн бұрын

Implementing a discrete-time Kalman filter (steady-state). A bit of theory and a practical demonstration. Uses the Arduino software. Acknowledgement to random nerd tutorials too. Measures pitch angle and will be suitable for some balancing projects such as a Segway or Quad copters. Uses sensor fusion of accelerometer and gyro readings. The steady state Kalman filter is implemented in closed-loop form and in state-space format. The relationship to a Wiener estimator I will show in more detail later. This requires a transfer function matrix but is not used here.

Пікірлер: 22
@TJMoir
@TJMoir 7 ай бұрын
Code: // Basic demo for accelerometer readings from Adafruit MPU6050 //Kalman filter added by T.J.Moir 8/5/2021 and angle calculation // ESP32 Guide: RandomNerdTutorials.com/esp32-mpu-6050-accelerometer-gyroscope-arduino/ // ESP8266 Guide: RandomNerdTutorials.com/esp8266-nodemcu-mpu-6050-accelerometer-gyroscope-arduino/ // Arduino Guide: RandomNerdTutorials.com/arduino-mpu-6050-accelerometer-gyroscope/ #include #include #include float angX,angY,dangZ1,dangZ2,dangZ3,angZ; //Kalman filter data float f11,f12,f21,f22,fc11,fc12,fc21,fc22; float d11,d12,d21,d22; //states float xh1k,xh2k,xh1k_1,xh2k_1; float s1,s2; //observations, angular position and angular velocity from accelerometer angles and gyro info //H matrix is identity //Filter gain matrix float k11,k12,k21,k22; //sampling freq and interval float fs,Ts; // for sampling freq int sample_pin=16; boolean running = false; Adafruit_MPU6050 mpu; void setup(void) { pinMode(sample_pin,OUTPUT); sample_pin=false; /////////////////////////// //sampling frequency fs=10000.0; //sampling interval Ts=1/fs; f11=1; f12=-Ts; f21=0.0; f22=1.0; d11=Ts; d12=-Ts*Ts*0.5; d21=0.0; d22=Ts; //Kalman gains have been calculated offline for Q=I,R=I*1e-5; k11=0.0311; k12=-5.1556e-5; k21=-4.8444e-5; k22=0.0311; // //initialise state estimates xh1k=0.0; xh2k=0.0; xh1k_1=0.0; xh2k_1=0.0; /////// //calculate Kalman filter Fc closed loop F matrix. Note H=I identity matrix Fc=F-KH (K has been found offline) fc11=f11-k11; fc12=f12-k12; fc21=f21-k21; fc22=f22=k22; ///// Serial.begin(115200); while (!Serial) //delay(10); // will pause Zero, Leonardo, etc until serial console opens //Serial.println("Adafruit MPU6050 test!"); // Try to initialize! if (!mpu.begin()) { //Serial.println("Failed to find MPU6050 chip"); while (1) { delay(10); } } //Serial.println("MPU6050 Found!"); mpu.setAccelerometerRange(MPU6050_RANGE_8_G); //Serial.print("Accelerometer range set to: "); switch (mpu.getAccelerometerRange()) { case MPU6050_RANGE_2_G: // Serial.println("+-2G"); break; case MPU6050_RANGE_4_G: //Serial.println("+-4G"); break; case MPU6050_RANGE_8_G: //Serial.println("+-8G"); break; case MPU6050_RANGE_16_G: //Serial.println("+-16G"); break; } mpu.setGyroRange(MPU6050_RANGE_500_DEG); //Serial.print("Gyro range set to: "); switch (mpu.getGyroRange()) { case MPU6050_RANGE_250_DEG: //Serial.println("+- 250 deg/s"); break; case MPU6050_RANGE_500_DEG: // Serial.println("+- 500 deg/s"); break; case MPU6050_RANGE_1000_DEG: //Serial.println("+- 1000 deg/s"); break; case MPU6050_RANGE_2000_DEG: //Serial.println("+- 2000 deg/s"); break; } mpu.setFilterBandwidth(MPU6050_BAND_5_HZ); //Serial.print("Filter bandwidth set to: "); switch (mpu.getFilterBandwidth()) { case MPU6050_BAND_260_HZ: //Serial.println("260 Hz"); break; case MPU6050_BAND_184_HZ: //Serial.println("184 Hz"); break; case MPU6050_BAND_94_HZ: //Serial.println("94 Hz"); break; case MPU6050_BAND_44_HZ: //Serial.println("44 Hz"); break; case MPU6050_BAND_21_HZ: //Serial.println("21 Hz"); break; case MPU6050_BAND_10_HZ: //Serial.println("10 Hz"); break; case MPU6050_BAND_5_HZ: //Serial.println("5 Hz"); break; } //Serial.println(""); delay(100); } void loop() { /* Get new sensor events with the readings */ sensors_event_t a, g, temp; mpu.getEvent(&a, &g, &temp); /* Print out the values */ /* Serial.print("Acceleration X: "); Serial.print(a.acceleration.x); Serial.print(", Y: "); Serial.print(a.acceleration.y); Serial.print(", Z: "); Serial.print(a.acceleration.z); Serial.println(" m/s^2");*/ //dangZ1=sqrt(a.acceleration.z*a.acceleration.z+a.acceleration.x*a.acceleration.x); dangZ2=sqrt(a.acceleration.z*a.acceleration.z+a.acceleration.y*a.acceleration.y); //dangZ3=sqrt(a.acceleration.x*a.acceleration.x+a.acceleration.y*a.acceleration.y); //angX=57.29*atan2(a.acceleration.y,dangZ1); //Serial.println(angX); //roll angY=57.29*atan2(a.acceleration.x,dangZ2); // Serial.println(angY); //pitch angle in degrees only //angZ=57.29*atan2(a.acceleration.z,dangZ3); //Serial.println(angZ); //Pitch wrt 90 degrees //Kalman filter here s1= angY; //angular position from accelerometer calculation s2=g.gyro.y;//from gyro angular velocity //shuffle regressors of the states xh1k_1=xh1k; xh2k_1=xh2k; xh1k=fc11*xh1k_1 +fc12*xh2k_1+k11*s1+k12*s2; xh2k=fc21*xh1k_1 +fc22*xh2k_1+k21*s1+k22*s2; /* Serial.print("\t"); Serial.print(s1); //noisy angle estimate of pitch Serial.print(" "); */ Serial.println(xh1k); //KF pitch angle estimate // Serial.println(xh2k); //KF pitch angular velocity estimate // Sets a flag at a precise time. ////// // To measure the sample rate from pin 21 digitalWrite(sample_pin,running); running=!running; /* Serial.print("Rotation X: "); Serial.print(g.gyro.x); Serial.print(", Y: "); Serial.print(g.gyro.y); Serial.print(", Z: "); Serial.print(g.gyro.z); Serial.println(" rad/s"); Serial.print("Temperature: "); Serial.print(temp.temperature); Serial.println(" degC"); Serial.println(""); */ //delay(5); }
@jcalvarezg
@jcalvarezg 2 жыл бұрын
Very nice, thanks for the guidelines.I got the book yesterday and I like the way the examples are worked. Great job.
@amineminou6046
@amineminou6046 2 жыл бұрын
The book has thé cod??
@phillipmaser132
@phillipmaser132 17 күн бұрын
Project requires counting sections of pipe. If I shoot missile like object down a PVC pipe; it count sections of pipe as it passes the joints? I want to use acceleration and Gyro to find these section as a peak in travel. Possibly a Kalman filter can help? I need to know the velocity traveled so I know when to stop at a distance. Threshold could vary between sections not good.
@TJMoir
@TJMoir 16 күн бұрын
If you can measure noisy position you can get velocity and acceleration via a Kalman filter. You will need the equations of motion of course in your KF. Counting the sections I suppose is position.
@sebastiantreu8243
@sebastiantreu8243 25 күн бұрын
please correct me if I'm wrong but this works only on ground. This may not work on an airplane for coordinated turns where you are moving forward in space but also G force vector would produce unstable values...
@TJMoir
@TJMoir 24 күн бұрын
The first real application of the Kalman filter was in the Apollo space programme. There is a NASA report somewhere - old one that gives the equations for inertial navigation. They had 12 states I think and it was implemented digitally (surprising for the 1960s) with a custom computer. The KF had the equations of the Apollo craft built in as well. This is a simplified steady state Kalman filter I have here but should work ok in a quadcopter. Not tried it though, only tried it on simple self balancing machines.
@wilfriedpacomemenye739
@wilfriedpacomemenye739 9 ай бұрын
Please can you know how i can use this with gps to estimate the position in space? It's for my School project
@TJMoir
@TJMoir 9 ай бұрын
A spaceship uses a Gyro and Accelerometer. Each inertial measurement unit has three gyroscopes and three accelerometers -- one gyro and one accelerometer for each axis of the spacecraft. x y and z. From acceleration and velocity (angular for both) we can estimate position in each axis using a Kalman Filter. ie how far in each axis the spaceship has turned. You would need at least 6 states, two for each axis but possibly more (I think Apollo had 12). But this only gives a relative position to a past position, you need an absolute measurement so on earth we can use GPS and on say Mars you would need a star fix from a star tracker. When Apollo took off it had a fix for the Gyros from earth but from the Moon they must have used a star to fix absolute position (though all such measurements are relative of course and there are no absolutes in space). With no Kalman filter you would need to somehow combine the Gyro and Accelerometer readings using a cruder method. You would also need to integrate and this gives drift and errors.
@monishagowri1902
@monishagowri1902 2 жыл бұрын
can i get the code?
@KennyFairweather
@KennyFairweather 3 жыл бұрын
Nice
@TJMoir
@TJMoir 3 жыл бұрын
I re did the other one in higher res too.
@satyabratasenapati7376
@satyabratasenapati7376 7 ай бұрын
Very useful 😂
@ahmedbelhcine1441
@ahmedbelhcine1441 3 жыл бұрын
can I get the code? I have esp32 and MPU6050 and I wanna get real time tilt angle for my self balancing robot :( can u help?
@TJMoir
@TJMoir 3 жыл бұрын
Is this just a hobby or a project from university?
@stasjurgensons7008
@stasjurgensons7008 7 ай бұрын
@@TJMoir Dear Tom Moir. I do for Uni. I am writing my bachelor paper about comparison of sensor fusion algorithms for UAV sensor fusion. At the same time we are building high power rocket in university and I am contributing as navigation system designer. For some reason I can not access your book "feedback" via uni library even though second one book "Rudiments of Signal Processing and Systems" is available. May be you can provide some useful materials that can contribute to my understanding of developing complex discrete Kalman filter to fuse all UAV sensors. As with my current understanding most likely I would cascade complementary filters.
@TJMoir
@TJMoir 7 ай бұрын
@@stasjurgensons7008 Send me an email at tomspeechnzREMOVESPAM@gmail.com but remove cap letters.
@TJMoir
@TJMoir 7 ай бұрын
Code is in comment here by me. Latest comment
@StevenCookFX
@StevenCookFX 2 жыл бұрын
There is no Arduino language. Its embedded C. Arduino is a IDE
@TJMoir
@TJMoir 2 жыл бұрын
Yes fair enough agreed
@andresilva_bjj
@andresilva_bjj 2 жыл бұрын
no code, no like.
@TJMoir
@TJMoir 7 ай бұрын
Posted code in a comment. Too big to go in the description.
Accelerometers and Gyroscopes - Sensor Fusion #1 - Phil's Lab #33
14:50
Kalman Filter - Part 1
8:35
Machine Learning TV
Рет қаралды 107 М.
She's very CREATIVE💡💦 #camping #survival #bushcraft #outdoors #lifehack
00:26
Всё пошло не по плану 😮
00:36
Miracle
Рет қаралды 3,3 МЛН
Flipping Robot vs Heavier And Heavier Objects
00:34
Mark Rober
Рет қаралды 59 МЛН
Friends make memories together part 2  | Trà Đặng #short #bestfriend #bff #tiktok
00:18
Embedded Kalman Filtering
31:23
T.J Moir
Рет қаралды 6 М.
Drone Control and the Complementary Filter
11:13
Brian Douglas
Рет қаралды 115 М.
Sensor Fusion:  Extended Kalman Filter - Autonomous Car Motion Estimation
35:45
Al-khwarizmi (الخوارزمى)
Рет қаралды 18 М.
15 | Combine a gyroscope and accelerometer to measure angles - precisely
9:49
She's very CREATIVE💡💦 #camping #survival #bushcraft #outdoors #lifehack
00:26