PID控制(下)

本文转载自微信公众号“电子搬砖师”,原文链接

这篇文章是PID控制的进阶说明,如果没有看过PID控制(上)的读者,请先看看PID控制(上),以便更容易看懂这篇文章。

一、PID算法优化

先讲PID算法优化。奉上最经典的角度PID算法:

float inteAngle, lastErrorAnglel; //角度积分,上一次的角度误差

//函数功能:角度PID算法
//输入参数:Angle,传感器测量得到的角度
//返回参数:PID算法输出值
float PID_cal(float angle)
{
    float errorAngle;                                        //角度误差
    float diffAngle;                                         //角度微分
    errorAngle = expectAngle - angle;                        //比例:角度误差 = 期望角度 - 传感器测的角度
    inteAngle = inteAngle + errorAngle;                      //积分:角度误差积分 = 角度误差积分 + 本次角度误差
    diffAngle = errorAngle - lastErrorAnglel;                // 微分:角度微分 = 本次角度误差 - 上次角度误差
    lastErrorAnglel = errorAngle;                            //记录本次角度误差
    return (P * errorAngle + I * inteAngle + D * diffAngle); //返回PID计算结果
}

以上PID算法是不是很简单?只要5行代码,只要调节P、I、D这3个系数,这个算法就可以让平衡车立起来!

我们开始对这简单算法做优化。

1

如果输入角度Angle是一个噪声比较大的值,可以对Angle做一个简单滤波,比如做个平滑滤波:

errorAngle = K * (expectAngle - angle) + (1 - K) * lastErrorAngle;

当然角度数据最好能在输入PID算法前就先做滤波了。

2

某些控制模型的误差绝对值大于一定值时可能需要停止运行,比如说平衡车倒地了,这时平衡车可能就不要再转轮了,不然可能产生意外。这时我们就可以判断平衡车角度误差绝对值是否大于限定值,如果大于的话我们就直接返回0,停止车轮滚动。如下:

if ((abs)errorAngle > limitAngle1) { return 0; }

3

如果误差绝对值大于一定值,积分项就会累积到很大的积分值,太大的积分值会使得系统更难控制,所以我们可以判断误差绝对值是否超标,过大的话就不积分,合规的话就可以积分,如下:

if ((abs)errorAngle < limitAngle2) { inteAngle += errorAngle; }

4

以上还有一种处理积分的方式叫积分分离法,它指的是如果误差绝对值大于一定值,积分项干脆直接清零。这样做的好处是可以使控制模型更快回复到平衡状态,或者避免加剧控制模型的失控,如下:

if ((abs)errorAngle > limitAngle2) {inteAngle = 0; }

5

由于过大的积分值会使系统难以控制或者回归稳定太慢,我们需要对积分做限制幅度处理,如下:

if (inteAngle > limitInteAngle) { inteAngle = limitInteAngle; }
if (inteAngle < -limitInteAngle) { inteAngle = -limitInteAngle; }

6

微分项往往是噪声比较大的项,如果微分噪声大我们也最好加个平滑滤波。本例中的角度微分项其实就是角速度,它可以用本次角度误差减去上次角度误差获得,也可以直接用陀螺仪测量得到的角速度。假设我们用的是前者,那对前者微分滤波如下:

diffAngle = J * (errorAngle - lastErrorAngle) + (1 - J) * lastDiffAngle;

7

执行机构的死区指的是PID算法给出一个控制数值到执行机构,执行机构可能会因为输入值较小而没反应。比如你给电机1V的电压,可能电机根本不会动,直到你给3V电压时,它才会动。这个3V电压就是该电机的死区。
死区通常可以用PID的积分项消除掉,但是有的地方不想用积分累积那么久才越过死区值,就可以在PID输出值上直接加上死区,如下:

PID_Out = P * errorAngle + I * inteAngle + D * diffAngle;
if (PID_Out > 0) { PID_Out += deadValue; }
else if (PID_Out < 0) { PID_Out += -deadValue; }

