[技术问答] PID算法,增量式和位置式控制,实现代码

[复制链接]
603|0
 楼主| maudlu 发表于 2024-7-25 03:41 | 显示全部楼层 |阅读模式



  1. #include "pid.h"
  2. #include "main.h"

  3. // pid结构体的初始化
  4. void PIDStructInit(_PID *pid,float target,float p,float i,float d)
  5. {
  6.         pid->p = p;
  7.         pid->i = i;
  8.         pid->d = d;
  9.         pid->target = target;
  10.         pid->err_curr = 0;
  11.         pid->err_last = 0;
  12.         pid->err_sum = 0;
  13. }

  14. // pid 位置式计算
  15. float PID_Postion(_PID *pid,float current)
  16. {
  17.         volatile float Pout;   // 计算的输出值
  18.         pid->err_curr = pid->target - current;   // 计算当前误差
  19.         pid->err_sum += pid->err_curr;   //积分
  20.         Pout = (pid->p * pid->err_curr) + (pid->i * pid->err_sum) + (pid->d * (pid->err_curr - pid->err_last));   // 计算pid的值
  21.         printf("P = %.3f   I = %.3f   D = %.3f\r\n",(pid->p * pid->err_curr) , (pid->i * pid->err_sum) , (pid->d * (pid->err_curr - pid->err_last)));
  22.         pid->err_last = pid->err_curr;   // 记录上一次的误差为当前这一次
  23.         return Pout;
  24. }


  1. typedef struct _PID
  2. {
  3.         volatile float p;
  4.         volatile float i;
  5.         volatile float d;
  6.         float err_curr;   // 当前误差
  7.         float err_last;  // 上次误差
  8.         float err_sum;   // 误差和  积分
  9.         float err_last_last;  // 上上次的误差
  10.         float target;    // 目标值
  11.         float Out;  // 增量 输出的值
  12. }_PID;

  13. // pid结构体的初始化
  14. void PIDStructInit(_PID *pid,float target,float p,float i,float d)
  15. {
  16.         pid->p = p;
  17.         pid->i = i;
  18.         pid->d = d;
  19.         pid->target = target;
  20.         pid->err_curr = 0;
  21.         pid->err_last = 0;
  22.         pid->err_last_last = 0;
  23.         pid->err_sum = 0;
  24.         pid->Out  = 0;
  25. }


  26. // 增量式PID 计算
  27. float PID_Incremental(_PID *pid,float current)
  28. {
  29.         volatile float Pout;   // 计算的输出值
  30.         pid->err_curr = pid->target - current;   // 计算当前误差
  31.         Pout = (pid->p * (pid->err_curr - pid->err_last)) + (pid->i * pid->err_last) + (pid->d * ((pid->err_curr - 2* pid->err_last + pid->err_last_last)));   // 计算pid的值
  32.         printf("P = %.3f   I = %.3f   D = %.3f\r\n",(pid->p * (pid->err_curr - pid->err_last)) , (pid->i * pid->err_last) , (pid->d * ((pid->err_curr - 2* pid->err_last + pid->err_last_last))));
  33.         pid->err_last_last = pid->err_last;   // 上上次更新为上次
  34.         pid->err_last = pid->err_curr;     // 将上次的值更新为这次
  35.         pid->Out += Pout;
  36.         return pid->Out;
  37. }



您需要登录后才可以回帖 登录 | 注册

本版积分规则

54

主题

1693

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部