搜索
bottom↓
回复: 30

分享一个3天时间做得飞控程序,通俗易懂

[复制链接]

出0入0汤圆

发表于 2014-5-13 21:52:35 | 显示全部楼层 |阅读模式
本帖最后由 sdu1028 于 2014-5-14 14:56 编辑

因为之前仿过MK的四轴,不过没做过软件。上次五一假期自己写了下飞控算法弥补一下。简单粗暴,直接有效

code全是自己做的,最简单的complementary filter,加RPY的PID控制。事实证明这种简单的算法还是最有效的,其实大部分时间都耗在调参数上。

用的Arduino的板子和GY-88 IMU snesor,还有一个超声测距模块,用来定高。
遥控用串口转蓝牙模块,还写了一个Android App来控制。


上video,还算稳定:

http://v.youku.com/v_show/id_XNzExNTc4ODIw.html

http://v.youku.com/v_show/id_XNzExODU1NTMy.html

附PID控制部分的code:

void loop()
{
        dt_us_=micros()-time_us_;
        time_us_=micros();

        //There's no delays in this sketch while doing distance pings.
          if (millis() >= pingTimer) {
                pingTimer += pingSpeed;      // Set the next ping time.
                sonarAltitude.ping_timer(echoCheck); // Send out the ping
          }

        //update IMU data
        IMU_proc();
        rotation_x = imu_data[1] - sensor_to_ground_bias[1];
        rotation_y = imu_data[2] - sensor_to_ground_bias[2];
        rotation_z = imu_data[3] - sensor_to_ground_bias[3];

        //Caculate average rotation speed, degrees per 100ms
        float drotation_x = 100.0f*(rotation_x - hrotation_x)/(((float)dt_us_)/1000.0f);
        float drotation_y = 100.0f*(rotation_y - hrotation_y)/(((float)dt_us_)/1000.0f);
        float drotation_z = 100.0f*(rotation_z - hrotation_z)/(((float)dt_us_)/1000.0f);

        //serialPrintRotation();
        //printserialChart();
        getSerial3Cmd();

        //PD Balance Control
        adjustAC = - ( P_ * (rotation_x - desired_pitch_x) - D_ * drotation_x );
        adjustBD = - ( P_ * (rotation_y - desired_pitch_y) - D_ * drotation_y );

        //PD Yaw control
        desired_heading = hrotation_z;
        heading_integ_value = rotation_z-lock_yaw;// + I_HEADING_*(rotation_z -desired_heading);

        float heading_trim = heading_integ_value*P_HEADING_ - drotation_z* D_HEADING_;
        heading_trim = limitAbs(heading_trim, HEADING_TREIM_LIMIT);

        //PID controller for altitude
        float altitude_trim = - P_ALT_T_ * (sonar_altitude_cm_ - desired_altitude) - D_ALT_T_*daltitude_cm_;
        altitude_trim = limitAbs(altitude_trim, MAX_ALTI_TRIM );

        //limit max speed
        speeda=limitMAXSPD(upspeed + adjustAC + heading_trim + altitude_trim);
        speedb=limitMAXSPD(upspeed + adjustBD - heading_trim + altitude_trim);
        speedc=limitMAXSPD(upspeed - adjustAC + heading_trim + altitude_trim);
        speedd=limitMAXSPD(upspeed - adjustBD - heading_trim + altitude_trim);

        //update speed
        setFormatedSpeed(1, speeda); //a
        setFormatedSpeed(2, speedb); //b
        setFormatedSpeed(3, speedc); //c
        setFormatedSpeed(4, speedd); //d

        //Record history rotation
        hrotation_x = rotation_x;
        hrotation_y = rotation_y;
        hrotation_z = rotation_z;

        dt_us_=micros()-time_us_;

        if(dt_us_ < CONTROL_CYCLE_US)
        delayMicroseconds(CONTROL_CYCLE_US-dt_us_); //delay to 5ms ->200Hz
}

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2014-5-13 22:03:09 | 显示全部楼层
之前做两轮平衡载人小车,也是用这样简单粗暴的算法,没整那么多,也还行吧。。。

