控制的基本知识
控制是指对一个系统或过程施加作用,使其按照预定的目标或规律运行的过程。
控制系统的基本组成
- 控制器:是控制系统的核心部分,它根据系统的输入和输出信息,按照一定的控制策略产生控制信号,以调节被控对象的行为。如工业自动化中的PLC(可编程逻辑控制器)、DCS(分布式控制系统)等。
- 执行器:接受控制器发出的控制信号,并将其转换为相应的物理动作,对被控对象施加控制作用,常见的有电机、阀门、液压缸等。
- 被控对象:是控制系统所要控制的设备、过程或系统,如加热炉、水箱、生产流水线等。
- 传感器:用于检测被控对象的状态或输出信息,将物理量转换为电信号等便于处理的信号形式,反馈给控制器,如温度传感器、压力传感器、流量传感器等。
控制方式
- 开环控制
- 原理:控制器根据给定的输入信号,按照一定的控制规律产生控制信号,直接作用于被控对象,而不考虑被控对象的实际输出情况。
- 特点:结构简单、成本低,但控制精度相对较低,抗干扰能力较弱,适用于对控制精度要求不高、干扰较小的场合,如普通的定时器控制的路灯开关系统。
- 闭环控制
- 原理:将被控对象的输出信号反馈到输入端,与给定输入信号进行比较,得到偏差信号,控制器根据偏差信号进行调节,使偏差趋于零,从而实现对被控对象的精确控制。
- 特点:控制精度高、抗干扰能力强,但结构复杂、成本较高,常用于对控制精度和稳定性要求较高的场合,如工业生产中的温度、压力、流量等控制系统。
PID是闭环控制
控制性能指标
- 稳定性:是控制系统的首要性能指标,指系统在受到干扰后,能够恢复到原来的平衡状态或跟踪给定输入的能力。一个稳定的控制系统才能正常工作,不稳定的系统无法实现有效的控制。
- 快速性:反映了系统对输入信号的响应速度,通常用上升时间、调节时间等指标来衡量。快速性好的系统能够快速跟踪输入信号的变化,提高系统的工作效率。
- 准确性:指系统的输出与给定输入之间的接近程度,常用稳态误差来衡量。准确性越高,系统的控制精度越高,能够更好地满足实际应用的要求。
控制理论基础
- 经典控制理论:主要以传递函数为数学模型,采用频率响应法、根轨迹法等分析和设计控制系统,适用于单输入单输出、线性定常系统的控制,在20世纪40-50年代得到了广泛的发展和应用,如PID控制就是经典控制理论的典型应用。
- 现代控制理论:以状态空间法为基础,能处理多输入多输出、非线性、时变系统等复杂系统的控制问题,包括最优控制、自适应控制、鲁棒控制等先进控制方法,在航空航天、机器人控制等领域有着重要应用。
常见的控制算法
除了PID控制算法外,还有以下常见算法:
- 模糊控制:以模糊集合论、模糊语言变量及模糊逻辑推理为基础的一种智能控制方法,不需要建立精确的数学模型,适用于复杂、难以精确建模的系统,如洗衣机的模糊控制,根据衣物的重量、脏污程度等模糊信息自动调整洗涤时间和力度。
- 神经网络控制:利用人工神经网络的自学习、自适应和非线性映射能力,对复杂系统进行建模和控制,具有很强的容错性和鲁棒性,在机器人控制、图像处理等领域有广泛应用。
- 预测控制:通过预测模型预测系统未来的输出,根据预测结果和给定的性能指标,在线滚动优化控制策略,适用于大滞后、多变量、强耦合的复杂工业过程控制。
PID算法
PID控制器中的P(比例)、I(积分)、D(微分)是三种基本的控制作用,它们在控制系统中各自发挥着独特的作用,以下是对它们的详细解释:
P(比例)
- 定义:比例控制是一种最简单的控制方式,其控制作用与偏差成正比关系。即控制器的输出信号u(t)与输入偏差e(t)之间的关系为u(t) = Kp * e(t),其中Kp为比例系数。
- 作用
- 快速响应偏差:能够快速对偏差做出反应,偏差一旦出现,比例控制立即产生相应的控制作用,试图减小偏差。
比如在水箱水位控制中,如果水位低于设定值,比例控制器会根据偏差大小成比例地打开进水阀门,偏差越大,阀门开度越大,进水速度越快。 - 确定系统响应速度:比例系数Kp决定了系统的响应速度。Kp越大,系统对偏差的反应越灵敏,控制作用越强,系统输出能更快地向设定值靠近。
- 快速响应偏差:能够快速对偏差做出反应,偏差一旦出现,比例控制立即产生相应的控制作用,试图减小偏差。
- 理解:可以将比例控制想象成一个“即时反应”机制,它只关注当前的偏差情况,偏差大就加大控制力度,偏差小就减小控制力度,就像一个人根据当前看到的情况立即做出反应一样。但它的局限性在于,仅靠比例控制往往无法使系统完全达到设定值,可能会存在一定的稳态误差,因为它只考虑了当前偏差,没有考虑偏差的历史积累和变化趋势。
I(积分)
-
定义:积分控制作用是对偏差随时间的积累进行运算,其输出与偏差的积分成正比,其中Ki为积分系数。
-
-
作用
- 消除稳态误差:只要系统存在偏差,积分作用就会不断累积,随着时间的增加,积分项会逐渐增大,直到偏差为零,使系统达到无差调节。
例如在温度控制系统中,若比例控制使温度接近设定值但仍有小偏差,积分作用会逐渐增加加热功率,最终消除这个偏差。 - 提高控制精度:积分作用能够对系统的微小偏差进行持续调节,使系统的输出更加精确地跟踪设定值,提高系统的控制质量。
- 消除稳态误差:只要系统存在偏差,积分作用就会不断累积,随着时间的增加,积分项会逐渐增大,直到偏差为零,使系统达到无差调节。
-
理解:积分控制就像是一个“记忆”机制,它会记住过去所有时刻的偏差情况,并将这些偏差积累起来,根据积累的结果来调整控制作用。它的目的是消除系统过去产生的偏差对当前的影响,让系统能够更加准确地达到设定值。不过,积分作用也不能过强,否则可能会导致系统超调量过大,甚至引起系统振荡。
D(微分)
-
定义:微分控制作用与偏差的变化率成正比,其中Kd为微分系数。
-
-
作用
- 预测偏差变化趋势:微分环节能够根据偏差的变化速度来提前预测偏差的变化趋势,在偏差还没有明显增大或减小之前,就提前给出相应的控制作用,起到“超前控制”的效果。
比如在电机速度控制中,当发现速度变化过快时,微分控制会提前施加一个反向的控制作用,阻止速度继续快速变化。 - 改善系统动态性能:通过提前调节,微分作用可以有效减小系统的超调量,缩短系统的调节时间,使系统更快地达到稳定状态,提高系统的稳定性和响应速度。
- 预测偏差变化趋势:微分环节能够根据偏差的变化速度来提前预测偏差的变化趋势,在偏差还没有明显增大或减小之前,就提前给出相应的控制作用,起到“超前控制”的效果。
-
理解:微分控制类似于一个“预测器”,它不仅仅关注当前的偏差,更关注偏差的变化趋势。就像一个人根据事物的发展趋势提前做出判断和准备一样,微分控制能够提前对可能出现的偏差变化做出反应,使系统的控制更加平稳、快速。但微分控制对噪声比较敏感,因为噪声可能会导致偏差的变化率出现虚假的波动,从而使微分控制产生误动作。
PID补充算法
在PID控制算法中,为了改善控制性能、避免系统出现异常情况,常使用积分限幅、积分分离、变速积分、积分先行、输出限幅等补充算法,下面为你详细讲解:
积分限幅
- 原理
在PID算法中,积分项会对误差进行不断累积。在一些情况下,误差可能会持续存在或者较大,导致积分项不断增大,进而使控制器输出大幅度变化,可能引起系统超调甚至不稳定。积分限幅就是对积分项的大小进行限制,当积分项超过设定的上限或下限时,将其限制在这个范围之内。 - 实现方式
在计算积分项时,添加判断逻辑。假设积分项为 I I I,积分限幅上限为 I m a x I_{max} Imax,下限为 I m i n I_{min} Imin,则积分项更新后需要进行如下判断:
# 计算积分项
I = I + Ki * e * dt
if I > I_max:
I = I_max
elif I < I_min:
I = I_min
积分分离
- 原理
在系统偏差较大时,积分作用可能会导致系统超调过大,因为此时误差较大,积分项会快速累积。积分分离算法的核心思想是当偏差绝对值 ∣ e ∣ |e| ∣e∣ 大于某个设定的阈值 β \beta β 时,取消积分作用(令积分项为 0即直接舍去);当偏差绝对值小于等于阈值时,再引入积分作用,这样可以有效减小系统的超调。 - 实现方式
if abs(e) > beta:
I = 0
else:
I = I + Ki * e * dt
变速积分
- 原理
积分分离算法是简单地在偏差较大时取消积分作用,而变速积分则是根据偏差的大小动态调整积分速度。当偏差较大时,积分速度慢,减小积分项的累积;当偏差较小时,积分速度快,加快消除稳态误差。可以通过一个比例系数 f ( e ) f(e) f(e) 来实现积分速度的调整, f ( e ) f(e) f(e) 是关于偏差 e e e 的函数,偏差越大, f ( e ) f(e) f(e) 越小。 - 实现方式
假设 f ( e ) f(e) f(e) 是一个根据偏差大小计算的系数,范围在 [ 0 , 1 ] [0, 1] [0,1] 之间,则积分项更新公式为:
f_e = calculate_f_e(e) # 根据偏差计算系数 f(e)
I = I + Ki * f_e * e * dt
积分先行
- 原理
传统的PID控制中,是先计算比例、积分、微分三项的和得到控制量。而积分先行是先对积分项进行单独处理和输出,比例和微分部分根据积分项的输出结果以及当前误差进行计算。这样可以在系统启动或设定值突变时,避免积分项的快速累积导致的超调问题,让积分作用更加平滑地加入到控制过程中。 - 实现方式
# 先更新积分项
I = I + Ki * e * dt
# 积分项单独输出
u_I = I
# 计算比例和微分项
u_P = Kp * e
u_D = Kd * (e - e_prev) / dt
# 最终控制量
u = u_I + u_P + u_D
输出限幅
- 原理
控制器的输出通常需要有一定的范围限制,例如执行器(如电机、阀门等)有其允许的最大和最小工作范围。如果PID控制器的输出超出这个范围,可能会损坏执行器或者导致系统异常。输出限幅就是对控制器的最终输出进行限制,使其在设定的范围之内。 - 实现方式
假设控制器输出为 u u u,输出限幅上限为 u m a x u_{max} umax,下限为 u m i n u_{min} umin,则:
if u > u_max:
u = u_max
elif u < u_min:
u = u_min
PID代码实现示例
利用cubemx和keil开发
在main.c文件中添加以下 PID 控制函数
#include "main.h"
#include "tim.h"
#include "gpio.h"
// PID结构体定义
typedef struct {
float Kp; // 比例系数
float Ki; // 积分系数
float Kd; // 微分系数
float setpoint; // 设定值
float integral; // 积分项
float prev_error; // 上一次的误差
} PID_HandleTypeDef;
// PID初始化函数
void PID_Init(PID_HandleTypeDef *pid, float Kp, float Ki, float Kd, float setpoint) {
pid->Kp = Kp;
pid->Ki = Ki;
pid->Kd = Kd;
pid->setpoint = setpoint;
pid->integral = 0.0;
pid->prev_error = 0.0;
}
// PID计算函数
float PID_Compute(PID_HandleTypeDef *pid, float current_value) {
float error = pid->setpoint - current_value;
pid->integral += error;
float derivative = error - pid->prev_error;
float output = pid->Kp * error + pid->Ki * pid->integral + pid->Kd * derivative;
pid->prev_error = error;
return output;
}
// 电机控制函数
void Motor_Control(float pwm_value) {
if (pwm_value > 0) {
// 正转
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, (uint32_t)pwm_value);
} else if (pwm_value < 0) {
// 反转
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, (uint32_t)(-pwm_value));
} else {
// 停止
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 0);
}
}
在main函数中使用 PID 控制电机
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM3_Init();
// 启动PWM输出
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
// PID参数初始化
PID_HandleTypeDef pid;
PID_Init(&pid, 1.0, 0.1, 0.01, 500.0); // 设定值为500
// 模拟当前电机速度
float current_speed = 0.0;
while (1)
{
// 计算PID输出
float pwm_value = PID_Compute(&pid, current_speed);
// 限制PWM值在0-1000范围内
if (pwm_value > 1000) {
pwm_value = 1000;
} else if (pwm_value < -1000) {
pwm_value = -1000;
}
// 控制电机
Motor_Control(pwm_value);
// 模拟电机速度变化
current_speed += pwm_value * 0.01;
HAL_Delay(10);
}
}
以凡人之躯,比肩神明。 —塞涅卡