PID控制算法系列(2) 您所在的位置:网站首页 串级控制系统流程图怎么做 PID控制算法系列(2)

PID控制算法系列(2)

2024-07-05 18:50| 来源: 网络整理| 查看: 265

正文一、串级PID1.1 原理理解

有单级PID,那么也就一定会有串级PID。其实串级PID就是在原先的PID控制块的前面再接一个PID控制块,叫做外环,内外环串接起来就是大概下面这个样子:PID控制算法系列(2)-串级PID的理解与实现_内环

前面的控制块里面放着什么,以及其他的输入都先不用管,一步步来。

首先需要回答的第一个问题就是我们为什么需要串级的PID?

还是使用上面四轮小车作为例子说明。先不管我们建立的第一个PID模型,只看小车这一个整体,我们可以控制的是小车的速度。而小车这一个系统的任务可以有许多,其中就比如到达某一个具体的位置。我们虽然能够使用单级的PID系统控制小车的速度在某一时刻尽可能快地达到期望值,但是我们是没有办法控制小车的加速度的,除非我们每时每刻都能改变小车速度的期望值。我们所希望的是,当我们给定一个位置,也就是给定一个位移的时候,小车能够尽快地到达,其中小车的运动必然是一开始用较大的加速度做加速运动,快到终点了再用一定的加速度做减速运动,注意,是小车能够自行完成这样的任务。

显然单级PID是无法做到这一点的,所以需要在它的前边再添加一级PID控制器,这个控制器的功能只有一个,那就是提供一个合适的速度变化曲线,使得单级的PID具备前面所说的先加速,后减速的功能。

用数学公式去理解,设位移是S,也就是整个系统最后需要达到的目标,第一级PID直接控制了V,也就是控制了小车当前的速度,在没有外界干预的情况下它只能做匀速直线运动,也就是

\[S=vt\]

那么这个小车到达S的方法是什么呢?是弹射启动与急刹。在启动瞬间达到速度V并且在通过终点的瞬间急刹,从而完成S的位移。但是学过高中物理的人都知道这是不可能的,小车达到速度V需要时间,从V降低速度到0也需要时间。

所以引入第二个PID控制器,它的目的前面说过,是找到合适的曲线来引导速度的变化,也就是小车有了一定的加速度,所以有:

\[S=vt+\frac{1}{2}at^{2}\]

现在就好了,小车就能在一个加速度增大的加速运动与一个加速度逐渐减小的减速运动中(可能是这样吧)平滑地到达终点了,这与上面单级PID不同,这是物理上真实可以实现的。

所以也有一句话是这么说的,外环的微分就是内环。在这个例子中外环实际上提供的就是一条速度变化曲线,在这条曲线上任意一点取微分,就得到了速度,也就是内环控制的物理量。

那么这个合适的速度变化曲线,我们上哪找呢?其实大部分使用的曲线都类似下面这两种:PID控制算法系列(2)-串级PID的理解与实现_摇杆_02

这里的曲线并不是指真的需要输入这种曲线,而是在这个PID控制器中,当参数设定好后,输出的控制结果就类似这种曲线。同时一般在外环中只会引入P(比例),而不使用I(积分)与D(微分),原因是添加I后响应会变慢,添加D后又对噪声敏感,我们要的只是一个大概的曲线,有比例系数控制就足够好了。

现在我们就拥有了一台能够实现下面功能的小车:

给定一个位置,小车可以实现自动控制加减速以一个尽可能短的时间到达终点,期间不需要人的干预

也就是下图的样子:

PID控制算法系列(2)-串级PID的理解与实现_内环_03

但是外环PID想要直接获取到当前的位移是比较困难的,所以做下面的处理来间接获取:

PID控制算法系列(2)-串级PID的理解与实现_内环_04

而小车的期望位置则由时间内油门摇杆偏移量的积分来求得。

所以现在我们就有了一个比较好的小车模型。需要注意的是,在这个模型中小车的转向是不受PID控制的,因为并没有相关的陀螺仪传感器来反馈角度与角速度的数据,也就是说小车的转向只能与人眼构成一个闭环系统,我们觉得它转得慢了,就加大油门量;觉得它转的快了,就降低油门量。

在油门量方面,如果通过遥杆来控制,那么小车能够保持直线行驶(没有PID的小车四个轮子的转速没办法达到一致);如果是通过其他的设备(例如上位机等)控制,那么小车不仅能够保证直线行,还能知道自己走了多远,还有多远没走,你让它往前开一米,它就能精确地到达一米的位置。

串级的PID多数用于二轮平衡小车上,在平衡小车上我们就没有办法通过摇杆来控制小车的速度实现小车的平衡了,必须由小车自己结合角度的PID进行融合控制。

那么单纯看二轮平衡小车的位置环设置大概就是下面这样:

当小车静止的时候,小车的期望位置就是原点,反馈的位置就是小车时间内的速度的积分;当小车运动的时候,小车的期望位置就是摇杆的偏移量在时间内的积分,反馈的位置同上。1.2 代码实现//串级PID//定义所需要的变量float Kp_ex; //外环Pfloat Kp, Ki, Kd; //内环PIDfloat Motor1_speed; //电机当前的速度float Position_now; //小车当前的位置,由当前速度积分得出float target_speed; //我们需要电机达到的速度,外环的输出,也就是内环的输入float target_position; //我们需要小车达到的位置,由摇杆积分得出float err_position_now; //当前小车位置的误差float err_position_last; //上一次小车位置的误差float err_speed_now; //当前速度与电机期望值的差,也就是当前的误差值float err_speed_last; //上一次计算的误差值float err_speed_i; //积分项,将累计时间内所有的误差值float output; //经过PID算法后输出的数据,其实是一个控制PWM占空比的参数,我们只需要直接放在输出PWM的函数里就好了//外环PIDerr_position_now = target_position - position_now;target_speed = Kp_ex *err_position_now;//外环的输出就是内环的输入//速度的限幅处理略err_position_last = err_position_now;//内环PIDerr_speed_now = target_speed - Motor1_speed;errspeed__i += err_speed_now;if(err_speed_i > x) err_speed_i = x;//这里需要设定一个极限值,以防积分变量溢出,其实一般来说并不会达到这个极限值,因为误差并不都是正数//没有对D进行操作output = Kp * err_speed_now + Ki * err_speed_i +Kd * (err_speed_now - err_speed_last);//PID公式if(output > x) output = x;//这里需要对输出也进行一个限制,这里倒不是限制溢出,而是PWM输出的参数本身就有最大值,超过了就无效了。TIM_SetCompare1(TIMx, output);//对产生PWM的定时器通道一进行输出err_speed_last = err_speed_now;//将使用完的当前误差值赋给上一次的误差值,进行下一轮循环



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有