#include <stdio.h> #include <stdlib.h> #include <string.h> /****************************************************************** 积分分离的 PID 控制算法 在普通 PID 控制中, 引入积分环节的目的, 主要是为了消除静差, 提高 控制精度。 但是在启动、 结束或大幅度增减设定时, 短时间内系统输出有很大的 偏差, 会造成 PID 运算的积分积累, 导致控制量超过执行机构可能允许的最大动 作范围对应极限控制量, 从而引起较大的超调, 甚至是震荡, 这是绝对不允许的。 为了克服这一问题, 引入了积分分离的概念, 其基本思路是 当被控量与设 定值偏差较大时, 取消积分作用; 当被控量接近给定值时, 引入积分控制, 以消 除静差, 提高精度。 其具体实现代码如下: *******************************************************************/ typedef struct { float SetSpeed; //定义设定值 float ActualSpeed; //定义实际值 float err; //定义偏差值 float err_last; //定义上一个偏差值 float Kp,Ki,Kd; //定义比例、 积分、 微分系数 float voltage; //定义电压值(控制执行器的变量) float integral; //定义积分值 } PID ; void PID_Init(); float PID_realize(float speed); PID pid ; FILE* out ; int main() { out = fopen("C:\\Users\\Administrator\\Desktop\\log.txt","w"); if(out) { printf("File open err...\n"); } printf("System begin \n"); PID_Init(); unsigned long count=0; while(count<2000) { float speed=PID_realize(200.0); printf("%f\n",speed); fprintf(out,"%f\n",speed); fflush(out); count++; } fclose(out); return 0; } void PID_Init() { printf("PID_init begin \n"); pid.SetSpeed=0.0; pid.ActualSpeed=0.0; pid.err=0.0; pid.err_last=0.0; pid.voltage=0.0; pid.integral=0.0; pid.Kp=0.2; pid.Ki=0.015; pid.Kd=0.2; printf("PID_init end \n"); } float PID_realize(float speed) { int index = 0 ; pid.SetSpeed=speed; pid.err=pid.SetSpeed-pid.ActualSpeed; // pid.integral+=pid.err; // pid.voltage=pid.Kp*pid.err+pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last); if(abs(pid.err)>200) { index=0; } else{ index=1; pid.integral+=pid.err; } pid.voltage=pid.Kp*pid.err+index*pid.Ki*pid.integral+pid.Kd*(pid.err-pid.err_last); pid.err_last=pid.err; pid.ActualSpeed=pid.voltage*1.0; return pid.ActualSpeed; }
时间: 2024-11-05 04:59:18