当前位置: 首页 > news >正文

PID控制技术深度剖析:从基础原理到高级应用(六)

PID 控制技术深度剖析:从基础原理到高级应用

在这里插入图片描述
在这里插入图片描述
最近在项目中有要开始进行PID的控制了,隔了很久没有做PID控制的东西了,所以想正好借这个机会,温习一下和PID有关的内容。

系列文章目录

PID控制技术深度剖析:从基础原理到高级应用(一)
PID控制技术深度剖析:从基础原理到高级应用(二)
PID控制技术深度剖析:从基础原理到高级应用(三)
PID控制技术深度剖析:从基础原理到高级应用(四)
PID控制技术深度剖析:从基础原理到高级应用(五)


文章目录

  • PID 控制技术深度剖析:从基础原理到高级应用
  • 系列文章目录
    • 七、PID 控制的 C 语言实现示例
      • 7.1 位置式 PID 控制的 C 语言实现
      • 7.2 增量式 PID 控制的 C 语言实现
      • 7.3 抗积分饱和 PID 控制的 C 语言实现
      • 7.4 模糊 PID 控制的 C 语言实现
      • 7.5 自适应 PID 控制的 C 语言实现
    • 八、总结与展望
      • 8.1 PID 控制的优势与局限
      • 8.2 PID 控制的发展趋势
      • 8.3 实际应用建议


七、PID 控制的 C 语言实现示例

7.1 位置式 PID 控制的 C 语言实现

以下是一个位置式 PID 控制器的 C 语言实现示例:

typedef struct {float Kp;        // 比例系数float Ki;        // 积分系数float Kd;        // 微分系数float setpoint;  // 设定值float last_error; // 上一次的误差float integral;  // 积分项float output_min; // 输出最小值限制float output_max; // 输出最大值限制
} PIDController;// PID控制器初始化函数
void PID_Init(PIDController *pid, float Kp, float Ki, float Kd, float setpoint, float output_min, float output_max) {pid->Kp = Kp;pid->Ki = Ki;pid->Kd = Kd;pid->setpoint = setpoint;pid->last_error = 0.0;pid->integral = 0.0;pid->output_min = output_min;pid->output_max = output_max;
}// PID计算函数
float PID_Compute(PIDController *pid, float feedback) {float error = pid->setpoint - feedback;float P = pid->Kp * error;pid->integral += error;float I = pid->Ki * pid->integral;float D = pid->Kd * (error - pid->last_error);float output = P + I + D;// 输出限幅if (output > pid->output_max) {output = pid->output_max;} else if (output < pid->output_min) {output = pid->output_min;}// 保存当前误差用于下一次计算pid->last_error = error;return output;
}

代码说明

  1. PIDController结构体包含了 PID 控制器的所有参数和状态变量。

  2. PID_Init函数用于初始化 PID 控制器的参数。

  3. PID_Compute函数根据当前反馈值计算控制输出,实现了位置式 PID 算法。

  4. 代码中包含了输出限幅处理,防止控制量超出安全范围。

  5. 积分项integral累积了所有历史误差,这是位置式 PID 的关键特性。

7.2 增量式 PID 控制的 C 语言实现

以下是一个增量式 PID 控制器的 C 语言实现示例:

typedef struct {float Kp;        // 比例系数float Ki;        // 积分系数float Kd;        // 微分系数float setpoint;  // 设定值float last_error; // 上一次的误差float prev_error; // 上上次的误差float output_min; // 输出最小值限制float output_max; // 输出最大值限制
} IncrementalPIDController;// 增量式PID控制器初始化函数
void IncrementalPID_Init(IncrementalPIDController *pid, float Kp, float Ki, float Kd, float setpoint, float output_min, float output_max) {pid->Kp = Kp;pid->Ki = Ki;pid->Kd = Kd;pid->setpoint = setpoint;pid->last_error = 0.0;pid->prev_error = 0.0;pid->output_min = output_min;pid->output_max = output_max;
}// 增量式PID计算函数
float IncrementalPID_Compute(IncrementalPIDController *pid, float feedback) {float error = pid->setpoint - feedback;float delta_P = pid->Kp * (error - pid->last_error);float delta_I = pid->Ki * error;float delta_D = pid->Kd * (error - 2 * pid->last_error + pid->prev_error);float delta_output = delta_P + delta_I + delta_D;// 输出限幅if (delta_output > pid->output_max) {delta_output = pid->output_max;} else if (delta_output < pid->output_min) {delta_output = pid->output_min;}// 保存误差用于下一次计算pid->prev_error = pid->last_error;pid->last_error = error;return delta_output;
}

