返回主站|会员中心|保存桌面

菲尼克斯连接器专营    

菲尼克斯连接器、连接端子

新闻分类
  • 暂无分类
联系方式
  • 联系人:吴经理
  • 电话:18576370666
  • 邮件:18576370666@qq.com
首页 > 新闻中心 > PID完全微分控制程序!
新闻中心
PID完全微分控制程序!
发布时间:2025-11-14        浏览次数:1        返回列表

PID 控制中的 “完全微分” 通常指包含理想微分环节的控制算法(理想 PID),其控制规律为:u(t)=Kp[e(t)+Ti10te(τ)dτ+Tddtde(t)]其中,Kp为比例系数,Ti为积分时间,Td为微分时间,e(t)为偏差(设定值 - 反馈值)。

在实际编程中,需将连续时间的微分方程离散化为数字形式(适用于 PLC、单片机等数字控制器)。以下是基于位置式 PID增量式 PID的完全微分控制程序实现思路(以 C 语言为例,可移植到其他平台)。

一、位置式 PID(完全微分)程序

位置式 PID 直接计算控制量的绝对值,适用于执行机构无积分特性的场景(如阀门、电加热)。

1. 算法离散化

将连续公式离散为:u(k)=Kp[e(k)+TiTi=0ke(i)+TTd(e(k)e(k1))]其中,T为采样周期(s),k为当前时刻,e(k)为当前偏差,e(k1)为上一时刻偏差。

2. 程序实现

c

运行

#include <stdio.h>// PID参数结构体typedef struct {
    float Kp;          // 比例系数
    float Ti;          // 积分时间(s)
    float Td;          // 微分时间(s)
    float T;           // 采样周期(s)
    float setpoint;    // 设定值
    float last_error;  // 上一时刻偏差
    float integral;    // 积分累计值
    float output;      // 输出控制量
    float output_max;  // 输出上限
    float output_min;  // 输出下限} PID_Controller;// 初始化PID参数void PID_Init(PID_Controller *pid, float Kp, float Ti, float Td, float T, 
              float output_min, float output_max) {
    pid->Kp = Kp;
    pid->Ti = Ti;
    pid->Td = Td;
    pid->T = T;
    pid->setpoint = 0.0f;
    pid->last_error = 0.0f;
    pid->integral = 0.0f;
    pid->output = 0.0f;
    pid->output_min = output_min;
    pid->output_max = output_max;}// 位置式PID计算(完全微分)float PID_PositionCalculate(PID_Controller *pid, float feedback) {
    float error;         // 当前偏差
    float proportional;  // 比例项
    float integral;      // 积分项
    float derivative;    // 微分项

    // 计算当前偏差
    error = pid->setpoint - feedback;

    // 比例项
    proportional = pid->Kp * error;

    // 积分项(带抗积分饱和)
    if (pid->output >= pid->output_max || pid->output <= pid->output_min) {
        // 输出饱和时,停止积分累计
        integral = pid->integral;
    } else {
        integral = pid->integral + (pid->Kp * pid->T / pid->Ti) * error;
        pid->integral = integral;  // 更新积分累计值
    }

    // 微分项(完全微分,基于当前与上一时刻偏差)
    derivative = (pid->Kp * pid->Td / pid->T) * (error - pid->last_error);
    // 保存当前偏差,用于下一周期微分计算
    pid->last_error = error;

    return pid->output;}// 示例:主函数调用int main() {
    PID_Controller pid;
    float feedback = 0.0f;  // 反馈值(如传感器采集)
    float control_output;   // 控制输出

    // 初始化PID:Kp=2.0, Ti=1.0s, Td=0.5s, 采样周期0.1s, 输出范围0~100
    PID_Init(&pid, 2.0f, 1.0f, 0.5f, 0.1f, 0.0f, 100.0f);
    pid.setpoint = 50.0f;   // 设定目标值

    // 模拟采样控制(循环执行)
    for (int i = 0; i < 100; i++) {
        // 模拟反馈值(实际中替换为传感器数据)
        feedback += 0.5f * control_output;  // 简化模型,实际需根据系统调整
        if (feedback > 60.0f) feedback = 60.0f;

        // 计算PID输出
        control_output = PID_PositionCalculate(&pid, feedback);

        // 打印结果(实际中输出到执行机构)
        printf("第%d次: 反馈=%.2f, 输出=%.2f\n", i+1, feedback, control_output);
    }

    return 0;}

