一、背景:
PID控制器是一种常见的反馈控制器,用于控制系统中的物理量:温度,速度,位置等。PID的名称来自于其三个组成部分:比例项(P), 积分项(I), 微分项(D)。PID控制的目标是使输入的参数(例如温度)趋近于目标点(例如目标温度),并保持在设定点附近。
比例项(P):用于根据当前误差计算输出。若误差较大,则输出也较大,从而加快系统的响应速度。
积分项(I): 用于消除稳态误差。若稳态误差持续存在,则积分项会逐渐增加,从而增加输出,直到误差消失。
稳态误差举例:设目标温度为30°C,实际25°C,此时差值e为5。比例项(P)为固定值。若此时输出u可令温度在0.5h内上升5°C,但环境影响可令温度在0.5h内降低5°C,则输出u的作用被抵消,则偏差一直存在。该偏差即为稳态误差。
微分项(D):用于减少系统的超调和震荡。若误差变化速度较快,则微分项会增加输出,从而较少超调和震荡。
二、简单实现:
- // PID控制器参数
- #define KP 1.0f
- #define KI 0.1f
- #define KD 0.01f
-
- // 温度传感器参数
- #define TARGET_TEMP 25.0f
- #define ROOM_TEMP 20.0f
- #define MAX_TEMP 100.0f
- #define MIN_TEMP 0.0f
-
- //PID控制器变量
- float error = 0.0f;
- float integral = 0.0f;
- float derivative = 0.0f;
- float last_err = 0.0f;
- float output = 0.0f;
-
- //温度传感器变量
- float current_temp = ROOM_TEMP;
-
- //PID控制器函数
- float pid_ctrl(float set_point, float input, float dt) {
- error = set_point - input;
- integral += error * dt;
- derivative = (error - last_error) / dt;
- output = KP * error + KI * intergal + KD * derivative;
- last_error = error;
-
- return output;
- }
-
- int main(void) {
- //模拟时间步长
- float dt = 0.1f;
-
- //模拟时间
- float t = 0.0f;
-
- //模拟循环
- while(1) {
- //计算PID输出
- output = pid_ctrl(TARGET_TEMP, current_temp, dt);
-
- //限制输出范围
- if (output > MAX_TEMP) {
- output = MAX_TEMP;
- } else if (output < MIN_TEMP) {
- output = MIN_TEMP;
- }
-
- //模拟温度变化
- current_temp += (output - current_temp) * dt;
- //输出结果
- printf("Time: %f, set_point: %f, input: %f, output: %f\n", t, TARGET_TEMP, current_temp, output);
- //时长变化
- t += dt;
- }
-
- return 0;
- }
在该例程中,创建了一个简单的PID控制器,定义了一些常量来表示PID控制器的参数和温度传感器的反馈的参数。主函数中使用while循环模拟时间变化,并在每个时间步长中计算PID输出和温度变化。最后输出结果并令时间变化。