参考资料:

https://blog.csdn.net/nemol1990/article/details/45131603

https://blog.csdn.net/qq_27114397/article/details/53378941

https://blog.csdn.net/sunnyxiaohu/article/details/50601577

http://forum.eepw.com.cn/thread/259834/1

常用四轴的两种PID算法讲解(单环PID、串级PID)

这里主要讲解的PID算法属于一种线性控制器,这种控制器被广泛应用于四轴上。要控制四轴,显而易见的是控制它的角度,那么最简单,同时也是最容易想到的一种控制策略就是角度单环PID控制器,系统框图如图所示

或许有些朋友看得懂框图,但是编程实现有一定困难,在这里笔者给出了伪代码:

上述角度单环PID控制算法仅仅考虑了飞行器的角度信息,如果想增加飞行器的稳定性(增加阻尼)并提高它的控制品质,我们可以进一步的控制它的角速度,于是角度/角速度-串级PID控制算法应运而生。在这里,相信大多数朋友已经初步了解了角度单环PID的原理,但是依旧无法理解串级PID究竟有什么不同。其实很简单:它就是两个PID控制算法,只不过把他们串起来了(更精确的说是套起来)。那这么做有什么用?答案是,它增强了系统的抗干扰性(也就是增强稳定性),因为有两个控制器控制飞行器,它会比单个控制器控制更多的变量,使得飞行器的适应能力更强。为了更为清晰的讲解串级PID,这里笔者依旧画出串级PID的原理框图,如图所示:

同样,为了帮助一些朋友编程实现,给出串级PID伪代码:

二、代码学习整理

根据上述的描述,并且参考给出的代码:https://github.com/yzhajlydy/Micro-Quadrotor

以下我个人的理解,其中外环的 角度误差 = 期望误差 - 当前误差

当前误差其实就是当前的角度如pitch, roll, yaw

那么期望误差其实就是遥控器的控制角度,遥控器的角度范围是1000~2000(天地飞07)。那么比如如果我要控制±40°的信号

/**************************实现函数********************************************
*函数原型: void Direction_Control(void)
*功 能: 前后左右方向控制
*******************************************************************************/
void Direction_Control(void)
{
//根据遥控器传过来的前后方向值,改变ZHONGZHI_PIT的给定值
//按40度计算,500/40 = 12.5(pwm/度) 2度是25
ZHONGZHI_PIT = (myControl.remoteControl[]-)/12.5; //根据遥控器传过来的左右方向值,改变ZHONGZHI_ROL的给定值
ZHONGZHI_ROL = (myControl.remoteControl[]-)/12.5;
} /**************************实现函数********************************************
*函数原型: void Outter_PID(void)
*功 能: 外环角度控制
*******************************************************************************/
void Outter_PID(void)
{
//计算X轴和Y轴角度偏差值
e_pit = ZHONGZHI_PIT-myControl.pitch;
e_rol = ZHONGZHI_ROL-myControl.roll; //外环PID运算
angular_speed_X = pit_p*e_pit;
angular_speed_Y = rol_p*e_rol;
}

然后外环的输出,是内环的输入。

/**************************实现函数********************************************
*函数原型: void Inner_PID(void)
*功 能: 内环角速度控制
*******************************************************************************/
void Inner_PID(void)
{
//计算X轴和Y轴角速度偏差
e_X[] = angular_speed_X - myControl.gyro_X;
e_Y[] = angular_speed_Y - myControl.gyro_Y; //===========================绕X轴内环PID运算============================================
//积分分离,以便在偏差较大的时候可以快速的缩减偏差,在偏差较小的时候,才加入积分,消除误差
if(e_X[]>=150.0||e_X[]<=-150.0){
flag_X = ;
}else{
flag_X = ;
e_I_X += e_X[];
} //积分限幅
if(e_I_X>MOTOR_MAXVALUE)
e_I_X=MOTOR_MAXVALUE;
if(e_I_X<MOTOR_MIDVALUE)
e_I_X=MOTOR_MIDVALUE; //位置式PID运算
PWM_X = kp1*e_X[]+flag_X*ki1*e_I_X+kd1*(e_X[]-e_X[]); //===========================绕Y轴内环PID运算========================================
//积分分离,以便在偏差较大的时候可以快速的缩减偏差,在偏差较小的时候,才加入积分,消除误差
if(e_Y[]>=150.0||e_Y[]<=-150.0){
flag_Y = ;
}else{
flag_Y = ;
e_I_Y += e_Y[];
} //积分限幅
if(e_I_Y>MOTOR_MAXVALUE)
e_I_Y=MOTOR_MAXVALUE;
if(e_I_Y<MOTOR_MIDVALUE)
e_I_Y=MOTOR_MIDVALUE; //位置式PID运算
PWM_Y = kp2*e_Y[]+flag_Y*ki2*e_I_Y+kd2*(e_Y[]-e_Y[]); //=======================================================================================
//记录本次偏差
e_X[] = e_X[]; //用本次偏差值替换上次偏差值
e_Y[] = e_Y[]; //用本次偏差值替换上次偏差值 }

三、PID调试整理

PID控制器我大概就是这么实现的,首先将四轴固定在单轴平衡平台上,让飞行器完成单轴平衡,主要观察姿态角的

(1)稳定性,能否平衡在期望角度;
(2)响应性,当操纵命令改变时,四轴能否即时的响应期望的变化;
(3)操纵性,由操纵员感受四轴的姿态是否已与操纵,会不会产生响应过冲。

P

因为PID有内外环之分,所以应该先从内环调节,内环稳定后再调外环。

内环的顺序是先调P,其他I、D设为0,那么如何确定P的值呢?主要的现象是等幅震荡,就是四轴会绕着轴来回摆动。

调节P时遇到的情况:

1)四轴开启后加速翻转,说明P的值方向错了。如果P值过大,可能出现自转的情况,就是绕着轴最大马力旋转(太可怕了)

