studio_pid_c.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /**
  2. ******************************************************************************
  3. * @file : studio_pid_c.c
  4. * @author : wangyingjie
  5. * @brief : None
  6. * @attention : None
  7. * @date : 2025/5/23
  8. ******************************************************************************
  9. */
  10. #include "studio_pid_c.h"
  11. // 初始化PID结构体
  12. void init_pid(studio_pid *pid, double init_v, double goal_v, double p, double i, double d,
  13. double integral_limit_val, double output_limit_val)
  14. {
  15. pid->initval = init_v;
  16. pid->goal = goal_v;
  17. pid->Kp = p;
  18. pid->Ki = i;
  19. pid->Kd = d;
  20. pid->error = goal_v - init_v;
  21. pid->prev_error = pid->error;
  22. pid->inte_error = 0.0;
  23. pid->dif_error = 0.0;
  24. pid->integral_limit = integral_limit_val;
  25. pid->output_limit = output_limit_val;
  26. }
  27. // 计算PID输出
  28. double compute_pid(studio_pid *pid, double current_value)
  29. {
  30. // 计算当前误差 CTE
  31. double cte = pid->goal - current_value;
  32. // 更新积分和微分项
  33. pid->inte_error += cte; // 积分项
  34. pid->dif_error = cte - pid->prev_error; // 微分项
  35. pid->prev_error = cte;
  36. // 应用积分限幅
  37. if (pid->inte_error > pid->integral_limit)
  38. {
  39. pid->inte_error = pid->integral_limit;
  40. } else if (pid->inte_error < -pid->integral_limit)
  41. {
  42. pid->inte_error = -pid->integral_limit;
  43. }
  44. // 计算PID输出
  45. double output = pid->Kp * cte + pid->Ki * pid->inte_error + pid->Kd * pid->dif_error;
  46. // 应用输出限幅
  47. if (output > pid->output_limit)
  48. {
  49. output = pid->output_limit;
  50. } else if (output < -pid->output_limit)
  51. {
  52. output = -pid->output_limit;
  53. }
  54. return output;
  55. }
  56. // 设置PID参数
  57. void set_pid_params(studio_pid *pid, double p, double i, double d)
  58. {
  59. pid->Kp = p;
  60. pid->Ki = i;
  61. pid->Kd = d;
  62. }
  63. // 设置积分限幅
  64. void set_integral_limit(studio_pid *pid, double limit)
  65. {
  66. pid->integral_limit = limit;
  67. }
  68. // 设置输出限幅
  69. void set_output_limit(studio_pid *pid, double limit)
  70. {
  71. pid->output_limit = limit;
  72. }
  73. // 获取目标值
  74. double get_goal(const studio_pid *pid)
  75. {
  76. return pid->goal;
  77. }
  78. // 重置PID状态
  79. void reset_pid(studio_pid *pid)
  80. {
  81. pid->prev_error = pid->goal - pid->initval;
  82. pid->inte_error = 0.0;
  83. pid->dif_error = 0.0;
  84. }
  85. // 设置目标值并重置PID状态
  86. void set_goal(studio_pid *pid, double goal_v)
  87. {
  88. pid->goal = goal_v;
  89. reset_pid(pid);
  90. }