极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

楼主: comet1989

arduino 四軸飛行器 問題

[复制链接]
 楼主| 发表于 2013-7-19 15:55:42 | 显示全部楼层
目前程式修改的進度
  1. #include "Wire.h"
  2. #include "I2Cdev.h"
  3. #include "MPU6050.h"
  4. #include "PID_v1.h"
  5. #include  "Servo.h"

  6. Servo myservo;
  7. Servo myservo1;
  8. MPU6050 accelgyro;

  9. unsigned long now, lastTime = 0;
  10. float dt;                                   //微分时间
  11. /**********************************************************************/
  12. int16_t ax, ay, az, gx, gy, gz;             //加速度计陀螺仪原始数据
  13. float aax=0, aay=0, agx=0, agy=0, agz=0;    //角度变量
  14. long axo = 0, ayo = 0, azo = 0;             //加速度计偏移量
  15. long gxo = 0, gyo = 0, gzo = 0;             //陀螺仪偏移量

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

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

  22. float a_x[10]={0}, a_y[10]={0} ,g_x[10]={0} ,g_y[10]={0}; //加速度计协方差计算队列
  23. float Px=1, Rx, Kx, Sx, Vx, Qx;             //x轴卡尔曼变量
  24. float Py=1, Ry, Ky, Sy, Vy, Qy;             //y轴卡尔曼变量
  25. /**********************************************************************/
  26. double Kp=0.2; //Initial Proportional Gain
  27. double Ki=0; //Initial Integral Gain
  28. double Kd=0; //Initial Differential Gain
  29. double  Input,Output,Output1,Output2,Output1_old=10,Output2_old=10;
  30. double  Setpoint=0;
  31. int  Direction;
  32. PID myPID(&Input, &Output, &Setpoint,Kp,Ki,Kd, DIRECT);

  33. void setup() {
  34.   Wire.begin();
  35.   Serial.begin(9600);

  36.   accelgyro.initialize();                 //初始化

  37.   unsigned short times = 200;             //采样次数
  38.   for(int i=0;i<times;i++){
  39.     accelgyro.getMotion6(&ax, &ay, &az, &gx, &gy, &gz); //读取六轴原始数值
  40.     axo += ax; ayo += ay; azo += az;      //采样和
  41.     gxo += gx; gyo += gy; gzo += gz;
  42.   }
  43.   axo /= times; ayo /= times; azo /= times; //计算加速度计偏移
  44.   gxo /= times; gyo /= times; gzo /= times; //计算陀螺仪偏移
  45.   
  46.   myPID.SetMode(AUTOMATIC);  
  47.   myservo.attach(5,1000,2000);
  48.   myservo1.attach(6,1000,2000);
  49.   delay(100);
  50.   myservo.writeMicroseconds(1000);
  51.   myservo1.writeMicroseconds(1000);
  52.   delay(2000);
  53.   
  54. }

  55. void loop(){
  56.   MPU6050_Angle();

  57. if(agy<0)
  58. {
  59.     Input = agy;
  60.     myPID.Compute();
  61.     Output1 = Output + 14;
  62. //    Output1_old = Output1;
  63.     Output2 = Output2_old;
  64. }
  65. else
  66. {
  67.     Input = -1 * agy;
  68.     myPID.Compute();
  69.     Output2 = Output + 10.5;
  70. //    Output2_old = Output2;
  71.     Output1 = Output1_old;
  72. }
  73. if((Output1)>=180)
  74. {
  75.   Output1 = 180;
  76.   myservo.write(Output1);
  77.   myservo1.write(Output2);
  78. }
  79. else if((Output2)>=180)
  80. {
  81.   Output2 = 180;
  82.   myservo.write(Output1);
  83.   myservo1.write(Output2);
  84. }
  85. else
  86. {
  87.   myservo.write(Output1);
  88.   myservo1.write(Output2);
  89. }
  90. //    Output1_old = Output1;
  91. //    Output2_old = Output2;
  92. //  delay(15);
  93. /*  Serial.print(agx);Serial.print(",");
  94.   Serial.print(agy);Serial.println();*/
  95.   Serial.print(agx); Serial.print("\t");
  96.   Serial.print(agy); Serial.print("\t");
  97.   Serial.print(Output1); Serial.print("\t");
  98.   Serial.println(Output2);
  99. }

  100. void  MPU6050_Angle()
  101. {
  102.   unsigned long now = millis();             //当前时间(ms)
  103.   dt = (now - lastTime) / 1000.0;           //微分时间(s)
  104.   lastTime = now;                           //上一次采样时间(ms)

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

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

  109.   aax = atan(accy / accz) * (-180) / pi;    //x轴对于水平面的夹角
  110.   aay = atan(accx / accz) * 180 / pi;       //y轴对于水平面的夹角

  111.   aax_sum = 0;                              // 对于加速度计原始数据的滑动加权滤波算法
  112.   aay_sum = 0;
  113.   for(int i=1;i<n_sample;i++){
  114.     aaxs[i-1] = aaxs[i];
  115.     aax_sum += aaxs[i] * i;
  116.     aays[i-1] = aays[i];
  117.     aay_sum += aays[i] * i;
  118.   }
  119.   aaxs[n_sample-1] = aax;
  120.   aax_sum += aax * n_sample;
  121.   aax = (aax_sum / (11*n_sample/2.0)) * 9 / 7.0; //角度调幅至0-90°
  122.   aays[n_sample-1] = aay;                        //此处应用实验法取得合适的系数
  123.   aay_sum += aay * n_sample;                     //本例系数为9/7
  124.   aay = (aay_sum / (11*n_sample/2.0)) * 9 / 7.0;

  125.   float gyrox = - (gx-gxo) / GyroRatio * dt; //x轴角速度
  126.   float gyroy = - (gy-gyo) / GyroRatio * dt; //y轴角速度
  127.   agx += gyrox;                             //x轴角速度积分
  128.   agy += gyroy;                             //x轴角速度积分

  129.   /* kalmen start */
  130.   Sx = 0; Rx = 0;
  131.   Sy = 0; Ry = 0;
  132.   for(int i=1;i<10;i++){                 //测量值平均值运算
  133.     a_x[i-1] = a_x[i];                      //即加速度平均值
  134.     Sx += a_x[i];
  135.     a_y[i-1] = a_y[i];
  136.     Sy += a_y[i];
  137.   }
  138.   a_x[9] = aax;
  139.   Sx += aax;
  140.   Sx /= 10;                                 //x轴加速度平均值
  141.   a_y[9] = aay;
  142.   Sy += aay;
  143.   Sy /= 10;                                 //y轴加速度平均值

  144.   for(int i=0;i<10;i++){
  145.     Rx += sq(a_x[i] - Sx);
  146.     Ry += sq(a_y[i] - Sy);
  147.   }
  148.   Rx = Rx / 9;                              //得到方差
  149.   Ry = Ry / 9;                        

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

  154.   Py = Py + 0.0025;
  155.   Ky = Py / (Py + Ry);
  156.   agy = agy + Ky * (aay - agy);
  157.   Py = (1 - Ky) * Py;
  158. }