2)四轴在某个角度稍稍停顿,然后掉落,说明P给小了

3)当P太小时,四轴在很大倾斜的地方,在重力与P的作用下也会震荡,这种震荡不是等幅的,也不是对称的,震荡波谷的绝对值明显要比波峰绝对值大而且距离0度会很远。这种情况要加以区分。

参考资料中说,在有一点反馈力到等幅震荡的区间内确定四轴的P值。

D

然后开始调D,如果说P是回复力的话,那么D就是阻尼。虽然它能抑制震荡,但同时也会抑制P的效果。

当震动产生时,在震动的中心点四轴震动速度最大,也是D作用最强的时刻。

加了D效果就比较明显了,四轴在外力的干扰先能明显的有回复力且,能快速稳定在平衡点了,调D就是试,当然D大了也会产生震荡,但是此时不加D时光P作用时的震荡就很小,很明显就可以看出随着D的增大,震荡减小又增大的过程。

I

调 I 的时候我先把积分限幅去掉。然后从小往大加,当调平衡时,随着油门的变大,静差应该是越来小的。

我将油门推到差不多快要将四轴推离地面的位置,看I能不能消除静差。因为如果油门给小了,静差较大,调出来的I虽然能消除静差但是I比较大,在加油门时有可能也会产生超调震荡。

最后I要再能消除静差又不产生震荡,个人认为要近可能小。最后加上合适的积分限幅。

其他资料的PID整定:

而笔者在整定串级PID时的经验则是:先整定内环PID,再整定外环P。

内环P:从小到大,拉动四轴越来越困难,越来越感觉到四轴在抵抗你的拉动;到比较大的数值时,四轴自己会高频震动,肉眼可见,此时拉扯它,它会快速的振荡几下,过几秒钟后稳定;继续增大,不用加人为干扰,自己发散翻机。

特别注意:只有内环P的时候,四轴会缓慢的往一个方向下掉,这属于正常现象。这就是系统角速度静差。

内环I:前述PID原理可以看出,积分只是用来消除静差,因此积分项系数个人觉得没必要弄的很大,因为这样做会降低系统稳定性。从小到大,四轴会定在一个位置不动,不再往下掉;继续增加I的值,四轴会不稳定,拉扯一下会自己发散。

特别注意:增加I的值,四轴的定角度能力很强,拉动他比较困难,似乎像是在钉钉子一样,但是一旦有强干扰,它就会发散。这是由于积分项太大,拉动一下积分速度快,给  的补偿非常大,因此很难拉动,给人一种很稳定的错觉。

内环D:这里的微分项D为标准的PID原理下的微分项,即本次误差-上次误差。在角速度环中的微分就是角加速度,原本四轴的震动就比较强烈,引起陀螺的值变化较大,此时做微分就更容易引入噪声。因此一般在这里可以适当做一些滑动滤波或者IIR滤波。从小到大,飞机的性能没有多大改变,只是回中的时候更加平稳;继续增加D的值,可以肉眼看到四轴在平衡位置高频震动(或者听到电机发出滋滋的声音)。前述已经说明D项属于辅助性项,因此如果机架的震动较大,D项可以忽略不加。