出0入0汤圆

发表于 2014-5-13 22:43:24 | 显示全部楼层
效果很不错啊,这是只用到了PD控制吗?调PD参数大概有什么诀窍吗?我用的也是这种方法,但是目前发现四轴很不稳定,卡在参数调节上了。还在考虑要不要寻找更复杂点的控制方法呢。

出0入0汤圆

发表于 2014-5-13 22:44:03 | 显示全部楼层
你的处理器是什么核心,貌似很牛的样子!

出105入79汤圆

发表于 2014-5-13 22:52:51 | 显示全部楼层
简单的complementary filter 一旦yaw快速旋转就崩。。没有滤除向心加速度

出0入0汤圆

 楼主| 发表于 2014-5-13 23:31:22 | 显示全部楼层
qwe2231695 发表于 2014-5-13 22:52
简单的complementary filter 一旦yaw快速旋转就崩。。没有滤除向心加速度

对呀,所以在程序里面把yaw lock了

出0入0汤圆

 楼主| 发表于 2014-5-13 23:38:01 | 显示全部楼层
ad1984fr 发表于 2014-5-13 22:43
效果很不错啊,这是只用到了PD控制吗?调PD参数大概有什么诀窍吗?我用的也是这种方法,但是目前发现四轴很 ...

只是pd,调的时候把它绑起来,先只开一个轴,开到大概悬停时的油门,然后先p后d。能稳定飞了再yaw。然后定高。
控制器用的Arduino mega,就是avr

出0入0汤圆

发表于 2014-5-13 23:45:22 | 显示全部楼层
sdu1028 发表于 2014-5-13 23:31
对呀,所以在程序里面把yaw lock了

恩。大概明白调试的流程了,我现在两个参数同时调,怎么都不行,原来是方法有问题。谢谢!目前我的YAW也lock了,感觉确实会崩。

出0入0汤圆

发表于 2014-5-14 00:01:33 | 显示全部楼层
真勇敢.  大四轴也敢用手机控制.   

出0入0汤圆

发表于 2014-5-14 08:52:16 | 显示全部楼层
qwe2231695 发表于 2014-5-13 22:52
简单的complementary filter 一旦yaw快速旋转就崩。。没有滤除向心加速度

那怎么做才能滤除向心加速度呢?

出0入0汤圆

 楼主| 发表于 2014-5-14 15:04:48 | 显示全部楼层
SMC 发表于 2014-5-14 08:52
那怎么做才能滤除向心加速度呢?

我是加上了对合加速度的判断,如果和加速度比重力大于一定范围就丢弃这一帧的值

这是code:

  float alpha = 0.98f;

  //if acce is beyond normal gravity
  if( abs( square((float)accel_x) + square((float)accel_y) + square((float)accel_z ) - GRAVITY_REF) > GRAVITY_REF*0.03f )
  {
      alpha=1.0f;
  }

  float angle_x = alpha*gyro_angle_x + (1.0 - alpha)*accel_angle_x;
  float angle_y = alpha*gyro_angle_y + (1.0 - alpha)*accel_angle_y;
  float angle_z = gyro_angle_z; //Accelerometer doesn't give z-angle

出0入0汤圆

发表于 2014-5-14 15:15:45 | 显示全部楼层
sdu1028 发表于 2014-5-14 15:04
我是加上了对合加速度的判断,如果和加速度比重力大于一定范围就丢弃这一帧的值

这是code:

是个好主意,但我觉得应该还有别的法子解决。

出100入101汤圆

发表于 2014-5-14 15:32:12 | 显示全部楼层
sdu1028 发表于 2014-5-13 23:38
只是pd,调的时候把它绑起来,先只开一个轴,开到大概悬停时的油门,然后先p后d。能稳定飞了再yaw。然后 ...

不是“程序里面把yaw lock”了么?

出0入0汤圆

 楼主| 发表于 2014-5-14 15:36:42 | 显示全部楼层
fengyunyu 发表于 2014-5-14 15:32
不是“程序里面把yaw lock”了么?

靠对Yaw的PID控制lock yaw

出0入0汤圆

