搜索
bottom↓
回复: 35

分析我的四轴串级PID代码O(∩_∩)O~

  [复制链接]

出0入85汤圆

发表于 2015-1-21 13:38:56 | 显示全部楼层 |阅读模式
从毕业到现在三年了,一直都很忙没时间折腾自己想玩的东西,现在辞职在家总算有时间了,哈哈。看到论坛这么多人玩四轴咱也凑凑热闹分享我传说中的串级PID,内环为角度环,外环为角速度。整定PID参数的时候先调外环,再调内环。
#include "CONTROL.h"
#include "IMU1.h"       
#include "moto.h"
#include "RFdate.h"
#include <math.h>
extern T_RC_Data                         Rc_D;                //遥控通道数据;

extern u8 txbuf[4];         //发送缓冲
extern u8 rxbuf[4];         //接收缓冲
extern u16 test1[3]; //接收到NRf24L01数据
extern S_INT16_XYZ ACC_F,GYRO_F;

PID PID_ROL,PID_PIT,PID_YAW;

extern S_INT16_XYZ        MPU6050_ACC_LAST,MPU6050_GYRO_LAST;       


int Motor_Ele=0;                                           //俯仰期望
int Motor_Ail=0;                                           //横滚期望

//u8 ARMED = 0;

//float rol_i=0,pit_i=0,yaw_p=0;
float thr=0;

S_FLOAT_XYZ EXP_ANGLE ,DIF_ANGLE;
PID1 PID_Motor;
/*********************************/
float Pitch_i,Roll_i,Yaw_i;                                   //积分项
float Pitch_old,Roll_old,Yaw_old;                 //角度保存
float Pitch_d,Roll_d,Yaw_d;          //微分项
float RC_Pitch,RC_Roll,RC_Yaw;                       //姿态角
float Pitch_shell_out,Roll_shell_out,Yaw_shell_out;//外环总输出
        //外环PID参数
float Pitch_shell_kp=280;//30 140
float Pitch_shell_kd=0;//
float Pitch_shell_ki=0;//
/*********************************/
float Roll_shell_kp=250;//30
float Roll_shell_kd=0;//10                 
float Roll_shell_ki=0;//0.08
/*********************************/
float Yaw_shell_kp=1.5;//10;//30
float Yaw_shell_kd=0;//10                 
float Yaw_shell_ki=0;//0.08;//0.08
float Gyro_radian_old_x,Gyro_radian_old_y,Gyro_radian_old_z;//陀螺仪保存
float pitch_core_kp_out,pitch_core_kd_out,Roll_core_kp_out,Roll_core_kd_out,Yaw_core_kp_out,Yaw_core_kd_out;//内环单项输出
float Pitch_core_out,Roll_core_out,Yaw_core_out;//内环总输出       
       
//内环PID参数
//float Pitch_core_kp=0.040;
//float Pitch_core_kd=0.008;////0.007;//0.07;
float Pitch_core_kp=0.040;
float Pitch_core_kd=0.002;////0.007;//0.07;

float Roll_core_kp=0.040;//;
float Roll_core_kd=0.002;////0.007;//06;//0.07;

float Yaw_core_kp=0.046;//;
float Yaw_core_kd=0.012;////0.007;//06;//0.07;


int16_t moto1=0,moto2=0,moto3=0,moto4=0;

