euler.c 1018 B

12345678910111213141516171819202122232425262728293031323334
  1. #include "euler.h"
  2. #include <math.h>
  3. #include "helpler_funtions.h"
  4. #include "quaternion.h"
  5. #include "dcm.h"
  6. inline void Euler_ByDcm(const float dcm[3][3], euler_angle_t *euler)
  7. {
  8. const float eps = 1e-4f;
  9. /* 由于欧拉角描述姿态存在奇异点, 需要单独对奇异情况下人为定义角值 */
  10. /* 如果 y 轴非竖直朝上或下 */
  11. if (fabsf(dcm[2][1]) < 1.0f - eps)
  12. {
  13. euler->pitch = atanf(dcm[2][1] / sqrtf(1.0f - dcm[2][1] * dcm[2][1]));
  14. euler->yaw = atan2f(-dcm[0][1], dcm[1][1]);
  15. euler->roll = atan2f(-dcm[2][0], dcm[2][2]);
  16. }
  17. /* 如果 Y 轴竖直朝上或下 */
  18. else
  19. {
  20. euler->pitch = sign(dcm[2][1]) * 0.5f * M_PI;
  21. euler->roll = 0.0f;
  22. /* 此时人为定义 y 轴在水平面的投影反向为航向角 */
  23. euler->yaw = atan2f(dcm[0][2], -dcm[1][2]);
  24. }
  25. }
  26. void Euler_ByQuaternion(const float Q[4], euler_angle_t *euler)
  27. {
  28. float dcm[3][3];
  29. DCM_ByQuaternion(Q, dcm);
  30. Euler_ByDcm(dcm, euler);
  31. }