增量式编码器 当设备运动的时候增量式编码器才会输出信号,很多增量式编码器还会设置一个额外的通道 Z 输出信号,用来表示编码器特定的参考位置,传感器转一圈 Z 轴信号才会输出一个脉冲。增量式编码器只输出设备的位置变化和运动方向,不会输出设备的绝对位置。
绝对式编码器 二进制码与编码器转轴的每一个不同角度是唯一对应的
混合式绝对式编码器 输出两组信息:一组信息用于检测磁极位置,带有绝对信息功能;另一 组则和增量式编码器的输出信息完全相同。
PID 控制实质是对目标值和实际值误差进行比例、积分、微分运算 后的结果用来作用在输出上。
Kp 越大偏差减小的就越快,但是极易 引起震荡;
Kp 减小发生震荡的可能性减小,但是调节的速度变慢,单纯的比例控制存在不能消 除的静态误差,
Ti 越小,积分速度越快, 积分作用越强。积分作用太强使系统超调加大,甚至使系统出现振荡。
Td微分控制作用一个很大的缺陷是容易引入高频噪声,所有在干扰信号比较严重的流量控制系
统中不宜引入微分控制作用。
位置式
PID
优缺点:
优点:
:
位置式
PID
是一种非递推式算法,可直接控制执行机构(如平衡小车),
u(k)
的值和执行
机构的实际位置(如小车当前角度)是一一对应的,因此在执行机构不带积分部件的对象中可以
很好应用
;
缺点:
:
每次输出均与过去的状态有关,计算时要对
e(k)
进行累加,运算工作量大。
增量式
PID
优缺点:
优点:
:
1.
误动作时影响小,必要时可用逻辑判断的方法去掉出错数据。
2.
手动
/
自动切换时冲击小,便于实现无扰动切换。
3.
算式中不需要累加。控制增量
Δu(k)
的确定仅与最近
3
次的采样值有关。在速度闭环控制
中有很好的实时性。
缺点:
1.
积分截断效应大,有稳态误差;
2.
溢出的影响大。有的被控对象用增量式则不太好
typedef struct //位置式 PID 的算法
{ float target_val; //目标值
float actual_val; //实际值
float err; //定义偏差值
float err_last; //定义上一个偏差值
float Kp,Ki,Kd; //定义比例、积分、微分系数
float integral; //定义积分值
}_pid;
void PID_param_init()
{ /* 初始化参数 */
printf("PID_init begin \n");
pid.target_val=0.0;
pid.actual_val=0.0;
pid.err=0.0;
pid.err_last=0.0;
pid.integral=0.0;
pid.Kp = 0.31;
pid.Ki = 0.070;
pid.Kd = 0.3;
printf("PID_init end \n");
}
/**
* @brief PID 算法实现 位置式 PID 的算法
* @param val 实际值
* @note 无 5 * @retval 通过 PID 计算后的输出
*/
float PID_realize(float temp_val)
{ /* 目标值只在这里参与计算,计算目标值与实际值的误差 */
pid.err=pid.target_val-temp_val;
/* 误差累积 */
pid.integral+=pid.err;
/*PID 算法实现 */
pid.actual_val=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last);
/* 误差传递 */
pid.err_last=pid.err;
/* 返回的值是经过 pid 运算以后的值 */
return pid.actual_val;
}
float val=PID_realize(pid.actual_val);
int temp = val;
// 给通道 1 发送实际值
set_computer_value(SEED_FACT_CMD, CURVES_CH1, &temp, 1);
在 PID_realize(flfloat temp_val) 函数中以传参的形式将实际值传入函数中,目标值只在这里参与计算pid.err=pid.target_val-temp_val; 返回的值是经过 pid 运算以后的值 return pid.actual_val; 然后所有的计算数值都是 pid 结构体成员的运算;
/*pid*/ //增量式 PID
typedef struct
{ float target_val; //目标值
float actual_val; //实际值
float err; //定义当前偏差值
float err_next; //定义下一个偏差值
float err_last; //定义最后一个偏差值
float Kp, Ki, Kd; //定义比例、积分、微分系数
}_pid;
void PID_param_init()
{ /* 初始化参数 */
printf("PID_init begin \n");
pid.target_val=0.0;
pid.actual_val=0.0;
pid.err = 0.0;
pid.err_last = 0.0;
pid.err_next = 0.0;
// pid.Kp = 0.21;
// pid.Ki = 0.070;
// pid.Kd = 0.32;
pid.Kp = 0.21;
pid.Ki = 0.80;
pid.Kd = 0.01;
printf("PID_init end \n");
}
float PID_realize(float temp_val)
{
/* 目标值只在这里参与计算,计算目标值与实际值的误差 */
pid.err=pid.target_val-temp_val;
/*PID 算法实现 */
float increment_val = pid.Kp*(pid.err - pid.err_next) + pid.Ki*pid.err␣ , pid.Kd*(pid.err - 2 * pid.err_next + pid.err_last);
/* 累加 */
pid.actual_val += increment_val;
/* 传递误差 */
pid.err_last = pid.err_next;
pid.err_next = pid.err;
/* 返回的值是经过 pid 运算以后的值 */
return pid.actual_val;
}
在 PID_realize(flfloat temp_val) 函数中以传参的形式将实际值传入函数中,目标值只在这里参与计算 pid.err=pid.target_val-temp_val;
返回的值是经过
pid
运算以后的值
return pid.actual_val;
试凑法
1.
先是比例(
P
),再积分(
I
),最后是微分(
D
)
2.
调试时,将
PID
参数置于影响最小的位置,即
P
最大,
I
最大,
D
最小;
3.
按纯比例系统整定比例度,使其得到比较理想的调节过程曲线,然后再把比例度放大
1.2
倍左右,将积分时间从大到小改变,使其得到较好的调节过程曲线;
4.
最后在这个积分时间下重新改变比例度,再看调节过程曲线有无改善;
5.
如有改善,可将原整定的比例度减少,改变积分时间,这样多次的反复,就可得到合适的
比例度和积分时间;
6.
如果在外界的干扰下系统稳定性不好,可把比例度和积分时间适当增加一些,使系统足够
稳定;
7.
将整定好的比例度和积分时间适当减小,加入微分作用,以得到超调量最小、调节作用时
间最短的调节过程。
临界比例法
临界比例法:适用于闭环控制系统里将调节器置于纯比例的作用下,从大到小逐渐改变调节器的
比例度,并且得到等幅度的震荡过程就叫做临界比例度;
1.
将调节器的积分置于最大,微分置于
0
,比例度系数适当即可平衡一段时间,把系统投放
到自动运行中。
2.
然后将比例逐渐增大,增大到产生等幅现象,并记录下等幅时的临界比例系数和两个波峰
的时间间隔。
3.
根据记下的比例系数和周期,采用经验公式,计算调节器的参数。
控制方法
一般调节法
a.
确定比例增益
P
:确定比例增益
P
时,首先去掉
PID
的积分项和微分项,一般是令
Ti=0
、
Td=0
(具体见
PID
的参数设定说明),使
PID
为纯比例调节。输入设定为系统允许的最大
值的
60%~70%
,由
0
逐渐加大比例增益
P
,直至系统出现振荡;再反过来,从此时的比例
增益
P
逐渐减小,直至系统振荡消失,记录此时的比例增益
P
,设定
PID
的比例增益
P
为
当前值的
60%~70%
。比例增益
P
调试完成。
b.
确定积分时间常数
Ti
比例增益
P
确定后,设定一个较大的积分时间常数
Ti
的初值,然后
逐渐减小
Ti
,直至系统出现振荡,之后在反过来,逐渐加大
Ti
,直至系统振荡消失。记录
此时的
Ti
,设定
PID
的积分时间常数
Ti
为当前值的
150%~180%
。积分时间常数
Ti
调试完
成。
c.
确定积分时间常数
Td
积分时间常数
Td
一般不用设定,为
0
即可。若要设定,与确定
P
和
Ti
的方法相同,取不振荡时的
30%
。
d.
系统空载、带载联调,再对
PID
参数进行微调,直至满足要求:理想时间两个波,前高后
低
4
比
1
。
采样周期要小于整数周期的 1/2,采样的频率应该大于原始频率的 2 倍。
STM32
下位机与上位机联调实例
野火
PID
调试上位机协议说明