float tempjd=0;
void CONTROL(float rol, float pit, float yaw)
{
       
         RC_Pitch=(Rc_D.PITCH-1500)/20;
       
        ////////////////////////外环角度环(PID)///////////////////////////////
  Pitch_i+=(Q_ANGLE.Pitch-RC_Pitch);
//-------------Pitch积分限幅----------------//
  if(Pitch_i>300) Pitch_i=300;
  else if(Pitch_i<-300) Pitch_i=-300;
//-------------Pitch微分--------------------//
  Pitch_d=Q_ANGLE.Pitch-Pitch_old;
//-------------Pitch  PID-------------------//
  Pitch_shell_out = Pitch_shell_kp*(Q_ANGLE.Pitch-RC_Pitch) + Pitch_shell_ki*Pitch_i + Pitch_shell_kd*Pitch_d;
//角度保存
  Pitch_old=Q_ANGLE.Pitch;
/*********************************************************/       
       
        RC_Roll=(Rc_D.ROLL-1500)/20;
        Roll_i+=(Q_ANGLE.Rool-RC_Roll);
//-------------Roll积分限幅----------------//
  if(Roll_i>300) Roll_i=300;
  else if(Roll_i<-300) Roll_i=-300;
//-------------Roll微分--------------------//
  Roll_d=Q_ANGLE.Rool-Roll_old;
//-------------Roll  PID-------------------//
  Roll_shell_out  = Roll_shell_kp*(Q_ANGLE.Rool-RC_Roll) + Roll_shell_ki*Roll_i + Roll_shell_kd*Roll_d;
//------------Roll角度保存------------------//
  Roll_old=Q_ANGLE.Rool;
       
       
        RC_Yaw=(Rc_D.YAW-1500)*10;
//-------------Yaw微分--------------------//
  Yaw_d=MPU6050_GYRO_LAST.Z-Yaw_old;
//-------------Roll  PID-------------------//
  Yaw_shell_out  = Yaw_shell_kp*(MPU6050_GYRO_LAST.Z-RC_Yaw) + Yaw_shell_ki*Yaw_i + Yaw_shell_kd*Yaw_d;
//------------Roll角度保存------------------//
  Yaw_old=MPU6050_GYRO_LAST.Z;
       
       
        ////////////////////////内环角速度环(PD)///////////////////////////////       
  pitch_core_kp_out = Pitch_core_kp * (Pitch_shell_out + MPU6050_GYRO_LAST.Y * 3.5);
  pitch_core_kd_out = Pitch_core_kd * (MPU6050_GYRO_LAST.Y   - Gyro_radian_old_y);

  Roll_core_kp_out  = Roll_core_kp  * (Roll_shell_out  + MPU6050_GYRO_LAST.X *3.5);
  Roll_core_kd_out  = Roll_core_kd  * (MPU6050_GYRO_LAST.X   - Gyro_radian_old_x);

  Yaw_core_kp_out  = Yaw_core_kp  * (Yaw_shell_out  + MPU6050_GYRO_LAST.Z * 1);
  Yaw_core_kd_out  = Yaw_core_kd  * (MPU6050_GYRO_LAST.Z   - Gyro_radian_old_z);
       
       
        Pitch_core_out = pitch_core_kp_out + pitch_core_kd_out;
  Roll_core_out  = Roll_core_kp_out  + Roll_core_kd_out;
  Yaw_core_out   = Yaw_core_kp_out   + Yaw_core_kd_out;

  Gyro_radian_old_y = MPU6050_GYRO_LAST.X;
  Gyro_radian_old_x = MPU6050_GYRO_LAST.Y;
  Gyro_radian_old_z = MPU6050_GYRO_LAST.Z;   //储存历史值
       
//--------------------将输出值融合到四个电机--------------------------------//

       
        if(Rc_D.THROTTLE>1020)
        {
  thr=Rc_D.THROTTLE- 1000;

//                if(Rc_D.THROTTLE<=2000)
//                {
//  moto1=(int16_t)(thr  - Pitch_core_out);//- yaw);
//        moto2=(int16_t)(thr  - Pitch_core_out);//+ yaw);       
//        moto3=(int16_t)(thr  + Pitch_core_out);// - yaw);
//        moto4=(int16_t)(thr  + Pitch_core_out);//+ yaw);       
   
//  moto1=(int16_t)(thr  - Roll_core_out);//- yaw);
//        moto2=(int16_t)(thr  + Roll_core_out);//+ yaw);       
//        moto3=(int16_t)(thr  + Roll_core_out);// - yaw);
//        moto4=(int16_t)(thr  - Roll_core_out);//+ yaw);

//  moto1=(int16_t)(thr  - Yaw_core_out);//- yaw);
//        moto2=(int16_t)(thr  + Yaw_core_out);//+ yaw);       
//        moto3=(int16_t)(thr  - Yaw_core_out);// - yaw);
//        moto4=(int16_t)(thr  + Yaw_core_out);//+ yaw);                       
                       
//moto1=(int16_t)(thr - Roll_core_out - Pitch_core_out);
//moto2=(int16_t)(thr + Roll_core_out - Pitch_core_out);       
//moto3=(int16_t)(thr + Roll_core_out + Pitch_core_out);
//moto4=(int16_t)(thr - Roll_core_out + Pitch_core_out);       
//                       
  moto1=(int16_t)(thr - Roll_core_out - Pitch_core_out- Yaw_core_out);
        moto2=(int16_t)(thr + Roll_core_out - Pitch_core_out+ Yaw_core_out);       
        moto3=(int16_t)(thr + Roll_core_out + Pitch_core_out- Yaw_core_out);
        moto4=(int16_t)(thr - Roll_core_out + Pitch_core_out+ Yaw_core_out);                       
                       
//                }
  }
        else
        {
                moto1 = 0;
                moto2 = 0;
                moto3 = 0;
                moto4 = 0;
        }
        MOTO_PWMRFLASH(moto1,moto2,moto3,moto4);//        Moto_PwmRflash(moto1,moto2,moto3,moto4);
}



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

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2015-1-21 18:48:37 | 显示全部楼层
支持支持。我这边也准备搞点飞控算法呢。

