/Modules/PID/pid.c

https://gitlab.com/krucios/Astraeus_FW · C · 97 lines · 48 code · 15 blank · 34 comment · 7 complexity · 69729f071c04a8af143d2f0a15b6b62b MD5 · raw file

  1. /*
  2. * pid.c
  3. *
  4. * Created on: 31 èþëÿ 2016 ã.
  5. * Author: kruci_000
  6. */
  7. #include "pid.h"
  8. #include <math.h>
  9. #include <Helpers/conversion_defines.h>
  10. #include <Modules/MPU6050/mpu6050.h>
  11. #include <Modules/AHRS/MadgwickAHRS.h>
  12. #include <Modules/MAVLink/common/mavlink.h>
  13. volatile int16_t Kp_u = 16, Kd_u = 3, Ki_u = 0;
  14. volatile uint16_t force = 0;
  15. static int16_t Dtmp_r, Dtmp_p, Dtmp_y;
  16. static int16_t Ptmp_r, Ptmp_p, Ptmp_y;
  17. static int16_t Itmp_r, Itmp_p, Itmp_y;
  18. static float roll, pitch, yaw;
  19. static int16_t roll_deg, pitch_deg, yaw_deg;
  20. /*
  21. inline void pid_update(float q0, float q1, float q2, float q3, float gx,
  22. float gy, float gz, uint16_t force, int16_t* pow) {
  23. */
  24. inline void pid_update(int16_t* pow) {
  25. uint8_t i;
  26. int16_t sum_r, sum_p, sum_y;
  27. mavlink_quaternion_to_euler(q, &roll, &pitch, &yaw);
  28. roll_deg = roll * RAD_TO_DEG;
  29. pitch_deg = pitch * RAD_TO_DEG;
  30. yaw_deg = yaw * DEG_TO_RAD;
  31. if (force < PID_FORCE_MIN) { // if force so low
  32. pow[0] = pow[1] = pow[2] = pow[3] = 0;
  33. return;
  34. } else if (force > PID_FORCE_MAX) // limit force if it so high for to prevent destabilization
  35. force = PID_FORCE_MAX;
  36. Ptmp_r = (int16_t) ((int32_t)Kp_u * roll_deg / Kp_d);
  37. Ptmp_p = (int16_t) ((int32_t)Kp_u * pitch_deg / Kp_d);
  38. Ptmp_y = (int16_t) ((int32_t)Kp_u * yaw_deg / Kp_d);
  39. /*
  40. Itmp_r += (int16_t) ((int32_t)Ki_u * _ay / Ki_d);
  41. Itmp_p += (int16_t) ((int32_t)Ki_u * _ax / Ki_d);
  42. Itmp_y += (int16_t) ((int32_t)Ki_u * _az / Ki_d);
  43. */
  44. Itmp_r += (int16_t) ((int32_t)Ki_u * roll_deg / Ki_d);
  45. Itmp_p += (int16_t) ((int32_t)Ki_u * pitch_deg / Ki_d);
  46. Itmp_y += (int16_t) ((int32_t)Ki_u * yaw_deg / Ki_d);
  47. Dtmp_r = (int16_t) ((int32_t)Kd_u * _gx / Kd_d);
  48. Dtmp_p = (int16_t) ((int32_t)Kd_u * _gy / Kd_d);
  49. Dtmp_y = (int16_t) ((int32_t)Kd_u * _gz / Kd_d);
  50. /*
  51. if (q0 > 0) { // åñëè óãîë ïîâîðîòà >0.5 ãðàäóñà, íóæíî ñòàáèëèçèðîâàòü ïî óãëàì.
  52. // (q1, q2, q3) - âåêòîð â ëîêàëüíîé ñèñòåìå êîîðäèàíò âîêðóã êîòîðîãî íåîáõîäèìî ïîâåðíóòü êîïòåð
  53. float P_gain = (float) Kp_u / 16.0; //êîýô óñèëåíèÿ
  54. float angle = acos(q0) * P_gain; //óãîë ïîâîðîòà
  55. float invNorma = invSqrt(q1 * q1 + q2 * q2 + q3 * q3); // íîðìèðóåì åãî ôóíêöèÿ äîëæíà íåÿâíî ïîäòÿíóòüñÿ èç ëèáû ìàæâèêà
  56. q1 *= invNorma;
  57. q2 *= invNorma;
  58. q3 *= invNorma;
  59. Ptmp_p = (int16_t) (q2 * angle);
  60. Ptmp_r = (int16_t) (q1 * angle);
  61. Ptmp_y = (int16_t) (q3 * angle);
  62. } else {
  63. Ptmp_p = 0;
  64. Ptmp_r = 0;
  65. Ptmp_y = 0;
  66. }
  67. */
  68. sum_r = Ptmp_r + Itmp_r + Dtmp_r;
  69. sum_p = Ptmp_p - Itmp_p + Dtmp_p;
  70. sum_y = Ptmp_y + Itmp_y + Dtmp_y;
  71. pow[0] = force + sum_r - sum_p - sum_y;
  72. pow[1] = force + sum_r + sum_p + sum_y;
  73. pow[2] = force - sum_r - sum_p + sum_y;
  74. pow[3] = force - sum_r + sum_p - sum_y;
  75. for (i = 0; i < 4; i++) {
  76. if (pow[i] < PID_POWER_MIN)
  77. pow[i] = PID_POWER_MIN;
  78. else if (pow[i] > PID_POWER_MAX)
  79. pow[i] = PID_POWER_MAX;
  80. }
  81. }