PID
来自Jack's Lab
(版本间的差异)
(以“== Overview == <br><br> == Reference == * [https://wenku.baidu.com/view/ee44725d9a6648d7c1c708a1284ac850ad02049c.html PID控制算法的C语言实现] * [https://...”为内容创建页面) |
(→Overview) |
||
| (未显示1个用户的3个中间版本) | |||
| 第1行: | 第1行: | ||
== Overview == | == Overview == | ||
| + | |||
| + | <source lang=cpp> | ||
| + | typedef struct { | ||
| + | float Kp; // 比例系数 | ||
| + | float Ki; // 积分系数 | ||
| + | float Kd; // 微分系数 | ||
| + | float integral; // 积分项 | ||
| + | float prev_error; // 上次误差 | ||
| + | float setpoint; // 目标电流 | ||
| + | } PID_Controller; | ||
| + | |||
| + | float PID_Calculate(PID_Controller *pid, float actual) | ||
| + | { | ||
| + | float error = pid->setpoint - actual; | ||
| + | |||
| + | // 比例项 | ||
| + | float p_out = pid->Kp * error; | ||
| + | |||
| + | // 积分项(防饱和) | ||
| + | pid->integral += error; | ||
| + | if(pid->integral > 1000) pid->integral = 1000; | ||
| + | if(pid->integral < -1000) pid->integral = -1000; | ||
| + | float i_out = pid->Ki * pid->integral; | ||
| + | |||
| + | // 微分项 | ||
| + | float d_out = pid->Kd * (error - pid->prev_error); | ||
| + | pid->prev_error = error; | ||
| + | |||
| + | // 输出 | ||
| + | float output = p_out + i_out + d_out; | ||
| + | |||
| + | // 限幅 | ||
| + | if(output > 0.95) output = 0.95; | ||
| + | if(output < 0.05) output = 0.05; | ||
| + | |||
| + | return output; | ||
| + | } | ||
| + | </source> | ||
| + | |||
| + | |||
| + | 改进型 PI 控制(消除积分饱和): | ||
| + | <source lang=cpp> | ||
| + | // 条件积分法 | ||
| + | if(!((output >= max_limit && error > 0) || | ||
| + | (output <= min_limit && error < 0))) { | ||
| + | integral += error; | ||
| + | } | ||
| + | |||
| + | // 积分分离法 | ||
| + | if(fabs(error) > threshold) { | ||
| + | // 只用比例控制 | ||
| + | output = Kp * error; | ||
| + | } else { | ||
| + | // 加入积分 | ||
| + | integral += error; | ||
| + | output = Kp * error + Ki * integral; | ||
| + | </source> | ||
<br><br> | <br><br> | ||
| 第7行: | 第64行: | ||
* [https://wenku.baidu.com/view/ee44725d9a6648d7c1c708a1284ac850ad02049c.html PID控制算法的C语言实现] | * [https://wenku.baidu.com/view/ee44725d9a6648d7c1c708a1284ac850ad02049c.html PID控制算法的C语言实现] | ||
* [https://blog.csdn.net/wangshuai_embeded/article/details/45719109?utm_source=blogxgwz3 工业PID控制方法的C语言实现详解] | * [https://blog.csdn.net/wangshuai_embeded/article/details/45719109?utm_source=blogxgwz3 工业PID控制方法的C语言实现详解] | ||
| + | |||
| + | * [https://www.jianshu.com/p/d3b1c3d307e0 我所理解的卡尔曼滤波] | ||
| + | * [https://blog.csdn.net/u012554092/article/details/78290223 理解卡尔曼滤波的三重境界] | ||
<br><br> | <br><br> | ||
<br><br> | <br><br> | ||
<br><br> | <br><br> | ||
2026年1月29日 (四) 11:23的最后版本
[编辑] 1 Overview
typedef struct {
float Kp; // 比例系数
float Ki; // 积分系数
float Kd; // 微分系数
float integral; // 积分项
float prev_error; // 上次误差
float setpoint; // 目标电流
} PID_Controller;
float PID_Calculate(PID_Controller *pid, float actual)
{
float error = pid->setpoint - actual;
// 比例项
float p_out = pid->Kp * error;
// 积分项(防饱和)
pid->integral += error;
if(pid->integral > 1000) pid->integral = 1000;
if(pid->integral < -1000) pid->integral = -1000;
float i_out = pid->Ki * pid->integral;
// 微分项
float d_out = pid->Kd * (error - pid->prev_error);
pid->prev_error = error;
// 输出
float output = p_out + i_out + d_out;
// 限幅
if(output > 0.95) output = 0.95;
if(output < 0.05) output = 0.05;
return output;
}
改进型 PI 控制(消除积分饱和):
// 条件积分法
if(!((output >= max_limit && error > 0) ||
(output <= min_limit && error < 0))) {
integral += error;
}
// 积分分离法
if(fabs(error) > threshold) {
// 只用比例控制
output = Kp * error;
} else {
// 加入积分
integral += error;
output = Kp * error + Ki * integral;
[编辑] 2 Reference