出0入0汤圆

发表于 2015-1-21 19:16:22 | 显示全部楼层
一直想做四轴,羡慕楼主啊。下家找到了吗

出0入85汤圆

 楼主| 发表于 2015-1-21 20:23:24 | 显示全部楼层
机器人天空 发表于 2015-1-21 19:16
一直想做四轴,羡慕楼主啊。下家找到了吗

没有,年后找找

出0入85汤圆

 楼主| 发表于 2015-1-21 20:27:02 | 显示全部楼层
登云钓月 发表于 2015-1-21 18:48
支持支持。我这边也准备搞点飞控算法呢。

角度融合那边都是成熟的,唯一难道就是后级马达PID 参数有点难调,自己多找找规律就出来了。努力吧

出0入0汤圆

发表于 2015-1-21 20:32:31 | 显示全部楼层
楼主你好,你的说明说内环为角度环,外环为角速度,下面程序的注释说内环为角速度环,外环为角度。我也刚才是学,问下整定PID参数的时候先调外环,再调内环。是不是调外环的时候内环所以参数给1.

出0入0汤圆

发表于 2015-1-22 14:19:11 来自手机 | 显示全部楼层
应该是表述错误了,一般内环是速率环,外环是角度环。

出0入85汤圆

 楼主| 发表于 2015-1-22 16:05:13 | 显示全部楼层
nnnkey 发表于 2015-1-22 14:19
应该是表述错误了,一般内环是速率环,外环是角度环。

嗯的,程序里面注释是对的

出0入0汤圆

发表于 2015-3-26 15:57:30 | 显示全部楼层
楼主可否Q交流:一二五六六七一一六五

出0入0汤圆

发表于 2015-3-27 11:19:35 | 显示全部楼层
楼主问个问题。。你调外环PID时,内环的参数怎么给的?都是一个确定的数值吧。。0.1或者1之类。。
还有这里"MPU6050_GYRO_LAST.Y * 3.5"为什么是乘以3.5
pitch_core_kp_out = Pitch_core_kp * (Pitch_shell_out + MPU6050_GYRO_LAST.Y * 3.5);

出0入0汤圆

发表于 2015-3-27 18:33:17 | 显示全部楼层
zzipeng 发表于 2015-3-27 11:19
楼主问个问题。。你调外环PID时,内环的参数怎么给的?都是一个确定的数值吧。。0.1或者1之类。。
还有这里 ...

pitch_core_kp_out = Pitch_core_kp * (Pitch_shell_out + MPU6050_GYRO_LAST.Y * 3.5);而且这里不应该是减吗?为什么是加号?

出0入0汤圆

发表于 2015-3-27 19:25:05 | 显示全部楼层
onev 发表于 2015-3-27 18:33
pitch_core_kp_out = Pitch_core_kp * (Pitch_shell_out + MPU6050_GYRO_LAST.Y * 3.5);而且这里不应该是 ...

个人觉得是加的。。内环P比例项

出0入0汤圆

发表于 2015-4-11 16:25:27 | 显示全部楼层
楼主,这样调节是什么意思

出0入0汤圆

发表于 2015-4-12 15:38:01 | 显示全部楼层
onev 发表于 2015-3-27 18:33
pitch_core_kp_out = Pitch_core_kp * (Pitch_shell_out + MPU6050_GYRO_LAST.Y * 3.5);而且这里不应该是 ...

你好,这是为啥是加啊?找到原因没?

出0入0汤圆

发表于 2015-4-12 16:25:09 来自手机 | 显示全部楼层
手机党标记!

出0入0汤圆

发表于 2015-4-13 09:03:02 | 显示全部楼层
onev 发表于 2015-3-27 18:33
pitch_core_kp_out = Pitch_core_kp * (Pitch_shell_out + MPU6050_GYRO_LAST.Y * 3.5);而且这里不应该是 ...

算了,我自己写了一个串级pid,还挺好使

出0入0汤圆

发表于 2015-4-14 14:18:19 | 显示全部楼层
楼主,你的Q_ANGLE.Pitch、RC_Pitch数据范围是多少?其它通道的呢?