外环P:当内环PID全部整定完成后,飞机已经可以稳定在某一位置而不动了。此时内环P,从小到大,可以明显看到飞机从倾斜位置慢慢回中,用手拉扯它然后放手,它会慢速回中,达到平衡位置;继续增大P的值,用遥控器给不同的角度给定,可以看到飞机跟踪的速度和响应越来越快;继续增加P的值,飞机变得十分敏感,机动性能越来越强,有发散的趋势。

整体方法:
1,将内外环PID都归0,适当增加内环的P,调整P至四轴从正面朝上自然转动到正面朝下时能感受到阻力,且没有抖动,有抖动就应减小P,当P减小到无抖动或者轻微抖动时即可。

2,让内环的D慢慢增加,到你用手能明显感受到转动四轴产生排斥外力的阻力即可,D能抑制P产生的振荡,但是D过大也会导致高频振荡,调整D至系统无振荡且能抑制外界的力即可。

3,给内环一点点I,注意的是I的积分要在油门开启后才开始,油门关闭就清0,且必须有积分限幅。I推荐取越小越好,我取的是0.01,I取大了会导致系统振荡。

4,将内环P减半,将外环P调至内环的50-70倍,根据系统产生的高频振荡降低内环的D,直至高频振荡消除即可。

5,给外环一点点I,同3.

6,根据实际情况对参数进行优化调整,调整过程中要注意区分各个参数的作用,时刻记住,P是回复力,大了会低频振荡,D是抑制力,大了会高频振荡,I是静差消除力,越小越好,大了会产生振荡。

四、衰减曲线法

https://blog.csdn.net/zhuifeng_tjy163163/article/details/78961017

我自己的实验记录:

我把油门摇杆打上3格,P调到1的时候反应有点小,2的时候。用手保持飞机朝上,轻轻放手,再拉住。感觉有明显的来回感,有时候掉下去快了,回馈力也比较大。

调到4的时候还是会往下掉,调到5的时候落下去回馈过头,翻过去了。4.5还是翻过去了,4.3下落的时候顿了一下。大概4.6到4.5的时候会反转,而4.3到4.5就会顿一下再下落。

-------------------------------------------------------------------------------------------------------------

2018年8月3日 20点51分 好痛苦,调了这么久都没效果。后来用示波器看了波形速率。发现9250的DMP读取有问题。

STM32F103如果把读取速率取到100,加上其他工作诸如串口啊(改成DMA方式发送还是占用资源)、定时器啊、外部中断啊都会被影响

后来我取了80效果一顿一顿的了,取到50发现匹配的刚刚好。如果有硬件I2C或许会快点,不过出来的曲线好多了。很平滑,没有之前的折线了。

为什么会发现这个问题?我在修改PID的时候,飞机要到30度倾角才有反应。这就让我很困惑,加大到了200Hz效果依然不好,最后用示波器调试。配合上位机才定位到问题。

感觉自己都在走弯路,硬件性能都没弄好还一个劲的调PID,调的自己还很泄气。

-----------------------------------------------------------------------------------------------------------------

硬件问题解决了,飞机的反应立马好了不少。再也没有之前的顿顿的强烈反应,取而代之的是平滑的往下滑,好蛋疼。虽然角速度基本没动,但是角度一直会慢慢往下滑。我在想是不是要加上外环才能稳定,加了外环也好像不能改善。

------------------------------------------------------------------------------------------------------------------

我又调试了一下,现在四轴的情况是,内环把角速度控制在比较小的变动范围,但是飞机还是会往下翻。然后我用外环控制姿态,意味着飞机一直会调整一下调整一下。

这样的情况单轴调试效果还行,但是试飞阶段时,我发现调试油门比起飞油门小了不少,导致飞机起飞的时候非常不稳。然后再改回单轴调试发现,用起飞的油门调试时。

P是太大了,我还是要重新调整。