代码说明

  1. IncrementalPIDController结构体包含了增量式 PID 控制器的所有参数和状态变量。

  2. IncrementalPID_Init函数用于初始化增量式 PID 控制器的参数。

  3. IncrementalPID_Compute函数根据当前反馈值计算控制量增量,实现了增量式 PID 算法。

  4. 增量式 PID 不需要积分项,而是通过计算当前误差与前两次误差的关系来确定控制增量。

  5. 每次调用IncrementalPID_Compute函数返回的是控制量的增量,而不是绝对输出值。

7.3 抗积分饱和 PID 控制的 C 语言实现

积分饱和是 PID 控制中常见的问题,当误差持续存在时,积分项会不断累积导致输出饱和。以下是一个具有抗积分饱和功能的 PID 控制器实现示例:

typedef struct {float Kp;        // 比例系数float Ki;        // 积分系数float Kd;        // 微分系数float setpoint;  // 设定值float last_error; // 上一次的误差float integral;  // 积分项float output_min; // 输出最小值限制float output_max; // 输出最大值限制
} AntiWindupPIDController;// 抗积分饱和PID初始化函数
void AntiWindupPID_Init(AntiWindupPIDController *pid, float Kp, float Ki, float Kd, float setpoint, float output_min, float output_max) {pid->Kp = Kp;pid->Ki = Ki;pid->Kd = Kd;pid->setpoint = setpoint;pid->last_error = 0.0;pid->integral = 0.0;pid->output_min = output_min;pid->output_max = output_max;
}// 抗积分饱和PID计算函数
float AntiWindupPID_Compute(AntiWindupPIDController *pid, float feedback) {float error = pid->setpoint - feedback;float P = pid->Kp * error;// 条件积分:只有当输出未达到极限时才更新积分项if (!((P > pid->output_max && error > 0) || (P < pid->output_min && error < 0))) {pid->integral += error;}float I = pid->Ki * pid->integral;float D = pid->Kd * (error - pid->last_error);float output = P + I + D;// 输出限幅if (output > pid->output_max) {output = pid->output_max;} else if (output < pid->output_min) {output = pid->output_min;}// 保存当前误差用于下一次计算pid->last_error = error;return output;
}

代码说明

  1. 在计算积分项时,首先检查当前的比例项输出是否已经达到了输出限制。

  2. 如果比例项输出已经达到限制,说明系统已经处于饱和状态,此时停止积分项的累积,避免积分饱和。

  3. 只有当输出未达到限制时,才继续累积积分项,这样可以有效防止积分饱和导致的控制性能下降。

  4. 其他部分与标准的位置式 PID 实现类似。

7.4 模糊 PID 控制的 C 语言实现

以下是一个模糊 PID 控制器的 C 语言实现示例:

// 模糊PID控制器结构体
typedef struct {PIDController pid;          // 基础PID控制器FuzzyController fuzzy;      // 模糊控制器float error;                // 当前误差float last_error;           // 上一次误差float error_rate;           // 误差变化率
} FuzzyPIDController;// 模糊PID初始化函数
void FuzzyPID_Init(FuzzyPIDController *fpid, float Kp, float Ki, float Kd, float setpoint, float output_min, float output_max) {PID_Init(&fpid->pid, Kp, Ki, Kd, setpoint, output_min, output_max);Fuzzy_Init(&fpid->fuzzy); // 模糊控制器初始化fpid->error = 0.0;fpid->last_error = 0.0;fpid->error_rate = 0.0;
}// 模糊PID计算函数
float FuzzyPID_Compute(FuzzyPIDController *fpid, float feedback) {// 计算误差和误差变化率fpid->error = fpid->pid.setpoint - feedback;fpid->error_rate = (fpid->error - fpid->last_error) / sample_time;// 模糊推理调整PID参数Fuzzy_AdjustParameters(&fpid->fuzzy, fpid->error, fpid->error_rate);// 更新PID参数PID_SetParameters(&fpid->pid, fpid->fuzzy.Kp, fpid->fuzzy.Ki, fpid->fuzzy.Kd);// 计算PID输出float output = PID_Compute(&fpid->pid, feedback);// 保存当前误差用于下一次计算fpid->last_error = fpid->error;return output;
}