出0入0汤圆

发表于 2015-4-14 14:35:07 | 显示全部楼层
moto1=(int16_t)(thr - Roll_core_out - Pitch_core_out- Yaw_core_out);
moto2=(int16_t)(thr + Roll_core_out - Pitch_core_out+ Yaw_core_out);        
moto3=(int16_t)(thr + Roll_core_out + Pitch_core_out- Yaw_core_out);
moto4=(int16_t)(thr - Roll_core_out + Pitch_core_out+ Yaw_core_out);   
楼主,怎么确定哪个电机对应哪个motox?式子中的加加减减跟相对应的电机又有什么联系呢?

出0入0汤圆

发表于 2015-4-16 15:20:23 | 显示全部楼层
onev 发表于 2015-4-13 09:03
算了,我自己写了一个串级pid,还挺好使

串级PID的调参思路是怎样的啊

出0入0汤圆

发表于 2015-4-18 21:14:35 | 显示全部楼层
who与争锋 发表于 2015-4-16 15:20
串级PID的调参思路是怎样的啊

参 APM或PIX4调参http://pixhawk.org/users/multirotor_pid_tuning

出0入0汤圆

发表于 2015-4-18 21:47:38 | 显示全部楼层
onev 发表于 2015-4-18 21:14
参 APM或PIX4调参http://pixhawk.org/users/multirotor_pid_tuning

你写的串级PID能否发上来看看呢?

出0入0汤圆

发表于 2015-4-19 15:19:53 | 显示全部楼层
好东西

出0入0汤圆

发表于 2015-5-13 23:34:04 | 显示全部楼层
onev 发表于 2015-4-18 21:14
参 APM或PIX4调参http://pixhawk.org/users/multirotor_pid_tuning

mark下,APM调参攻略

出0入0汤圆

发表于 2015-5-14 10:29:16 | 显示全部楼层
这玩意难不难,谁知道?

出0入0汤圆

发表于 2015-8-11 21:18:56 | 显示全部楼层
学习一下,谢谢分享

出0入0汤圆

发表于 2015-8-30 22:36:17 来自手机 | 显示全部楼层
楼主的飞行参数是多少

出0入0汤圆

发表于 2015-8-30 23:00:07 | 显示全部楼层
楼主  可玩WiFi   加载四轴上  、、、、

出0入0汤圆

发表于 2015-9-10 11:09:41 | 显示全部楼层
看看,标记下,谢谢楼主分享。

出0入0汤圆

发表于 2016-1-13 22:38:51 | 显示全部楼层
我最近在学习PID,发现发现楼主的程序跟标准的位置式PID怎么不太一样?
我查阅的资料见下图:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2016-1-13 22:41:58 | 显示全部楼层
楼主的D = Kd*(本次反馈值 - 上次反馈值);
我查阅的资料是D= Kd*(本次误差 - 上次误差)。

出0入0汤圆

发表于 2016-1-14 17:29:14 | 显示全部楼层
  pitch_core_kp_out = Pitch_core_kp * (Pitch_shell_out + MPU6050_GYRO_LAST.Y * 3.5);
  pitch_core_kd_out = Pitch_core_kd * (MPU6050_GYRO_LAST.Y   - Gyro_radian_old_y);

  Roll_core_kp_out  = Roll_core_kp  * (Roll_shell_out  + MPU6050_GYRO_LAST.X *3.5);
  Roll_core_kd_out  = Roll_core_kd  * (MPU6050_GYRO_LAST.X   - Gyro_radian_old_x);

  Yaw_core_kp_out  = Yaw_core_kp  * (Yaw_shell_out  + MPU6050_GYRO_LAST.Z * 1);
  Yaw_core_kd_out  = Yaw_core_kd  * (MPU6050_GYRO_LAST.Z   - Gyro_radian_old_z);

这是什么鬼??为什么乘以系数3.5 。

出0入0汤圆

发表于 2016-1-14 22:54:56 | 显示全部楼层
谢谢楼主分享

出0入0汤圆

发表于 2016-1-14 22:55:21 | 显示全部楼层
谢谢楼主分享   这帖子很有裨益

出0入0汤圆

发表于 2016-2-17 16:58:35 | 显示全部楼层
楼主,用这个算法最后会在稳态小幅震荡,该怎么调整参数呢?

出0入0汤圆

发表于 2016-2-26 12:20:26 | 显示全部楼层
mark PID调节参数

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-4-25 17:33

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

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