复制代码
用最笨的方式來做
不過還是不能平衡
這邊還要再想看看
回复 支持 反对

使用道具 举报

发表于 2013-7-19 16:19:48 | 显示全部楼层
你如果是想学习做飞控并且体验个中的味道,这样一步步来是可以的,否则建议你直接去学习人家开源的APM或者WMC,都是基于MEGA2560的!

如果想一边学一边做得更好,就不要用MEGA2560这种8位MCU了,直接用ARM吧,后期还能加上视频什么的......
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-19 23:21:25 | 显示全部楼层
拾瑞 发表于 2013-7-19 16:19
你如果是想学习做飞控并且体验个中的味道,这样一步步来是可以的,否则建议你直接去学习人家开源的APM或者WMC ...

我有去看過人家開源的程式碼~
只是都看不懂~
至於為啥不用ARM的問題嘛~
因為小弟我還是學生~沒那麼多$$再去買其他的東西
只能用現有的板子來玩囉~
回复 支持 反对

使用道具 举报

发表于 2013-7-20 09:43:30 | 显示全部楼层
哎,真心劝你一句,如果还没有一定的水平,而且是一个人战斗,你的四轴是飞不起来的......飞控是非常专业的东西,如果看不明白开源的代码,你又把重心再放到飞控上,就是唐诘柯德战风车啊!
回复 支持 反对