8

有的执行机构没法接收过大的PID输出值,比如PWM占空比最大只能100%,而如果PID输出的值大于这个PWM上限,那就要将PID输出值限幅,如下:

if (PID_Out > LimitPID) { PID_Out = LimitPID; }
if (PID_Out < LimitPID) { PID_Out = -LimitPID; }

9

高深点的PID的P、I、D三个系数还可以不是固定的,而是随着误差值的变化而变化的,这样就可以实现将非线性控制模型给线性控制住。这种方式我也没有用过,不过它的简单实现方式可以列出,还是应用本例,有:

P *f(ErrorAngle) * ErrorAngle + I *g(ErrorAngle) * InteAngle + D *h(ErrorAngle) * DiffAngle;

大概的PID算法优化以上都已经给出了,读者不用把每一项优化都添加到自己的算法中。毕竟每个控制模型都不一样,都有自己各自需要优化的地方,不要拘泥于此。

二、串级PID分析

奉上串级PID的框图:

串级PID框图

其中:

  • 圆圈带+-号的是误差比较机构
  • E(S)是误差
  • G(S)是被控对象
  • H(S)是反馈机构
  • 左边的PID属于外环
  • 右边的PID属于内环

回归到上一篇PID控制(上)中,那篇文章里面提到推箱子,箱子距离目的地越远就应该用越大的力气推,这个说法我当时是为了简单不绕提出的,但实际上是不对的。推力大会使得加速度大,如果摩擦力比较小,到达终点时推力为0只是说加速度为0,速度可能是非常大的,这个是不对的。真正正确的是距离和速度成比例,距离越远,速度越大,距离为0,速度为0,即推箱子的人应该控制的是速度而不是推力。

问:那速度要怎么控制呢?
答:可以靠串级PID算法控制。

串级PID在无人机上用得很多,它具有比单级PID控制更稳定,更顺滑的优点。它和单级PID控制的区别是:无人机单级PID是直接计算输入角度和反馈角度的误差,然后利用PID算法直接算出PWM值控制电机转动;而串级PID是先计算输入角度和反馈角度的误差,然后利用外环PID算法计算出在此角度误差下无人机的角速度最应该是多少,接着再计算外环PID输出的角速度和无人机当前角速度的误差,将此误差再送入控制角速度的内环PID算法中计算,最终内环PID输出一个PWM值控制电机转动。

串级PID中的内环控制频率可能会比外环控制频率高,因为外环给内环一个角速度值,内环不可能瞬间达到这个角速度,它必须经过几个周期的调整才可能达到这个角速度值。但是很多无人机内外环控制频率是一致的,这个也没什么问题,因为虽然内环没法及时达到外环的要求,但是却是往外环要求的趋势走的,最终无人机姿态还是会稳定的。

前面提到积分是消除静差用的,那这里无人机外环传递给内环的只是一个角速度,而内环利用自己的PID算法会负责将这个角速度实现出来,那这样外环输出的只是一个数字而已,哪怕是0.01度/秒,内环也会帮它实现,这就不该存在静差了,为什么外环要加个积分呢?

这里要说明积分的另一个作用,就是减小调节时间。假设比例项是5,角度误差是2度,纯比例控制输出的值会是10度/秒,但是如果有积分项存在,输出就会是:52+I积分,这个值会使角速度得到更快的变化。如果将外环的P和I系数调到一个合适值,虽然被控对象达到设定值时会过冲,然后反冲,如此震荡几次再稳定,但这个过程还是可以比仅有P系数的外环调节更快达到设定值。

拓展阅读:浅谈四轴PID调试心得

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,948评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,371评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,490评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,521评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,627评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,842评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,997评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,741评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,203评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,534评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,673评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,339评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,955评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,770评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,000评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,394评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,562评论 2 349

推荐阅读更多精彩内容