代码说明

  1. 模糊 PID 控制器由一个基础 PID 控制器和一个模糊控制器组成。

  2. 模糊控制器根据当前误差和误差变化率调整 PID 参数。

  3. Fuzzy_AdjustParameters函数实现模糊推理过程,根据输入的误差和误差变化率调整 PID 参数。

  4. 模糊 PID 控制器的参数调整周期通常与 PID 计算周期相同,或者略长。

  5. 模糊控制器的具体实现需要根据模糊规则和隶属函数来设计。

7.5 自适应 PID 控制的 C 语言实现

以下是一个基于模型参考的自适应 PID 控制器的 C 语言实现示例:

// 自适应PID控制器结构体
typedef struct {PIDController pid;          // 基础PID控制器ReferenceModel ref_model;   // 参考模型float error;                // 当前误差float last_error;           // 上一次误差float output;               // 控制器输出
} AdaptivePIDController;// 自适应PID初始化函数
void AdaptivePID_Init(AdaptivePIDController *apid, float Kp, float Ki, float Kd, float setpoint, float output_min, float output_max) {PID_Init(&apid->pid, Kp, Ki, Kd, setpoint, output_min, output_max);ReferenceModel_Init(&apid->ref_model); // 参考模型初始化apid->error = 0.0;apid->last_error = 0.0;apid->output = 0.0;
}// 自适应PID计算函数
float AdaptivePID_Compute(AdaptivePIDController *apid, float feedback) {// 计算误差和误差变化率apid->error = apid->pid.setpoint - feedback;float error_rate = (apid->error - apid->last_error) / sample_time;// 计算参考模型的输出float ref_output = ReferenceModel_Output(&apid->ref_model, apid->pid.setpoint);// 计算模型误差float model_error = apid->output - ref_output;// 自适应调整PID参数apid->pid.Kp += adaptive_rate * model_error * apid->error;apid->pid.Ki += adaptive_rate * model_error * apid->error * sample_time;apid->pid.Kd += adaptive_rate * model_error * error_rate / sample_time;// 限制PID参数范围if (apid->pid.Kp < 0) apid->pid.Kp = 0;if (apid->pid.Ki < 0) apid->pid.Ki = 0;if (apid->pid.Kd < 0) apid->pid.Kd = 0;// 计算PID输出apid->output = PID_Compute(&apid->pid, feedback);// 保存当前误差用于下一次计算apid->last_error = apid->error;return apid->output;
}

代码说明

  1. 自适应 PID 控制器由一个基础 PID 控制器和一个参考模型组成。

  2. 参考模型定义了期望的系统响应特性。

  3. 根据参考模型的输出与实际系统输出的误差,调整 PID 参数,使得实际系统的响应尽可能接近参考模型的响应。

  4. 自适应调整律基于模型参考自适应控制理论,通常采用梯度下降法或 Lyapunov 稳定性理论设计。

  5. adaptive_rate是自适应增益,控制参数调整的速度。

八、总结与展望

8.1 PID 控制的优势与局限

PID 控制作为一种经典的控制算法,具有以下优势:

  1. 结构简单:PID 控制器由三个基本环节组成,结构简单,易于理解和实现(2)。

  2. 鲁棒性强:对模型精度要求不高,在一定的参数范围内都能保持较好的控制性能(11)。

  3. 适用范围广:适用于各种线性和部分非线性系统,在工业控制中得到广泛应用(11)。

  4. 理论成熟:经过多年的研究和应用,PID 控制的理论基础已经非常成熟,有多种参数整定方法可供选择(11)。

  5. 实现方便:无论是硬件实现还是软件实现都相对简单,对计算资源要求不高(6)。

然而,PID 控制也存在一些局限性:

  1. 参数整定困难:对于复杂系统,PID 参数的整定需要丰富的经验和技巧,有时需要反复试凑(11)。

  2. 对非线性系统适应性差:对于强非线性系统,固定参数的 PID 控制器难以获得满意的控制效果(12)。

  3. 对时变系统适应性差:当系统特性随时间变化时,固定参数的 PID 控制器性能会下降(47)。

  4. 对复杂多变量系统控制效果不佳:对于多变量、强耦合的系统,单一的 PID 控制器难以实现理想的控制效果(12)。

8.2 PID 控制的发展趋势

