#include <stdio.h>
#include <math.h>
typedef struct {
float kp, ki, kd;
float error;
float last_error;
float sum_error;
float tar;
float now;
} PID;
/**
* @brief PID算法初始化函数,数值可根据自身需求进行调整
* @param PID类型结构体
* @retval 无
*/
void pid_init(PID *pid) {
pid->kp = 0.5; //比例系数,根据实际情况调整
pid->ki = 0.5; //积分系数,根据实际情况调整
pid->kd = 0.1; //微分系数,根据实际情况调整
pid->error = 0; //当前偏差
pid->last_error = 0; //上一次的偏差
pid->sum_error = 0; //历史偏差总和,使用积分隔离效果更好
pid->tar = 50; //目标值
pid->now = 0; //当前值
}
/**
* @brief PID算法控制函数
* @param PID类型结构体,积分隔离标志
* @retval 无
*/
void pid_control(PID *pid, bool ki_flag) {
pid->error = pid->tar - pid->now ;
if (ki_flag)//积分隔离
pid->sum_error += pid->error ;
pid->now += pid->kp * pid->error + pid->ki * pid->sum_error + pid->kd * (pid->error - pid->last_error );
pid->last_error = pid->error ;
}
int main() {
bool ki_flag = 0;//积分隔离标志,避免一开始偏差太大导致需要更长时间调整
float temp;//暂存目标值,一旦目标值改变了,做好积分隔离
int j = 2;
PID pid;
pid_init(&pid);
while (j--) {
if (abs(pid.tar - temp) > pid.tar * 0.2)//达到积分隔离要求,进行积分隔离
ki_flag = 0;
temp = pid.tar ;
for (int i = 0; i < 20; ++i) {
pid_control(&pid, ki_flag);
if (pid.error < (pid.tar * 0.2))//脱离积分隔离要求,可以进行积分
ki_flag = 1;
printf("error = %f\n", pid.error );
printf("sum_error = %f\n", pid.sum_error );
printf("now = %f\n", pid.now );
printf("tar = %f\n", pid.tar );
printf("\n\n");
}
pid.tar += 70;//模拟目标值改变
}
return 0;
}
DEV C++实现简单PID控制算法
最新推荐文章于 2024-07-29 13:48:22 发布