自动控制系统简介
PID算法简介
1.比例环节
例子:
假如有个温室大棚 目标温度 = 30℃ 反馈回路反馈的值 = 20℃
e=30-20=10℃ 假设u 为温控系统档位(u越大 调温速度就越快)
Kp越大 就越容易出现超调 情况(参考蓝色的线)
静态误差(如何消除静态误差 就引入 了积分环节)
静态误差:实测值 永远也到不了 目标值 因为整个系统已经稳定了
2.积分环节
没加积分环节的话,会一直有个偏差(系统到达稳态了),
加了积分环节,很快消除掉静态误差,达到 目标值。
3.微分环节(减小超调 克服震荡)
例如 目标温度:30℃ 现在温度为:20℃ e1=10
经过比例和积分 第二次 温度 28℃ 此时e=2
此时ek=2,ek-1=10 2-10= -8
从变化量中就能遇见到 用纯粹的 比例和积分 去调节输出时 下一次 一定会过头 超过30℃
所以加入了微分 有过头的趋势 就会 为负数 提高温度就没那么快了 超调就会得到相应的控制。
k:序号(第几次的意思) 例如 k=2
则 uk:第二次输出的值 ek:第二次的偏差
PID离散公式
位置式PID公式:
1.假设输出 为 角度 25° 由于积分项 偏差累计越来越大 假设计算出现异常 偏差量很大 最终算出来 远远的偏离了 25°
2.全量计算 就是 e的k的次数 都要进入最终输出的 计算中 前面要不断地进行偏差的累加(积分环节)
积分饱和
位置式PID 因为有 积分 所以 会对偏差 不断地 累计求和
例子: 电机转速=350转/分 但电机 最大转速=300转/分 所以 会一直有 偏差 e=50
由于长时间的 积分环节的 偏差累计 所以 积分其实是一直在增加的 每次计算e就+50
可能一段时间后 e=10W了 如果此时改变目标值 转速=250转/分 那么 由于积分导致e=10W了 ,所以每次 积分再-50 得很久才能 响应 。
解决方法:
1.优化PID曲线:曲线越快 到达目标值 偏差就会越小 累计偏差也会越小
2.规避可预见偏差: 例如 已知 电机最大转速=300转/分 那么设置目标值的时候就不要设置超过300转/分 的 数值
3.进行积分限幅
增量式PID公式:
增量式 是 上一次 输出的值 + 这一次计算的增量
推导
△u: 相对于uk-1 增加的 输出量 的 变化值
PID离散公式对比
PID算法函数实现
1.PID初始化函数: 设置PID的数值 例 KP=10 KI=5 Kd=0.1
2.PID闭环控制函数 : 就是PID的公式 代码化
3.定时器更新中断函数 :调用PID控制函数 计算输出 例如:我是 直流有刷电机 速度环控制 通过定时器返回的输出 其实是PWM的比较值 因为直流有刷电机和电压有关 控制电压就能控制直流有刷电机的速度 电压又和PWM 占空比有关
4.PID上位机调试函数(正点原子特有)
PID采样周期
在 电机中 可以简单理解为 编码器传出来的数值 获取的时间间隔
实际值突变能力: 例如 电机中 直流有刷电机速度 1S可以突变 60转/分 这个就是他的突变能力。
假设 温控系统 1H 可以突变36℃ =3600s --->36 如果我1S采样一次 那么 这1S 最大突变 为 0.01℃
若实际温度为30℃ 那隔一秒去采样一次有意义吗?? (一S只变换0.01℃)体现的作用不大
但如果系统精度要求不是非常高 采样频率就没必要这么高
温度这种 实际值 很难 发生突变 所以 采样周期 可以稍微大一点
压力、流量 这些量可能会发生突变的 可以 根据需求 把周期调小一点
PID参数整定方法
调参 主要还是经验
PID曲线分析
系统震荡:微分环节 减小震荡
调参 先引入 P ,I 和 D 先不用 先使用纯比例环节
如果纯比例环节出现这种情况 --- 大幅度系统震荡 如果不及时再调整参数 就容易导致系统崩溃
原因:比例系数太大
减小后:系统震荡得到有效的缓解 但是还是有震荡 纯粹调节比例系数已经没办法解决了
就需要 引入微分系数 抑制震荡
引入微分系数后:
会发现 这个曲线已经很好了,就不需要再引入积分环节了 所以 不一定每一个环节都参与。
静态误差 :积分环节 消除静态误差
先引入 纯比例环节:P 发现出现静态误差 则需要 再引入 积分系数
引入积分环节后: 发现消除静态误差的时间较长 此时就可以增大积分系数
然后就能调整出一个比较理想的曲线:
超调: 比例+积分+微分
如果 比例+积分怎么都控制不住
1.调小积分系数 在一些系统当中 减小积分系数 对于 超调的 抑制 比调微分系数 来得更好 更明显
2.增大微分系数:当减小积分系数 还不行 就增大微分系数 可控制超调量
直流有刷电机的 PID控制
速度环:
PID流程:通过测试编码器的速度来计算偏差e
1.设定PID参数结构体
定义一个 PID参数的结构体 定义一个 速度闭环的PID参数结构体变量。
2.初始化PID参数
把 PID结构体中的参数初始化, 目标值、期望值、累计偏差清零,配置PID系数
3.设置 目标 速度
通过 代码 或者 上位机 设置 目标速度!! 是目标速度!
这里是通过按键 按下 自增 目标速度
4.PID闭环控制
在定时器中 定时器的中断回调函数 进行PID计算 (需要限制占空比)
定时器三 主要是通过 相位 A B 进行计数 先通过A 再通过B 则CR1的DIR位 为0 则为正向计数
反之为反向(有可能是反的)
定时器6,主要任务是计时, 获得 V=S/T 的T 在定时器6的定时时间内 获得编码器计数的计数值,再除以 定时器6的定时时间,则可以获得 多少S/圈的V
以及用定时器6 每隔一段时间 计算并输出 PID 的数值 用于计算。
每次定时器6 进入中断函数时 val++ 定时器6初始化时 每隔50us 就进入一次中断 val++
PID计算函数(这个是位置式)
限制速度(这个是限制 上位机 变换的速度!)
对于正点原子 发送波形函数在这
电流环:
PID控制流程:要注意 与速度环 控制对象 和 反馈电路 的区别为 采集的数据不一样 速度环 采集的是 编码器测算出来的速度 而电流环是 电流采集电路中的电流。
1.设定PID结构体
定义一个 电流闭环的PID 参数结构体 变量 。
2.初始化PID参数
把期望值、累计偏差值清零,配置目标值、PID系数 (为什么配置目标值?) 因为电机需要60mA的电流才能启动,而主程序 增减一次设定的增减值为20ma 所以需要设定目标值 如果主函数直接设定增加一次60mA 则也能不设定目标值。
3.实际电流滤波
用ADC中断回调函数 对实际电流进行滤波和采样计算。
计算平均值也是滤波的一种方法
ADC平均值函数 (这段没怎么看懂 反正 需要第一次滤波(求平均) 和 第二次滤波(在求平均后的值中再求平均) )
还需要一阶低通滤波
4.设置目标电流
通过 程序或者上位机 设置目标电流
5.PID闭环控制
在定时器中断回调函数中进行PID计算。
位置环:
位置通过什么来反馈:
位置:指的是电机运动的位置 如果想把电机稳定的控制在某一个位置的话 就可以使用PID 位置环控制。
在实际运用当中 如何来反映电机的位置 通过 编码器当前的计数总值 来反映
电机运动会伴随着编码器计数变化,我们可以通过计数变化计算编码器当前的计数总值。
通过计数总值来控制此时电机的位置。
1.设定PID参数结构体变量
2.初始化PID参数
3.设置目标位置
在主函数中或者上位机中设置目标位置 电机转到哪个位置
这个就是 按下按键一 电机 目标位置(编码器目标数值) 就自增1320(一圈)
为什么1320为一圈: 首先此电机 编码器旋转一圈 输出脉冲为11个 减速比为1:30(输出轴转一圈 编码器转30圈) ,脉冲4倍频 所以 11*30*4=1320 也就是 转一圈 实际编码器在MCU中计数为1320个脉冲。
4.PID闭环控制
如上面 电流环 速度环 一样
5.波形
在调整位置环时 会观察到 会存在震荡现象 实际上 单靠位置控制 是很难把震荡控制得很完美的
这时候就 体现出 双环控制 的作用了 在这种情况下 单环控制 已经不足以把曲线优化好
则需要双环控制 来达到更好的 控制效果
双环控制时 外环 PID参数 不要调很大 会对曲线影响很大 尽量调节内环
直流有刷电机双环控制:外环:优先考虑对象 内环:对控制效果进行优化
为什么需要 双环控制?
上一个位置控制 很难靠单环控制调平曲线,因为电机是惯性系统,达到(位置的)目标值之后,速度不会马上降下来(达到某个位置,但速度≠0 所以还会动偏离原有的位置)因此存在超调现象。所以引入了双环
外环:优先考虑对象 内环:对控制效果进行优化(最终需要控制的结果 为 外环 )
1.速度+位置 双环控制 (最终需要控制的结果 为 外环 )
在考虑 我电机要到某个位置必须停下来 例如 转一圈就得停下来 或者1/2圈就要停下来,那么考虑对象肯定是 位置环 它所考虑的就是 你有没有到达这个位置 , 那 位置环 就是 外环 , 而引入 速度环 对位置环进行效果优化 所以 位置环为外环,速度环为内环。(最终需要控制的结果 为 外环 )
内环的作用:以怎么样的速度达到这个目标位置 能让曲线变得更好。
首先 设置目标值(目标位置) 通过编码器计数(获取实际值(实际位置)) 目标位置和实际位置进行偏差计算 获得偏差 输入到位置环(外环)此时和单环控制一样, 经过位置环 PID计算 把外环PID输出 和编码器测速(实际获取的值(实际速度))采集的值 做偏差 得到这个偏差之后 再进行内环PID控制 外环的输出作为内环的输入 经过速度环PID计算后 最终输出 作用于PWM占空比。 (PID计算 后 输出的值 其实是 控制值 / )外环的输出(外环的输出可以通过计算变成速度) 和 实际转速 进行偏差计算 再输入内环
代码实现:
1.PID参数结构体:
定义 位置、速度闭环 的PID参数结构体变量。(2个)
2.初始化PID参数:双环控制时 外环 PID参数 不要调很大 会对曲线影响很大 尽量调节内环
把目标值、期望值、累计偏差 清零,配置PID参数。
3.设置目标值
设置目标位置,在主函数 或者 上位机上 设置 我们需要的目标值(目标位置 的值)设置的是外环的目标值
4.PID双环控制
实际应用的时候,内环的计算频率要高于外环,这样系统会更加稳定
可以理解为 位置偏差越大速度越快(最大150) 位置偏差越小,速度就越慢。
对比 PID单环 位置环 看限制的 东西 会发现
此时 双环控制时 限制的是目标速度 不是限制的PWM(在单环中限制的是PWM)
所以 对 速度环 输入的 也是速度值 是目标速度值
所以 如果 位置环输出的值为小千1500(这个不可能 因为位置环的PID都很小!!!所以限制到了150为速度!!!) 那按照150的速度为目标速度 输入到 速度闭环 对 刚采集回来的 实际速度做偏差
如果 位置 相差得越大 位置环PID 输出的值 越大 此时
速度 :实际值-目标值>0 : 则实际慢一点, 所以会向着目标值迸发 就加速
实际值-目标值<0时 :实际快了,所以就减慢速度慢慢的将到达 位置的 目标值。
此时曲线 变得平滑。
2.电流(内环)+位置(外环) 双环控制
设置目标的位置,通过编码器计数 采集电机实际位置 与 目标位置做偏差 进行PID位置环计算
得出 实际位置与目标位置是否偏差很大 输出的值(经过限制其实是电流环中的目标电流值) 如果很大 则输入到电流环内的 目标值就会要更大一点
如果 现在的位置和将要达到的位置偏差没那么多 则 输入到电流环中的 目标值就会更小一点。
代码实现步骤
1.PID参数结构体:
定义 位置(外环)、电流(内环)的PID结构体参数变量。
2.初始化PID参数:
3.设置目标位置(设置外环目标值):
设置目标位置
4.PID双环控制
通过外环PID计算获得 输出 输出值 限制为 电流参数 作为 电流环 内环的 输入参数(目标值)
为什么要 判断外环输出是否为正数 如果为正数 则电机正转 如果为负数 电机反转
答:首先 电流没有负数 所以电流环 目标值必须是正数。 所以位置环最终作用到电流环的输入必须为正数。 外环输出为正数 则不管 ,外环输出为负数则 取反设置电机反转(因为一直是正数就一直为正转没办法反转,所以需要手动设置反转)
电流环输出 会 直接作用到 占空比上 。
PID输出后 会观察到实物现象就是不停地抖动 正反转来回轻微不停地抖
原因:电流ADC采集的数值不稳定 设定值例如在 10 但每次采集的 可能是10.1 9.8之类的 所以会不停地进行PID计算 从而 不停地输出 不一样的占空比 从而导致不停地抖动。
3.电流(内环)+速度(外环) 双环控制
速度作为外环 成为设定值
代码实现
积分限幅的作用
这两个主要是调试的时候,确定数值所使用的, 当确定好 积分限幅的数值后 就可以不用这两个函数了。
单纯的积分限制 幅度 当大于最大值时就限制为某个值,当小于最小值时 就限制为最小值的某个值。
积分饱和的问题
限制目标值范围: 此处限制的是转速 转速 正反转不能超过 300
进行积分限幅:(就是限制 积分环节 累积的 值 不能超过哪个值 方便 后期调整时能 及时的做出反映)
当这俩方法全部注销后会出现什么问题:
当我将电机的转速 调到一个永远到不了的数值 例如500 电机最大转速300
则 PID 的积分环节 会让 累积误差不断变大 。
当我下一步再想调小(调到正常 速度) 时 电机的反应时间会很长 (要消除累积的误差)
积分限幅范围应该是多少?
将电流和速度调至最大 然后看一下积分能到达什么程度 累计偏差的最大值 再根据系统能达到的累计偏差相应的去调大一点 积分的限幅
三环控制
位置环(最外环) 速度环(次外环) 电流环(内环)
首先设置目标位置(最终对象 为电机的位置) 通过编码器计数 测出 实际的位置
与目标位置做偏差 输出 偏差e(偏差越大,速度环的速度就越快) e通过限制 变成 速度环中 速度的输入 速度环中 通过编码器 测出 实际速度 与 位置环输出的目标速度 和 实际速度 做偏差
得出e2 e2通过限制 作为 电流环的 输入 目标电流 再通过电流采集电路 做偏差 得出e3
e3经过电流环 再通过限制 输出为 占空比 占空比输出 到电机。
代码实现步骤
闭环死区
假设 设置电机 目标位置 为 375 但 电机最小固定值位置变换 为50
也就是说 只能到达350或者400 到达不了375 此时电机 经过PID控制 在相对稳定时 就会在目标位置上下波动 如果是 速度或者 电流 环 则波动带来的 影响不明显
但是 位置环 则 整个电机 就会一直震荡 为了解决这个问题 我们可以人为的设定一个区间
此时 去判断整个系统 偏差是不是进入到这个区间内 如果是 则 清楚偏差 此时 整个系统 相当于开环状态 在区间之内 PID控制 无效 大于或者小于这个区间PID 就继续生效。
通常在 位置环中用到 在速度环和电流环中很少用