赵欣1994

赵欣1994

0个粉丝

4

问答

0

专栏

0

资料

赵欣1994  发布于  2015-10-02 22:48:32
采纳率 0%
4个问答
3781

使用了网上的姿态融合算法,波动好大,求指导


     我用的是arduino mega2560 和一块10 DOF IMU sensor,上面集成了MPU6050和HMC5883L,拷入代码后做了实验,pitch角从0摆到45度再恢复水平,得到的数据绘图如下

波动太大,请问各位大神我的代码有什么问题呢?代码附上

[code]
#include
#include
#include
#include
#include
#include "I2Cdev.h"
#include "MPU6050.h"
#include"math.h"
#define Kp 2.0f
#define Ki 0.001f
#define halfT 0.3f
//----------------------------------------------------------------------------------------------------
// Variable definitions
float q0 = 1, q1 = 0, q2 = 0, q3 = 0;
float exInt = 0, eyInt = 0, ezInt = 0,pitch,yaw;
const int SampleTime=600;

MPU6050 accelgyro;

int ax,ay,az;
int16_t gx,gy,gz;
float angles[3]; // yaw pitch roll
float heading,mx,my,mz;
float Ax,Ay,Az,Gx,Gy,Gz;
short temperature;
long pressure;

// Set the FreeSixIMU object
FreeSixIMU sixDOF = FreeSixIMU();

HMC5883L compass;
// Record any errors that may occur in the compass.
int error = 0;

void setup(){

  Serial.begin(115200);
  Wire.begin();

  delay(5);
  sixDOF.init(); //init the Acc and Gyro
  delay(5);
  compass = HMC5883L(); // init HMC5883
  accelgyro.initialize();
  
  error = compass.SetScale(1.3); // Set the scale of the compass.
  error = compass.SetMeasurementMode(Measurement_Continuous); // Set the measurement mode to Continuous  
  if(error != 0) // If there is an error, print it out.
    Serial.println(compass.GetErrorText(error));

  bmp085Calibration(); // init barometric pressure sensor

}

void loop(){
  accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);
  Ax=(float)ax/16384;
    Ay=(float)ay/16384;
    Az=(float)az/16384;
    Gx=(gx/32.8+6)/57.3;
    Gy=(gy/32.8-5)/57.3;
  Gz=(gz/32.8-155)/57.3;
  temperature = bmp085GetTemperature(bmp085ReadUT());
  pressure = bmp085GetPressure(bmp085ReadUP());
  MagnetometerRaw raw = compass.ReadRawAxis();
  MagnetometerScaled scaled = compass.ReadScaledAxis();
   mx=scaled.XAxis;
   my=scaled.YAxis;
    mz=scaled.ZAxis;
  AHRSupdate(Gx,Gy,Gz,Ax,Ay,Az,mx,my,mz);
  PrintData();
  
  delay(0);
}

void PrintData(){
  


  Serial.print(pitch);
  Serial.println("  ");

  
}

void AHRSupdate(float gx, float gy, float gz, float ax, float ay, float az, float mx, float my, float mz) {
unsigned long now,timeChange;
static unsigned long lastTime=0;
  now = micros();                                 //us
  timeChange =now - lastTime;
  if(timeChange>=SampleTime){
    lastTime = now;
  
  float norm;
float hx, hy, hz, bx, bz;
float vx, vy, vz, wx, wy, wz;
float ex, ey, ez,lastex,lastey,lastez;

float q0q0 = q0*q0;
float q0q1 = q0*q1;
float q0q2 = q0*q2;
float q0q3 = q0*q3;
float q1q1 = q1*q1;
float q1q2 = q1*q2;
float q1q3 = q1*q3;
float q2q2 = q2*q2;  
float q2q3 = q2*q3;
float q3q3 = q3*q3;         

norm = sqrt(ax*ax + ay*ay + az*az);      
ax = ax / norm;                                                           
ay = ay / norm;
az = az / norm;
norm = sqrt(mx*mx + my*my + mz*mz);                                      
mx = mx / norm;
my = my / norm;
mz = mz / norm;        

hx = 2*mx*(0.5 - q2q2 - q3q3) + 2*my*(q1q2 - q0q3) + 2*mz*(q1q3 + q0q2);  
hy = 2*mx*(q1q2 + q0q3) + 2*my*(0.5 - q1q1 - q3q3) + 2*mz*(q2q3 - q0q1);
hz = 2*mx*(q1q3 - q0q2) + 2*my*(q2q3 + q0q1) + 2*mz*(0.5 - q1q1 - q2q2);        
bx = sqrt((hx*hx) + (hy*hy));                                             
bz = hz;      

vx = 2*(q1q3 - q0q2);                                                     
vy = 2*(q0q1 + q2q3);
vz = q0q0 - q1q1 - q2q2 + q3q3;

wx = 2*bx*(0.5 - q2q2 - q3q3) + 2*bz*(q1q3 - q0q2);                     
wy = 2*bx*(q1q2 - q0q3) + 2*bz*(q0q1 + q2q3);
wz = 2*bx*(q0q2 + q1q3) + 2*bz*(0.5 - q1q1 - q2q2);  

ex = (ay*vz - az*vy) + (my*wz - mz*wy);
ey = (az*vx - ax*vz) + (mz*wx - mx*wz);
ez = (ax*vy - ay*vx) + (mx*wy - my*wx);

exInt = exInt + ex*Ki;
eyInt = eyInt + ey*Ki;
ezInt = ezInt + ez*Ki;



gx = gx + Kp*ex + exInt;
gy = gy + (Kp*ey + eyInt);
gz = gz + (Kp*ez + ezInt);




q0 = q0 + (-q1*gx - q2*gy - q3*gz)*halfT;                        
q1 = q1 + (q0*gx + q2*gz - q3*gy)*halfT;
q2 = q2 + (q0*gy - q1*gz + q3*gx)*halfT;
q3 = q3 + (q0*gz + q1*gy - q2*gx)*halfT;  

norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);   
q0 = q0 / norm;
q1 = q1 / norm;
q2 = q2 / norm;
q3 = q3 / norm;


yaw= atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3;
pitch= asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3;
  }
}
[/code]
我来回答
回答0个
时间排序
认可量排序
易百纳技术社区暂无数据
或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区