之前对imu标定但不知道如何使用生成的.yaml文件
所以重新查找到新方法是对imu进行校准(所以校准和标定的区别是什么)
这里本打算使用树梅派通过IIC读取imu的数据即以前的博客
这里使用了arduino mega 2560对其进行校准
当芯片朝上水平放置(固定在某一位置)认为其处于一个初始状态,6轴所得理想值为下
ACC_X | ACC_Y | ACC_Z | GYR_X | GYR_Y | GYR_Z |
0 | 0 | 1G | 0 | 0 | 0 |
1G在数值上为16384
16位的寄存器,在2G的单位下,如下公式,除以两个2,一个2是因为分成正负两半,第二个2是2G,
1G=(2^16)/2/2=16384
放置好之后可能首次运行会得到
Sensor readings with offsets: -8 -3 16385 1 0 0
Your offsets: -3285 1272 623 -2 -26 -14
将Your offsets 的值放进65-70的代码中
然后在重复运行代码,将得到的Your offsets 再放入运行,直到Sensor readings with offsets的值接近理想值。
可以通过调整20,21行代码的值,来调整精确度,可以提高运行速度。
代码如下
1 // Arduino sketch that returns calibration offsets for MPU6050 // Version 1.1 (31th January 2014) 2 // Done by Luis Ródenas <luisrodenaslorda@gmail.com> 3 // Based on the I2Cdev library and previous work by Jeff Rowberg <jeff@rowberg.net> 4 // Updates (of the library) should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib 5 6 // These offsets were meant to calibrate MPU6050's internal DMP, but can be also useful for reading sensors. 7 // The effect of temperature has not been taken into account so I can't promise that it will work if you 8 // calibrate indoors and then use it outdoors. Best is to calibrate and use at the same room temperature. 9 10 11 12 // I2Cdev and MPU6050 must be installed as libraries 13 #include "I2Cdev.h" 14 #include "MPU6050.h" 15 #include "Wire.h" 16 17 /// CONFIGURATION / 18 //Change this 3 variables if you want to fine tune the skecth to your needs. 19 int averageAccount = 1000; //Amount of readings used to average, make it higher to get more precision but sketch will be slower (default:1000) 20 int acel_deadzone = 8; //Acelerometer error allowed, make it lower to get more precision, but sketch may not converge (default:8) 21 int giro_deadzone = 2; //Giro error allowed, make it lower to get more precision, but sketch may not converge (default:1) 22 23 // default I2C address is 0x68 24 // specific I2C addresses may be passed as a parameter here 25 // AD0 low = 0x68 (default for InvenSense evaluation board) 26 // AD0 high = 0x69 27 //MPU6050 accelgyro; 28 MPU6050 accelgyro(0x68); // <-- use for AD0 high 29 30 int16_t ax, ay, az, gx, gy, gz; 31 32 int mean_ax, mean_ay, mean_az, mean_gx, mean_gy, mean_gz, state = 0; 33 int ax_offset, ay_offset, az_offset, gx_offset, gy_offset, gz_offset; 34 35 /// SETUP 36 void setup() { 37 // join I2C bus (I2Cdev library doesn't do this automatically) 38 Wire.begin(); 39 // COMMENT NEXT LINE IF YOU ARE USING ARDUINO DUE 40 TWBR = 24; // 400kHz I2C clock (200kHz if CPU is 8MHz). Leonardo measured 250kHz. 41 42 // initialize serial communication 43 Serial.begin(115200); 44 45 // initialize device 46 accelgyro.initialize(); 47 48 // wait for ready 49 while (Serial.available() && Serial.read()); // empty buffer 50 while (!Serial.available()) { 51 Serial.println(F("Send any character to start sketch.")); 52 delay(1500); 53 } 54 while (Serial.available() && Serial.read()); // empty buffer again 55 56 // start message 57 Serial.println("MPU6050 Calibration Sketch"); 58 delay(2000); 59 Serial.println("Your MPU6050 should be placed in horizontal position, with package letters facing up. Don't touch it until you see a finish message."); 60 delay(3000); 61 // verify connection 62 Serial.println(accelgyro.testConnection() ? "MPU6050 connection successful" : "MPU6050 connection failed"); 63 delay(1000); 64 // reset offsets 65 accelgyro.setXAccelOffset(0); 66 accelgyro.setYAccelOffset(0); 67 accelgyro.setZAccelOffset(0); 68 accelgyro.setXGyroOffset(0); 69 accelgyro.setYGyroOffset(0); 70 accelgyro.setZGyroOffset(0); 71 } 72 73 /// LOOP 74 void loop() { 75 if (state == 0) { 76 Serial.println(" Reading sensors for first time..."); 77 meansensors(); 78 state++; 79 delay(1000); 80 } 81 82 if (state == 1) { 83 Serial.println(" Calculating offsets..."); 84 calibration(); 85 state++; 86 delay(1000); 87 } 88 89 if (state == 2) { 90 meansensors(); 91 Serial.println(" FINISHED!"); 92 Serial.print(" Sensor readings with offsets: "); 93 Serial.print(mean_ax); 94 Serial.print(" "); 95 Serial.print(mean_ay); 96 Serial.print(" "); 97 Serial.print(mean_az); 98 Serial.print(" "); 99 Serial.print(mean_gx); 100 Serial.print(" "); 101 Serial.print(mean_gy); 102 Serial.print(" "); 103 Serial.println(mean_gz); 104 Serial.print("Your offsets: "); 105 Serial.print(ax_offset); 106 Serial.print(" "); 107 Serial.print(ay_offset); 108 Serial.print(" "); 109 Serial.print(az_offset); 110 Serial.print(" "); 111 Serial.print(gx_offset); 112 Serial.print(" "); 113 Serial.print(gy_offset); 114 Serial.print(" "); 115 Serial.println(gz_offset); 116 Serial.println(" Data is printed as: acelX acelY acelZ giroX giroY giroZ"); 117 Serial.println("Check that your sensor readings are close to 0 0 16384 0 0 0"); 118 Serial.println("If calibration was succesful write down your offsets so you can set them in your projects using something similar to mpu.setXAccelOffset(youroffset)"); 119 while (1); 120 } 121 } 122 123 /// FUNCTIONS 124 void printOffset() 125 { 126 Serial.print(ax_offset); 127 Serial.print(" "); 128 Serial.print(ay_offset); 129 Serial.print(" "); 130 Serial.print(az_offset); 131 Serial.print(" "); 132 Serial.print(gx_offset); 133 Serial.print(" "); 134 Serial.print(gy_offset); 135 Serial.print(" "); 136 Serial.println(gz_offset); 137 } 138 139 void meansensors() { 140 long i = 0, buff_ax = 0, buff_ay = 0, buff_az = 0, buff_gx = 0, buff_gy = 0, buff_gz = 0; 141 142 while (i < (averageAccount + 101)) { 143 // read raw accel/gyro measurements from device 144 accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); 145 146 if (i > 100 && i <= (averageAccount + 100)) { //First 100 measures are discarded 147 buff_ax = buff_ax + ax; 148 buff_ay = buff_ay + ay; 149 buff_az = buff_az + az; 150 buff_gx = buff_gx + gx; 151 buff_gy = buff_gy + gy; 152 buff_gz = buff_gz + gz; 153 } 154 if (i == (averageAccount + 100)) { 155 mean_ax = buff_ax / averageAccount; 156 mean_ay = buff_ay / averageAccount; 157 mean_az = buff_az / averageAccount; 158 mean_gx = buff_gx / averageAccount; 159 mean_gy = buff_gy / averageAccount; 160 mean_gz = buff_gz / averageAccount; 161 } 162 i++; 163 delay(2); //Needed so we don't get repeated measures 164 } 165 } 166 167 void calibration() { 168 ax_offset = -mean_ax / 8; 169 ay_offset = -mean_ay / 8; 170 az_offset = (16384 - mean_az) / 8; 171 172 gx_offset = -mean_gx / 4; 173 gy_offset = -mean_gy / 4; 174 gz_offset = -mean_gz / 4; 175 176 while (1) { 177 int ready = 0; 178 accelgyro.setXAccelOffset(ax_offset); 179 accelgyro.setYAccelOffset(ay_offset); 180 accelgyro.setZAccelOffset(az_offset); 181 182 accelgyro.setXGyroOffset(gx_offset); 183 accelgyro.setYGyroOffset(gy_offset); 184 accelgyro.setZGyroOffset(gz_offset); 185 186 meansensors(); 187 188 printOffset(); 189 if (abs(mean_ax) <= acel_deadzone) ready++; 190 else ax_offset = ax_offset - mean_ax / acel_deadzone; 191 192 if (abs(mean_ay) <= acel_deadzone) ready++; 193 else ay_offset = ay_offset - mean_ay / acel_deadzone; 194 195 if (abs(16384 - mean_az) <= acel_deadzone) ready++; 196 else az_offset = az_offset + (16384 - mean_az) / acel_deadzone; 197 198 if (abs(mean_gx) <= giro_deadzone) ready++; 199 else gx_offset = gx_offset - mean_gx /giro_deadzone; 200 201 if (abs(mean_gy) <= giro_deadzone) ready++; 202 else gy_offset = gy_offset - mean_gy /giro_deadzone; 203 204 if (abs(mean_gz) <= giro_deadzone) ready++; 205 else gz_offset = gz_offset - mean_gz /giro_deadzone; 206 207 if (ready == 6) break; 208 } 209 }
可参考
https://wired.chillibasket.com/2015/01/calibrating-mpu6050/
https://blog.csdn.net/wulala789/article/details/99618189