使用道具 举报

发表于 2013-7-20 19:27:16 | 显示全部楼层
comet1989 发表于 2013-7-19 15:52
視頻方面我會在處理一下

我們這邊鎖掉了你們的一些視頻網站

谢谢楼主!!!
回复 支持 反对

使用道具 举报

发表于 2013-7-20 19:29:17 | 显示全部楼层
comet1989 发表于 2013-7-19 15:51
目前用2560只是做測試~
因為手邊就只有這塊~

恩恩!楼主厉害,我也打算做一个用来研究算法,最后就直接集成到一个很小的主板上,方便的安装就可以飞行,
回复 支持 反对

使用道具 举报

发表于 2013-7-20 20:36:33 | 显示全部楼层
comet1989 发表于 2013-7-19 15:55
目前程式修改的進度用最笨的方式來做
不過還是不能平衡
這邊還要再想看看

您好:
我也是台灣人,最近也再做四軸,還飛不起來><,樓主的程式沒用到PID嗎??
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-22 16:15:21 | 显示全部楼层
本帖最后由 comet1989 于 2013-7-22 16:17 编辑
TTTTTTT33 发表于 2013-7-20 20:36
您好:
我也是台灣人,最近也再做四軸,還飛不起來>


目前PID指有用一小部份而已~
要如何讓它能平衡就是難的地方哩
這邊就需要各位大大們的幫忙了~
回复 支持 反对

使用道具 举报

 楼主| 发表于 2013-7-22 16:16:30 | 显示全部楼层
学慧放弃 发表于 2013-7-20 19:29
恩恩!楼主厉害,我也打算做一个用来研究算法,最后就直接集成到一个很小的主板上,方便的安装就可以飞行 ...

我也沒有很厲害
我都是看論壇上大家的文章學來的
希望大家能一起討論這個問題吧~
回复 支持 反对

使用道具 举报

发表于 2013-7-22 16:17:35 | 显示全部楼层
comet1989 发表于 2013-7-22 16:16
我也沒有很厲害
我都是看論壇上大家的文章學來的
希望大家能一起討論這個問題吧~

嗯嗯,            
回复 支持 反对

使用道具 举报

发表于 2013-7-22 16:37:12 | 显示全部楼层
拾瑞 发表于 2013-7-20 09:43
哎,真心劝你一句,如果还没有一定的水平,而且是一个人战斗,你的四轴是飞不起来的......飞控是非常专业的东西 ...

小弟也是学生,想一步一步学飞控。。。求指点,从哪里学起?
回复 支持 反对

使用道具 举报

发表于 2013-7-27 12:26:21 | 显示全部楼层
comet1989 发表于 2013-7-22 16:15
目前PID指有用一小部份而已~
要如何讓它能平衡就是難的地方哩
這邊就需要各位大大們的幫忙了~

請問您是用pid函式庫??還是自己寫的??
回复 支持 反对

使用道具 举报

发表于 2013-7-27 12:56:31 | 显示全部楼层
拾瑞 发表于 2013-7-17 16:11
楼主台湾的吧!你的影片我们看不到的!

1,kalmen有个库文件的;

你用mpu6050的动dmp能读出正确的四元数,然后输出pyr吗?我用库里的例程貌似有问题,读出来pyr数据波动很大,加入延时300ms可以,但那样更新频率太低了,能说说你的办法吗?
回复 支持 反对

使用道具 举报

发表于 2013-7-27 23:11:09 | 显示全部楼层
看波形那是什么工具
回复 支持 反对

使用道具 举报

发表于 2013-7-28 10:29:49 | 显示全部楼层
ShadowWalker 发表于 2013-7-27 12:56
你用mpu6050的动dmp能读出正确的四元数,然后输出pyr吗?我用库里的例程貌似有问题,读出来pyr数据波动很 ...

用本论坛上的DMP库文件是可以的啊......
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-13 21:30 , Processed in 0.039943 second(s), 21 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表