二、增量式 PID(完全微分)程序

增量式 PID 计算控制量的变化量(Δu(k)),适用于步进电机、伺服电机等需要增量控制的执行机构。

1. 算法离散化

增量式公式由位置式推导而来:Δu(k)=u(k)u(k1)=Kp[e(k)e(k1)]+Kie(k)+Kd[e(k)2e(k1)+e(k2)]其中,Ki=KpT/Ti(积分系数),Kd=KpTd/T(微分系数)。

2. 程序实现

c

运行

#include <stdio.h>typedef struct {
    float Kp;          // 比例系数
    float Ki;          // 积分系数(Kp*T/Ti)
    float Kd;          // 微分系数(Kp*Td/T)
    float setpoint;    // 设定值
    float error[3];    // 偏差数组:error[0]=e(k), error[1]=e(k-1), error[2]=e(k-2)
    float output;      // 当前输出(累计值)
    float output_max;  // 输出上限
    float output_min;  // 输出下限} IncPID_Controller;// 初始化增量式PIDvoid IncPID_Init(IncPID_Controller *pid, float Kp, float Ki, float Kd, 
                 float output_min, float output_max) {
    pid->Kp = Kp;
    pid->Ki = Ki;
    pid->Kd = Kd;
    pid->setpoint = 0.0f;
    pid->error[0] = pid->error[1] = pid->error[2] = 0.0f;
    pid->output = 0.0f;
    pid->output_min = output_min;
    pid->output_max = output_max;}// 增量式PID计算(完全微分)float IncPID_Calculate(IncPID_Controller *pid, float feedback) {
    float delta_u;  // 控制量增量

    // 更新偏差数组(移位:保存前两时刻偏差)
    pid->error[2] = pid->error[1];  // e(k-2) = e(k-1)
    pid->error[1] = pid->error[0];  // e(k-1) = e(k)
    pid->error[0] = pid->setpoint - feedback;  // 计算当前偏差e(k)

    // 计算增量
    delta_u = pid->Kp * (pid->error[0] - pid->error[1]) 
            + pid->Ki * pid->error[0] 
            + pid->Kd * (pid->error[0] - 2*pid->error[1] + pid->error[2]);

    // 更新输出(累计增量)
    pid->output += delta_u;

    return pid->output;}// 示例:主函数调用int main() {
    IncPID_Controller inc_pid;
    float feedback = 0.0f;
    float control_output;

    // 初始化:Kp=2.0, Ki=0.2 (Kp*T/Ti=2.0*0.1/1.0), Kd=10 (Kp*Td/T=2.0*0.5/0.1)
    IncPID_Init(&inc_pid, 2.0f, 0.2f, 10.0f, 0.0f, 100.0f);
    inc_pid.setpoint = 50.0f;

    // 模拟控制循环
    for (int i = 0; i < 100; i++) {
        feedback += 0.5f * control_output;  // 模拟反馈
        if (feedback > 60.0f) feedback = 60.0f;

        control_output = IncPID_Calculate(&inc_pid, feedback);
        printf("第%d次: 反馈=%.2f, 输出=%.2f\n", i+1, feedback, control_output);
    }

    return 0;}

三、关键注意事项

  1. 微分环节的改进:完全微分对噪声敏感(高频干扰会放大),实际应用中常加入一阶惯性滤波(不完全微分),在微分项中增加滤波时间常数Tf,公式改为:微分项上一时刻微分项可减少噪声影响。

  2. 参数整定:优先用 “经验法” 或 “Ziegler-Nichols 法” 整定Kp,Ti,Td,微分时间Td通常为积分时间的 1/4~1/8。

  3. 抗积分饱和:位置式 PID 中,当输出超限时停止积分累计(如程序中 “积分项” 处理),避免系统超调过大。

  4. 采样周期:根据系统响应速度选择(如温度控制选 1~10s,电机速度控制选 0.01~0.1s),过短会放大噪声,过长会降低响应速度。

收缩
  • QQ咨询

  • 电话咨询

  • 18576370666
  • 添加微信客服