so3_math.h 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #ifndef SO3_MATH_H
  2. #define SO3_MATH_H
  3. #include <math.h>
  4. #include <Eigen/Core>
  5. #define SKEW_SYM_MATRX(v) 0.0,-v[2],v[1],v[2],0.0,-v[0],-v[1],v[0],0.0
  6. template<typename T>
  7. Eigen::Matrix<T, 3, 3> skew_sym_mat(const Eigen::Matrix<T, 3, 1> &v)
  8. {
  9. Eigen::Matrix<T, 3, 3> skew_sym_mat;
  10. skew_sym_mat<<0.0,-v[2],v[1],v[2],0.0,-v[0],-v[1],v[0],0.0;
  11. return skew_sym_mat;
  12. }
  13. template<typename T>
  14. Eigen::Matrix<T, 3, 3> Exp(const Eigen::Matrix<T, 3, 1> &&ang)
  15. {
  16. T ang_norm = ang.norm();
  17. Eigen::Matrix<T, 3, 3> Eye3 = Eigen::Matrix<T, 3, 3>::Identity();
  18. if (ang_norm > 0.0000001)
  19. {
  20. Eigen::Matrix<T, 3, 1> r_axis = ang / ang_norm;
  21. Eigen::Matrix<T, 3, 3> K;
  22. K << SKEW_SYM_MATRX(r_axis);
  23. /// Roderigous Tranformation
  24. return Eye3 + std::sin(ang_norm) * K + (1.0 - std::cos(ang_norm)) * K * K;
  25. }
  26. else
  27. {
  28. return Eye3;
  29. }
  30. }
  31. template<typename T, typename Ts>
  32. Eigen::Matrix<T, 3, 3> Exp(const Eigen::Matrix<T, 3, 1> &ang_vel, const Ts &dt)
  33. {
  34. T ang_vel_norm = ang_vel.norm();
  35. Eigen::Matrix<T, 3, 3> Eye3 = Eigen::Matrix<T, 3, 3>::Identity();
  36. if (ang_vel_norm > 0.0000001)
  37. {
  38. Eigen::Matrix<T, 3, 1> r_axis = ang_vel / ang_vel_norm;
  39. Eigen::Matrix<T, 3, 3> K;
  40. K << SKEW_SYM_MATRX(r_axis);
  41. T r_ang = ang_vel_norm * dt;
  42. /// Roderigous Tranformation
  43. return Eye3 + std::sin(r_ang) * K + (1.0 - std::cos(r_ang)) * K * K;
  44. }
  45. else
  46. {
  47. return Eye3;
  48. }
  49. }
  50. template<typename T>
  51. Eigen::Matrix<T, 3, 3> Exp(const T &v1, const T &v2, const T &v3)
  52. {
  53. T &&norm = sqrt(v1 * v1 + v2 * v2 + v3 * v3);
  54. Eigen::Matrix<T, 3, 3> Eye3 = Eigen::Matrix<T, 3, 3>::Identity();
  55. if (norm > 0.00001)
  56. {
  57. T r_ang[3] = {v1 / norm, v2 / norm, v3 / norm};
  58. Eigen::Matrix<T, 3, 3> K;
  59. K << SKEW_SYM_MATRX(r_ang);
  60. /// Roderigous Tranformation
  61. return Eye3 + std::sin(norm) * K + (1.0 - std::cos(norm)) * K * K;
  62. }
  63. else
  64. {
  65. return Eye3;
  66. }
  67. }
  68. /* Logrithm of a Rotation Matrix */
  69. template<typename T>
  70. Eigen::Matrix<T,3,1> Log(const Eigen::Matrix<T, 3, 3> &R)
  71. {
  72. T theta = (R.trace() > 3.0 - 1e-6) ? 0.0 : std::acos(0.5 * (R.trace() - 1));
  73. Eigen::Matrix<T,3,1> K(R(2,1) - R(1,2), R(0,2) - R(2,0), R(1,0) - R(0,1));
  74. return (std::abs(theta) < 0.001) ? (0.5 * K) : (0.5 * theta / std::sin(theta) * K);
  75. }
  76. template<typename T>
  77. Eigen::Matrix<T, 3, 1> RotMtoEuler(const Eigen::Matrix<T, 3, 3> &rot)
  78. {
  79. T sy = sqrt(rot(0,0)*rot(0,0) + rot(1,0)*rot(1,0));
  80. bool singular = sy < 1e-6;
  81. T x, y, z;
  82. if(!singular)
  83. {
  84. x = atan2(rot(2, 1), rot(2, 2));
  85. y = atan2(-rot(2, 0), sy);
  86. z = atan2(rot(1, 0), rot(0, 0));
  87. }
  88. else
  89. {
  90. x = atan2(-rot(1, 2), rot(1, 1));
  91. y = atan2(-rot(2, 0), sy);
  92. z = 0;
  93. }
  94. Eigen::Matrix<T, 3, 1> ang(x, y, z);
  95. return ang;
  96. }
  97. #endif