基于mpu6050,arduino输出三维倾斜角度 云台-Arduino中文社区 - Powered by Discuz! Archiver

z01228 发表于 2020-10-27 14:10

基于mpu6050,arduino输出三维倾斜角度 云台

mpu6050六轴姿态传感器介绍MPU-6000为全球首例整合性6轴运动处理组件,整合了3轴陀螺仪、3轴加速器,解决了组合陀螺仪与加速器时存在的一些问题问题,还包含了内建的温度感测器、DMP(Digital Motion Processor)DMP:可以直接输出四元数,减少复杂的融合演算数据、感测器同步化、姿势感应等的负荷MPU-6000的角速度感测范围为±250、±500、±1000与±2000°/sec (dps),可以准确捕捉快速与慢速动作,用户可程式控制的加速器全格感测范围为±2g、±4g±8g与±16g。产品传输可透过最高至400kHz的I2C或最高达20MHz的SPI。/*网址 :https://blog.csdn.net/GuanFuXinCSDN/article/details/104859768
scl 连a5 ,sda 连a4
舵机按照程序接线
*/
#include "Wire.h"
#include "I2Cdev.h"
#include "MPU6050.h"
/*舵机*/
#include <Servo.h>
Servo myservo;//创建一个舵机控制对象
Servo myservo2;//创建一个舵机控制对象
// 使用Servo类最多可以控制8个舵机
MPU6050 accelgyro;

unsigned long now, lastTime = 0;
float dt;                                          //微分时间

int16_t ax, ay, az, gx, gy, gz;                   //加速度计和陀螺仪的原始数据
float aax=0, aay=0,aaz=0, agx=0, agy=0, agz=0;    //角度变量
long axo = 0, ayo = 0, azo = 0;                   //加速度计偏移量
long gxo = 0, gyo = 0, gzo = 0;                   //陀螺仪偏移量

float pi = 3.1415926;
float AcceRatio = 16384.0;                     //加速度计比例系数
float GyroRatio = 131.0;                        //陀螺仪比例系数

uint8_t n_sample = 8;                            //加速度计滤波算法采样个数
float aaxs = {0}, aays = {0}, aazs = {0};         //x,y轴采样队列
long aax_sum, aay_sum,aaz_sum;                     //x,y轴采样和

float a_x={0}, a_y={0},a_z={0} ,g_x={0} ,g_y={0},g_z={0};
float Px=1, Rx, Kx, Sx, Vx, Qx;             //x轴卡尔曼变量
float Py=1, Ry, Ky, Sy, Vy, Qy;             //y轴卡尔曼变量
float Pz=1, Rz, Kz, Sz, Vz, Qz;             //z轴卡尔曼变量

void setup()
{    myservo.attach(9);// 该舵机由arduino第九脚控制
      myservo2.attach(8);// 该舵机由arduino第八脚控制
    Wire.begin();
    Serial.begin(115200);

    accelgyro.initialize();               //初始化

    unsigned short times = 200;             //采样次数
    for(int i=0;i<times;i++)
    {
      accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); //读取六轴原始数值
      axo += ax; ayo += ay; azo += az;      
      gxo += gx; gyo += gy; gzo += gz;
   
    }
   
    axo /= times; ayo /= times; azo /= times; //计算加速度计偏移
    gxo /= times; gyo /= times; gzo /= times; //计算陀螺仪偏移
}

void loop()
{
    unsigned long now = millis();            //当前时间
    dt = (now - lastTime) / 1000.0;             //微分时间
    lastTime = now;                            //上一次采样时间

    accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);//读取六轴原始数值

    float accx = ax / AcceRatio;                //x轴加速度
    float accy = ay / AcceRatio;                //y轴加速度
    float accz = az / AcceRatio;                //z轴加速度

    aax = atan(accy / accz) * (-180) / pi;    //y轴对于z轴的夹角
    aay = atan(accx / accz) * 180 / pi;       //x轴对于z轴的夹角
    aaz = atan(accz / accy) * 180 / pi;       //z轴对于y轴的夹角

    aax_sum = 0;                               // 对于加速度计原始数据的滑动加权滤波算法
    aay_sum = 0;
    aaz_sum = 0;

    for(int i=1;i<n_sample;i++)
    {
      aaxs = aaxs;
      aax_sum += aaxs * i;
      aays = aays;
      aay_sum += aays * i;
      aazs = aazs;
      aaz_sum += aazs * i;
   
    }
   
    aaxs = aax;
    aax_sum += aax * n_sample;
    aax = (aax_sum / (11*n_sample/2.0)) * 9 / 7.0;    //角度调幅至0-90°
    aays = aay;                        //此处应用实验法取得合适的系数
    aay_sum += aay * n_sample;                        //本例系数为9/7
    aay = (aay_sum / (11*n_sample/2.0)) * 9 / 7.0;
    aazs = aaz;
    aaz_sum += aaz * n_sample;
    aaz = (aaz_sum / (11*n_sample/2.0)) * 9 / 7.0;

    float gyrox = - (gx-gxo) / GyroRatio * dt;   //x轴角速度
    float gyroy = - (gy-gyo) / GyroRatio * dt;    //y轴角速度
    float gyroz = - (gz-gzo) / GyroRatio * dt;    //z轴角速度
    agx += gyrox;                              //x轴角速度积分
    agy += gyroy;                           //x轴角速度积分
    agz += gyroz;
   
    /* kalman start */
    Sx = 0; Rx = 0;
    Sy = 0; Ry = 0;
    Sz = 0; Rz = 0;
   
    for(int i=1;i<10;i++)
    {                                          //测量值平均值运算
      a_x = a_x;                        //即加速度平均值
      Sx += a_x;
      a_y = a_y;
      Sy += a_y;
      a_z = a_z;
      Sz += a_z;
   
    }
   
    a_x = aax;
    Sx += aax;
    Sx /= 10;                                  //x轴加速度平均值
    a_y = aay;
    Sy += aay;
    Sy /= 10;                                  //y轴加速度平均值
    a_z = aaz;
    Sz += aaz;
    Sz /= 10;

    for(int i=0;i<10;i++)
    {
      Rx += sq(a_x - Sx);
      Ry += sq(a_y - Sy);
      Rz += sq(a_z - Sz);
   
    }
   
    Rx = Rx / 9;                               //得到方差
    Ry = Ry / 9;                        
    Rz = Rz / 9;

    Px = Px + 0.0025;                           // 0.0025在下面有说明...
    Kx = Px / (Px + Rx);                     //计算卡尔曼增益
    agx = agx + Kx * (aax - agx);            //陀螺仪角度与加速度计速度叠加
    Px = (1 - Kx) * Px;                        //更新p值

    Py = Py + 0.0025;
    Ky = Py / (Py + Ry);
    agy = agy + Ky * (aay - agy);
    Py = (1 - Ky) * Py;

    Pz = Pz + 0.0025;
    Kz = Pz / (Pz + Rz);
    agz = agz + Kz * (aaz - agz);
    Pz = (1 - Kz) * Pz;


    Serial.print(agx);Serial.print(",");
    Serial.print(agy);Serial.print(",");
    Serial.print(agz);Serial.println();
    myservo.write(agx);      // 指定舵机转向的角度
    delay(15);                     // 等待15ms让舵机到达指定位置
    myservo2.write(agy);      // 指定舵机转向的角度
    delay(15);                     // 等待15ms让舵机到达指定位置
   
}

志向成真 发表于 2021-3-27 09:18

请问图中的那段程序怎么把0到90度改为-45到45度的范围
页: [1]
查看完整版本: 基于mpu6050,arduino输出三维倾斜角度 云台