参考资料:

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. PHP-执行外部程序

    备份 / 恢复数据库 exec - 执行一个外部程序(在 php 文件所在目录进行执行) 很久以前写的,很多方法是项目中的直接复制粘体用不了,只能提供下思路. 用到执行外部程序的就这一句: exec( ...

  2. Selenium WebDriver高级应用

    WebDriver高级应用 public class Demo4 { WebDriver driver; // @BeforeMethod:在每个测试方法开始运行前执行 @BeforeMethod p ...

  3. Drone 的插件 - Docker 插件

    Drone 插件市场 Drone 插件文档 原文地址 - Docker 插件的手册 Docker 插件可以用于构建镜像及发布镜像到 Docker registry.下面的 pipeline 配置,就使 ...

  4. Parameter Initializations in Deep Learning

    全零初始化的问题: 在Linear Regression中,常用的参数初始化方式是全零,因为在做Gradient Descent的时候,各个参数会在输入的各个分量维度上各自更新.更新公式为: 而在Ne ...

  5. knn算法手写字识别案例

    import pandas as pd import numpy as np import matplotlib.pyplot as plt import os from sklearn.neighb ...

  6. Java笔记——Map集合

    Map集合接口 Map集合与Collection不是从属关系,是平级的 Map集合的映射特点 一个映射不能包含重复的键,由此键只能允许有一个空null 每个键最多只能和一个值对应 值可以重复,由此值允 ...

  7. Ubuntu12.04安装MariaDB并修改字符集为UTF-8

    其实按照MariaDB官网的步骤来安装MariaDB特别的简单,只要按照步骤来做,很容易就搞定了. 首先,到MariaDB官网: https://downloads.mariadb.org/maria ...

  8. svg画圆环

    之前我已经分享了一篇css画圆环,为啥今天还要分享一篇svg画圆环呢? 原因是:css画圆环在部分ipone手机会有bug,最大张角为90°,所以圆环会有白色的间隙. 好了,开始代码展示: html: ...

  9. 14、numpy——统计函数

    NumPy 统计函数 NumPy 提供了很多统计函数,用于从数组中查找最小元素,最大元素,百分位标准差和方差等. 函数说明如下:(沿哪条轴执行,就是是最后结果的形式) 1.numpy.amin() 和 ...

  10. python——列表操作函数和方法

    1.添加新元素 1.1 append()函数 描述:append() 方法用于在列表末尾添加新的对象. 语法:list.append(obj) 参数:obj -- 添加到列表末尾的对象. 返回值:该方 ...