• imu校准


    之前对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

  • 相关阅读:
    吴恩达 机器学习EX1学习笔记 MATLAB实现
    二分法解具有单调性的方程
    利用new定位运算符进行高效的数组动态增扩
    单循环链表基本操作及部分可能出现的细节问题
    数组中某元素的删除
    C# 实现可克隆(ICloneable)的类型
    Python学习十三
    Python学习十二
    Python学习十一
    Python学习十
  • 原文地址:https://www.cnblogs.com/miaorn/p/13985173.html
Copyright © 2020-2023  润新知