四轴PID思路整理的更多相关文章

  1. GTP+SDI工程播出部分思路整理

    GTP+SDI工程播出部分思路整理 1.video_out_to_sdi模块 关于video_out_to_sdi模块的输出信号: tx_video_a_y[9:0] 这是要输入SDI IP核内的 t ...

  2. Angular2发布思路(整理官网Deployment页面)

    本文是按着ng2官网的高级内容“Deployment”的思路整理得出的,原文虽然在angular2的中文站下挂着,截止目前却还是英文版未翻译,笔者就在这里结合自己的理解给出原文的一点点整理.这是原文地 ...

  3. GTP+SDI工程播出部分思路整理(3)

    GTP+SDI工程播出部分思路整理(3) 1.本文的目的主要分析video_out_to_sdi模块中输入信号 tx_usrclk, rst, tx_mode, tx_level_b的使用 Tx_us ...

  4. GTP+SDI工程播出部分思路整理(2)

    GTP+SDI工程播出部分思路整理(2) 以同样的方法来分析tx_video_a_c_in信号: SDI核中tx_video_a_c_in信号连接情况如下所示 .tx_video_a_c_in     ...

  5. 一些JavaSE学习过程中的思路整理(主观性强,持续更新中...)

    目录 一些JavaSE学习过程中的思路整理(主观性强,持续更新中...) Java书写规范 IDEA的一些常用快捷键 Java类中作为成员变量的类 Java源文件中只能有一个public类 Java中 ...

  6. 解决Android加固多进程ptrace反调试的思路整理

    本文博客链接:http://blog.csdn.net/qq1084283172/article/details/53613481 一.Android多进程反调试的原理代码 当ptrace附加目标进程 ...

  7. AVL树的算法思路整理

    http://www.cnblogs.com/heqile/archive/2011/11/28/2265713.html 看完了<数据结构与算法分析(C++描述)>的4.4节AVL树,做 ...

  8. iOS 工程自动化 - 思路整理

    4 月份参加 2017@Swift 大会的时候有幸听到了 @zesming 大佬关于美团组件化的 Topic,有一张图印象特别深刻. 来自 @zesming 大佬 后来跟 @zesming 大佬沟通怎 ...

  9. iOS内置图片瘦身思路整理

    一.前言 前段时间注意到我们APP的包大小超过100MB了,所以随口跟老板说了下能否采用字体文件(.ttf)替代PNG图片,老板对应用瘦身很感兴趣因此让我做下技术调研.这篇文章主要是将我们的各个技术方 ...

随机推荐

  1. xpath使用技巧

    爬虫中我们对于元素的定位有多种方法,大致有: Beautifulsoup.Xpath和正则表达式三种方式 其中效率比较为: Beautifulsoup<Xpath<正则表达式 习惯了使用B ...

  2. Share架构的一些心得

    个人这些年,从web->system service->app 项目实战,陆陆续续经历的项目很多,自己也数不清.自己也一直对于架构没有明确去给出一个自己的定义描述. 刚好最近一直在flut ...

  3. 双轴按键摇杆控制器控制TFTLCD(使用ADC1双通道DMA传输)

    实验使用如下所示的双轴按键摇杆控制器,来控制TFTLCD上显示的直线.首先介绍一下双轴按键摇杆控制器.原理:十字摇杆为一个双向的10K电阻器,随着摇杆方向不同,抽头的阻值随着变化.本模块使用5V供电( ...

  4. 初次打开jenkins页面一片空白的解决办法

    安装完成jenkins后,点击[使用admin账号继续]后,页面一片空白的解决办法: step1: Jenkins插件管理-高级设置界面==> http://localhost:8080/plu ...

  5. Openstack_SQLAlchemy 修改数据库的表结构

    目录 目录 前言 更改数据库的方法 为数据库添加一张或多张新表 删除一张或多张表 为旧表添加一个字段 为旧表更新一个字段 为旧表初始化一条新的记录 最后 前言 SQLAlchemy 的使用方法和相关基 ...

  6. cts-on-gsi测试流程

    测试前提: 1.发货user版本 2.selinux:Enable 3.连接ADB,stay awake 4.烧录XXX申请的key 5.外网环境(ipv6) ATV9测试准备(正常准备环境+fast ...

  7. error LNK2019: unresolved external symbol __vsnwprintf

    老DX SDK,新VS2019问题,编译老项目GG,依赖库加入 legacy_stdio_definitions.lib 解决

  8. 《STL源码剖析》——第四章、序列容器

     1.容器的概观与分类 所谓序列式容器,其中的元素都可序(ordered)[比如可以使用sort进行排序],但未必有序(sorted).C++语言本身提供了一个序列式容器array,STL另外再提供v ...

  9. java--反射原理及操作

    1.反射原理 反射具体操作 15.反射的原理(********理解********) * 应用在一些通用性比较高的代码 中 * 后面学到的框架,大多数都是使用反射来实现的 * 在框架开发中,都是基于配 ...

  10. MyBatis-Spring的sqlSessionTemplate

    转自:http://www.cnblogs.com/yhtboke/p/5611375.html SqlSessionTemplate SqlSessionTemplate是MyBatis-Sprin ...