1.经典PID算法
PID控制器是工业控制中常用的调节器,通过比例(P)、积分(I)和微分(D)三个环节的组合来实现对系统的控制。
1.1位置式PID
1.1.1位置式PID概念
位置式PID控制的核心思想是:基于当前误差及其历史信息,直接计算控制器的绝对输出值。它实现了误差到控制量的直接映射关系。

1.1.2位置式PID优点&缺点
优点 | 1.直接给出控制器的绝对输出值 |
---|---|
2.对于绝对位置控制系统更加适用 | |
3.稳态误差收敛性好 | |
缺点 | 1.每次计算都要考虑误差的累积和,计算量相对较大 |
2.积分饱和问题明显,需要积分限幅 | |
3.控制量突变时容易导致系统超调 | |
4.参数调整时会影响整个控制回路 |
1.1.3位置式PID的适用场景
位置式PID适用场景 | 1.对控制精度要求高的系统 |
---|---|
2.控制对象为位置、角度等绝对量的控制系统 | |
3.输出可以直接控制执行器位置的系统 | |
4.稳态性能要求高的场合 |
1.1.4位置式PID参考代码
typedef struct {
float Kp; // 比例系数
float Ki; // 积分系数
float Kd; // 微分系数
float sumError; // 积分项
float lastError; // 上次误差
float outputLimit; // 输出限幅
} PositionPID;
float PositionPID_Calculate(PositionPID *pid, float setPoint, float actualValue) {
float error = setPoint - actualValue;
// 计算积分项
pid->sumError += error;
// 设置积分限幅,防止积分饱和
if (pid->sumError > pid->outputLimit) {
pid->sumError = pid->outputLimit;
} else if (pid->sumError < -pid->outputLimit) {
pid->sumError = -pid->outputLimit;
}
// 计算微分项
float dError = error - pid->lastError;
// 计算PID输出
float output = pid->Kp * error + pid->Ki * pid->sumError + pid->Kd * dError;
// 输出限幅
if (output > pid->outputLimit) {
output = pid->outputLimit;
} else if (output < -pid->outputLimit) {
output = -pid->outputLimit;
}
// 保存当前误差
pid->lastError = error;
return output;
}
1.2增量式PID
1.2.1增量式PID概念
增量式PID控制的核心思想是:计算控制量的变化增量,而非绝对值,控制器输出是增量的累加。它实现了误差变化到控制量变化的映射关系。

1.2.2增量式PID优点&缺点
优点 | 1.无积分累积,不会出现积分饱和问题 |
---|---|
2.控制量增量式变化,系统更平稳,对执行机构冲击小 | |
3.算法自带"抗风扰"特性,对干扰有较好的抑制能力 | |
4.断电或计算机故障时,执行机构可以保持在当前位置,安全性更高 | |
缺点 | 1.对系统的稳态误差收敛性不如位置式 |
2.不适合对控制精度要求极高的场合 | |
3.控制系统有静差,难以完全消除 |
1.2.3增量式PID适用场景
增量式PID适用场景 | 1.电机调速等需要平稳变化的控制场合 |
---|---|
2.执行机构不能接受突变的系统,如阀门控制 | |
3.对系统安全性要求较高的场合 | |
4.嵌入式系统中,计算资源有限的场合 | |
5.抗干扰要求高的控制系统 |
1.2.4增量式PID参考代码
typedef struct {
float Kp; // 比例系数
float Ki; // 积分系数
float Kd; // 微分系数
float lastError; // 上次误差
float prevError; // 上上次误差
float lastOutput; // 上次输出值
float incrementLimit; // 增量限幅
float outputLimit; // 输出限幅
} IncrementalPID;
float IncrementalPID_Calculate(IncrementalPID *pid, float setPoint, float actualValue) {
float error = setPoint - actualValue;
// 计算PID增量
float pTerm = pid->Kp * (error - pid->lastError);
float iTerm = pid->Ki * error;
float dTerm = pid->Kd * (error - 2 * pid->lastError + pid->prevError);
float increment = pTerm + iTerm + dTerm;
// 增量限幅
if (increment > pid->incrementLimit) {
increment = pid->incrementLimit;
} else if (increment < -pid->incrementLimit) {
increment = -pid->incrementLimit;
}
// 计算当前输出
float output = pid->lastOutput + increment;
// 输出限幅
if (output > pid->outputLimit) {
output = pid->outputLimit;
} else if (output < -pid->outputLimit) {
output = -pid->outputLimit;
}
// 更新状态
pid->prevError = pid->lastError;
pid->lastError = error;
pid->lastOutput = output;
return output;
}
2.经典PID算法改进
下面这些PID改进方法各有特点,适用于不同的控制场景。通过合理选择和组合这些改进策略,可以显著提高PID控制器的性能,增强系统的稳定性、响应速度和抗干扰能力。在实际应用中,通常需要根据具体的控制对象和控制要求,选择合适的改进方法并进行参数调整。
2.1积分限幅
积分限幅是为了防止积分项在系统出现较大偏差时过度累积,导致控制器输出过大或过小,从而引起系统振荡或饱和。通过设置积分项的上限和下限,限制积分项的累积范围,避免积分项过大或过小。
2.2积分分离
积分项作用一般位于调控后期,用来消除持续的误差,调控前期一般误差较大且不需要积分项作用,如果此时仍然进行积分,则调控进行到后期时,积分项可能已经累积了过大的调控力,这会导致超调。
积分分离是指在系统偏差较大时,暂时关闭积分作用,仅使用比例和微分控制;当系统偏差较小时,再重新引入积分作用。这样可以避免在大偏差情况下积分项过度累积,导致系统响应过慢或超调。
2.3变速积分
变速积分是根据系统偏差的大小动态调整积分速度。当偏差较大时,积分速度较慢,避免积分项过快累积;当偏差较小时,积分速度加快,提高系统的响应速度。这种方法可以在不同偏差情况下灵活调整积分作用。
2.4微分先行
微分先行是指在控制器的输出中加入微分作用,但不对偏差进行微分,而是对系统的输出进行微分。这样可以避免对偏差的突变过于敏感,减少系统的振荡。
2.5不完全微分
不完全微分是对传统微分作用的改进,通过在微分环节中加入低通滤波器,减少高频噪声对微分项的影响。这样可以避免微分项对噪声过于敏感,提高系统的抗干扰能力。
2.6输出偏移
输出偏移是指在控制器的输出中加入一个固定的偏移量,用于补偿系统的静态误差或外部干扰。通过调整偏移量,可以使系统在稳态时达到期望的输出值。
2.7输入死区
输入死区是指在系统偏差较小时,控制器不进行调节,只有当偏差超过一定阈值时,控制器才开始工作。这样可以避免控制器对微小偏差过于敏感,减少系统的频繁调节。
2.8分段控制
分段控制通过“粗调 + 精调”策略,结合开关控制的快速性和PID的精确性,解决了温控系统在大误差时的响应速度问题和小误差时的稳定性问题。
比如温控系统,在误差较大时,可以考虑满功率开启,加快升温速度,在误差较小的时候PID再介入计算。