随着控制理论和计算机技术的发展,PID 控制也在不断发展和完善,主要发展趋势包括:

  1. 智能化:将模糊逻辑、神经网络、遗传算法等智能计算技术与 PID 控制相结合,形成智能 PID 控制,提高对复杂系统的控制能力(32)。

  2. 自适应化:开发具有在线辨识和参数自调整能力的自适应 PID 控制器,适应系统特性的变化(47)。

  3. 网络化:基于网络的 PID 控制技术,实现远程监控和分布式控制(12)。

  4. 集成化:将 PID 控制与其他先进控制策略(如预测控制、鲁棒控制等)集成,形成复合控制策略,提高控制性能(12)。

  5. 参数整定自动化:开发自动整定工具,减少人工干预,提高整定效率和精度(14)。

8.3 实际应用建议

基于本文的分析,针对 PID 控制的实际应用,提出以下建议:

  1. 根据系统特性选择合适的 PID 类型:对于大滞后系统,选择位置式 PID;对于快速响应系统,选择增量式 PID;对于易受干扰的系统,考虑使用抗积分饱和 PID(22)。

  2. 合理选择参数整定方法:简单系统可采用手动试凑法;工业过程控制可采用齐格勒 - 尼科尔斯法或科恩 - 库恩法;复杂系统可采用基于模型的方法或智能优化算法(11)。

  3. 重视抗干扰措施:根据系统特点,采取积分限幅、微分先行、滤波等抗干扰措施,提高控制系统的鲁棒性(6)。

  4. 结合先进控制策略:对于复杂系统,考虑将 PID 控制与模糊控制、自适应控制等先进控制策略结合,提高控制性能(32)。

  5. 进行充分的测试和验证:在实际应用前,对 PID 控制器进行充分的测试和验证,确保其在各种工况下都能稳定可靠地工作(12)。

  6. 持续优化和调整:随着系统特性的变化和控制要求的提高,需要持续优化和调整 PID 参数,确保控制性能始终处于最佳状态(11)。

PID 控制虽然已有几十年的历史,但仍然是工业控制中最常用的控制算法之一。随着控制理论和计算机技术的不断发展,PID 控制将继续发挥重要作用,并在新的应用领域展现出强大的生命力。

在这里插入图片描述

http://www.xdnf.cn/news/1477153.html

相关文章:

  • LeetCode 刷题【66. 加一、67. 二进制求和】
  • Linux bzip2 命令使用说明
  • 大数据毕业设计选题推荐-基于大数据的宫颈癌风险因素分析与可视化系统-Spark-Hadoop-Bigdata
  • Day22_【机器学习—集成学习(2)—Bagging—随机森林算法】
  • 学习nginx location ~ .*.(js|css)?$语法规则
  • Error metrics for skewed datasets|倾斜数据集的误差指标
  • 区块链论坛社区
  • 在 ES6 中如何提取深度嵌套的对象中的指定属性
  • 【111】基于51单片机停车场车位管理系统【Proteus仿真+Keil程序+报告+原理图】
  • 从RAW到BMP:工业视觉系统图像格式的转换与优化
  • 数据结构之二叉树(1)
  • STM32-----SPI
  • JUC、JVM八股补充
  • YOLOv8 在 Intel Mac 上的 Anaconda 一键安装教程
  • JBoltAI:赋能AI数智化升级的Java级引擎——深入解析企业级AI开发框架的核心能力与行业价值
  • 待定系数法分解分式
  • 后端(JDBC)学习笔记(CLASS 1):基础篇(一)
  • VBA之Excel应用第四章第七节:单元格区域的整行或整列扩展
  • 进阶向:密码生成与管理工具
  • 【PCIe EP 设备入门学习专栏 -- 8.1.3 PCIe EP AXI Bridge Module】
  • 发布vue项目、nginx配置及问题场景(history)
  • 服务器内存和普通计算机内存在技术方面有什么区别?
  • 前端入门——案例一:登录界面设计(html+css+js)
  • 【xss基本介绍】
  • 风电塔筒有毒有害气体监测控制系统
  • Maimo-AI驱动的行业研究工作平台
  • 理想汽车智驾方案介绍 4 World model + 强化学习重建自动驾驶交互环境
  • PostgreSQL与Greenplum常见连接客户端
  • 详解 Java 中的 CopyOnWriteArrayList
  • [光学原理与应用-420]:非线性光学 - 线性思维与非线性思维