[嵌入式C编程与固件开发] 位置式PID控制算法

[复制链接]
封存into 发表于 2025-8-9 22:48 | 显示全部楼层 |阅读模式
本帖最后由 封存into 于 2025-8-9 22:52 编辑

位置式PID(Proportional-Integral-Derivative)控制是一种经典的闭环控制算法,通过比例(P)、积分(I)和微分(D)三个环节的线性组合计算控制量,直接输出执行机构的绝对位置(如阀门开度、电机目标位置等)。以下是详细说明:
1. 位置式PID公式
离散化后的位置式PID控制量 u(k)为:
u(k)=Kpe(k)+Ki∑i=0ke(i)⋅T+Kde(k)−e(k−1)Tu(k)=Kp​e(k)+Ki​  
u(k): 第k次控制周期的输出值(绝对位置)。
e(k): 当前误差(设定值 r(k)r(k) - 反馈值 y(k)y(k))。
Kp,Ki,Kd : 比例、积分、微分系数。
T: 采样周期(两次计算的间隔时间)。
直接输出绝对量:控制量 u(k) 直接对应执行机构的目标位置(如阀门开度0%~100%)。
积分项累积误差:积分项 ∑e(i) 会累积历史所有误差,可能导致饱和(积分 windup)。
抗干扰能力强:适合稳态精度要求高的场景(如温度控制、位置伺服)。
需手动初始化:首次运行时需设定初始值 u(0)(如阀门初始开度)。
3. 代码示例

typedef struct {
    float Kp;           // 比例系数
    float Ki;           // 积分系数
    float Kd;           // 微分系数
    float target;       // 目标值
    float actual;       // 实际值
    float error;        // 当前误差
    float error_last;   // 上次误差
    float integral;     // 积分项
    float integral_max; // 积分限幅
    float output_max;   // 输出限幅
} PID_Controller;

// PID控制器初始化
void PID_Init(PID_Controller *pid, float Kp, float Ki, float Kd, float target) {
    pid->Kp = Kp;
    pid->Ki = Ki;
    pid->Kd = Kd;
    pid->target = target;
    pid->actual = 0.0f;
    pid->error = 0.0f;
    pid->error_last = 0.0f;
    pid->integral = 0.0f;
    pid->integral_max = 100.0f;  // 默认积分限幅
    pid->output_max = 100.0f;    // 默认输出限幅
}

// 设置PID参数
void PID_SetParameters(PID_Controller *pid, float Kp, float Ki, float Kd) {
    pid->Kp = Kp;
    pid->Ki = Ki;
    pid->Kd = Kd;
}

// 设置限幅值
void PID_SetLimits(PID_Controller *pid, float integral_max, float output_max) {
    pid->integral_max = integral_max;
    pid->output_max = output_max;
}

// PID计算
float PID_Calculate(PID_Controller *pid, float actual) {
    float output = 0.0f;
   
    // 更新实际值
    pid->actual = actual;
   
    // 计算当前误差
    pid->error = pid->target - pid->actual;
   
    // 比例项
    output = pid->Kp * pid->error;
   
    // 积分项(带限幅)
    pid->integral += pid->error;
   
    // 积分限幅
    if (pid->integral > pid->integral_max) {
        pid->integral = pid->integral_max;
    } else if (pid->integral < -pid->integral_max) {
        pid->integral = -pid->integral_max;
    }
   
    output += pid->Ki * pid->integral;
   
    // 微分项
    output += pid->Kd * (pid->error - pid->error_last);
    pid->error_last = pid->error;
   
    // 输出限幅
    if (output > pid->output_max) {
        output = pid->output_max;
    } else if (output < -pid->output_max) {
        output = -pid->output_max;
    }
   
    return output;
}
4. 位置式 vs 增量式PID
特性                  位置式PID                                        增量式PID
输出形式        绝对位置(如阀门开度50%)        相对增量(如阀门增加2%)
积分处理        累积所有历史误差        仅用最近两次误差差分
抗饱和        需额外处理(如积分限幅)        天然抗饱和
适用场景        执行机构需绝对位置控制        执行机构需增量控制(如步进电机)
积分抗饱和(Anti-windup):当输出超过执行机构限幅时(如阀门最大开度),需停止积分累积。
手动/自动切换:从手动切换到自动时,需初始化
u(k) 为当前实际位置,避免跳变。
噪声抑制:微分项对高频噪声敏感,可对误差信号滤波或使用不完全微分。

您需要登录后才可以回帖 登录 | 注册

本版积分规则

53

主题

111

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

53

主题

111

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部