发表于 2014-5-15 23:37:30 | 显示全部楼层
mark一下备用

出0入0汤圆

发表于 2014-5-16 10:25:04 | 显示全部楼层
楼主可否分享一下定高的想法。因为在只有姿态控制的情况下,四旋翼一下子飞高一下子飞低,看着就不很爽。

出0入0汤圆

 楼主| 发表于 2014-5-16 15:56:37 | 显示全部楼层
976717326 发表于 2014-5-16 10:25
楼主可否分享一下定高的想法。因为在只有姿态控制的情况下,四旋翼一下子飞高一下子飞低,看着就不很爽。 ...

也是靠PID控制。高度小于30cm的时候油门是加油门,大于30cm的时候,高度PID控制启用,油门是改变PID的的desired hight
超声波测距做反馈。
当然会比较不靠谱,比如下面遇到一个花盆什么的就忽然高了。

出0入0汤圆

发表于 2014-6-9 04:02:58 | 显示全部楼层
sdu1028 发表于 2014-5-14 15:04
我是加上了对合加速度的判断,如果和加速度比重力大于一定范围就丢弃这一帧的值

这是code:

这么做是一种很危险的行为,虽然我没想出更好的办法,但是不推荐这样做

出0入0汤圆

发表于 2014-6-9 04:05:04 | 显示全部楼层
qwe2231695 发表于 2014-5-13 22:52
简单的complementary filter 一旦yaw快速旋转就崩。。没有滤除向心加速度

虽然你不愿意讲如何滤除向心加速度,但我在查这个的时候发现了一个更严重的问题。

出105入79汤圆

发表于 2014-6-9 09:27:05 | 显示全部楼层
SMC 发表于 2014-6-9 04:05
虽然你不愿意讲如何滤除向心加速度,但我在查这个的时候发现了一个更严重的问题。 ...

我也没有办法滤除啊,只有yaw转速大时优化一下而已。你还发现了什么。

出0入0汤圆

发表于 2014-6-9 09:31:11 | 显示全部楼层
MARK以备后用顺便帮顶!

出0入0汤圆

发表于 2014-6-9 12:29:35 | 显示全部楼层
qwe2231695 发表于 2014-6-9 09:27
我也没有办法滤除啊,只有yaw转速大时优化一下而已。你还发现了什么。

这个问题可能只有我才犯得,就是直接积分每个轴数据当角度在有些情况下误差会很大。

出0入0汤圆

发表于 2014-6-9 12:44:10 | 显示全部楼层
mark。。。。。。。

出0入0汤圆

发表于 2014-6-9 15:19:33 | 显示全部楼层
MSRA的同学 你好。。

出0入0汤圆

 楼主| 发表于 2014-6-10 02:21:20 | 显示全部楼层
Surfire 发表于 2014-6-9 15:19
MSRA的同学 你好。。

楼上也在msra么

出0入0汤圆

 楼主| 发表于 2014-6-10 02:23:35 | 显示全部楼层
SMC 发表于 2014-6-9 04:02
这么做是一种很危险的行为,虽然我没想出更好的办法,但是不推荐这样做 ...

没有,实际证明这个方法很安全。现在加了optical的sensor后可以一直悬停十分钟到没电

出0入0汤圆

 楼主| 发表于 2014-6-10 02:25:53 | 显示全部楼层
SMC 发表于 2014-6-9 12:29
这个问题可能只有我才犯得,就是直接积分每个轴数据当角度在有些情况下误差会很大。
...

gyro有yaw的反馈,直接限制yaw的速度就是了。

出0入0汤圆

发表于 2014-6-10 09:10:20 | 显示全部楼层
感觉不错 很好

出0入0汤圆

发表于 2014-6-12 01:13:58 | 显示全部楼层

上个月底刚checkout
看到你的帖子小小的吃惊了一下 好像还看到过你的灰机

出0入0汤圆

发表于 2014-6-14 23:09:22 | 显示全部楼层
有点晃        

出0入0汤圆

发表于 2014-7-2 15:57:12 | 显示全部楼层
跪拜大神。请问姿态解算的部分能否交流一下。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 19:13

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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