1. PID控制器基础实现

任务目标

实现一个位置式PID控制器,包含比例(P)、积分(I)、微分(D)三个环节的计算,并通过阶跃响应测试验证控制器行为。给定目标值与反馈值,控制器输出控制量,使系统输出逐步逼近目标值。

核心实现

#include <stdio.h>
#include <stdlib.h>

typedef struct {
    double kp;          // 比例系数
    double ki;          // 积分系数
    double kd;          // 微分系数
    double integral;    // 积分累计值
    double prev_error;  // 上一次误差
    double dt;          // 采样周期(秒)
} PIDController;

// 初始化PID参数
void pid_init(PIDController *pid, double kp, double ki, double kd, double dt) {
    pid->kp = kp;
    pid->ki = ki;
    pid->kd = kd;
    pid->integral = 0.0;
    pid->prev_error = 0.0;
    pid->dt = dt;
}

// 位置式PID计算
double pid_compute(PIDController *pid, double setpoint, double measurement) {
    double error = setpoint - measurement;
    
    // 积分项(累加)
    pid->integral += error * pid->dt;
    
    // 微分项(后向差分)
    double derivative = (error - pid->prev_error) / pid->dt;
    
    // 更新上一次误差
    pid->prev_error = error;
    
    // 输出 = P + I + D
    return pid->kp * error + pid->ki * pid->integral + pid->kd * derivative;
}

// 模拟一阶惯性系统(被控对象):G(s) = 1 / (s + 1)
double plant_update(double output, double state, double dt) {
    // 离散化:state_new = state + dt * (-state + output)
    return state + dt * (-state + output);
}

int main() {
    PIDController pid;
    pid_init(&pid, 2.0, 0.5, 0.1, 0.01);
    
    double setpoint = 1.0;      // 目标值(阶跃输入)
    double measurement = 0.0;   // 当前测量值
    double control = 0.0;       // 控制器输出
    
    printf("step, measurement, control\n");
    for (int i = 0; i < 200; i++) {
        control = pid_compute(&pid, setpoint, measurement);
        measurement = plant_update(control, measurement, pid.dt);
        
        if (i % 10 == 0) {
            printf("%d, %.4f, %.4f\n", i, measurement, control);
        }
    }
    return 0;
}

运行与验证

编译运行:

gcc pid_controller.c -o pid_controller -lm
./pid_controller

预期输出特征:程序输出200步仿真数据,每10步打印一次。观察测量值(measurement)应从0逐步上升并稳定在1.0附近(稳态误差趋近于0),控制量(control)在初始阶段较大,随后逐渐减小并趋于稳定。若P、I、D系数设置合理,系统应在约50~100步内收敛到目标值。

验证方法:将输出数据导入Excel或绘图工具,绘制测量值随时间变化曲线。若曲线呈现上升后收敛于1.0且无明显振荡,则PID参数整定正确,控制器实现无误。可尝试修改kp、ki、kd值观察响应变化:增大kp加快响应但可能引起振荡,增大ki消除稳态误差但可能超调,增大kd抑制振荡但过大可能导致系统不稳定。

关键说明

  • 位置式PID直接对误差进行比例、积分、微分运算,输出为控制量,适用于执行机构不带积分特性的系统。
  • 积分项采用累加方式,需注意积分饱和问题(本案例未做限幅,实际工程中应增加积分限幅或抗积分饱和处理)。
  • 微分项采用后向差分法,对噪声敏感,实际应用中常配合低通滤波使用。
  • 被控对象使用一阶惯性系统模拟,用于验证控制器闭环响应,实际工程中替换为真实系统模型或硬件接口即可。