sim_details.hpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. #ifndef SOPHUS_SIM_DETAILS_HPP
  2. #define SOPHUS_SIM_DETAILS_HPP
  3. #include "types.hpp"
  4. namespace Sophus {
  5. namespace details {
  6. template <class Scalar, int N>
  7. Matrix<Scalar, N, N> calcW(Matrix<Scalar, N, N> const& Omega,
  8. Scalar const theta, Scalar const sigma) {
  9. using std::abs;
  10. using std::cos;
  11. using std::exp;
  12. using std::sin;
  13. static Matrix<Scalar, N, N> const I = Matrix<Scalar, N, N>::Identity();
  14. static Scalar const one(1);
  15. static Scalar const half(0.5);
  16. Matrix<Scalar, N, N> const Omega2 = Omega * Omega;
  17. Scalar const scale = exp(sigma);
  18. Scalar A, B, C;
  19. if (abs(sigma) < Constants<Scalar>::epsilon()) {
  20. C = one;
  21. if (abs(theta) < Constants<Scalar>::epsilon()) {
  22. A = half;
  23. B = Scalar(1. / 6.);
  24. } else {
  25. Scalar theta_sq = theta * theta;
  26. A = (one - cos(theta)) / theta_sq;
  27. B = (theta - sin(theta)) / (theta_sq * theta);
  28. }
  29. } else {
  30. C = (scale - one) / sigma;
  31. if (abs(theta) < Constants<Scalar>::epsilon()) {
  32. Scalar sigma_sq = sigma * sigma;
  33. A = ((sigma - one) * scale + one) / sigma_sq;
  34. B = (scale * half * sigma_sq + scale - one - sigma * scale) /
  35. (sigma_sq * sigma);
  36. } else {
  37. Scalar theta_sq = theta * theta;
  38. Scalar a = scale * sin(theta);
  39. Scalar b = scale * cos(theta);
  40. Scalar c = theta_sq + sigma * sigma;
  41. A = (a * sigma + (one - b) * theta) / (theta * c);
  42. B = (C - ((b - one) * sigma + a * theta) / (c)) * one / (theta_sq);
  43. }
  44. }
  45. return A * Omega + B * Omega2 + C * I;
  46. }
  47. template <class Scalar, int N>
  48. Matrix<Scalar, N, N> calcWInv(Matrix<Scalar, N, N> const& Omega,
  49. Scalar const theta, Scalar const sigma,
  50. Scalar const scale) {
  51. using std::abs;
  52. using std::cos;
  53. using std::sin;
  54. static Matrix<Scalar, N, N> const I = Matrix<Scalar, N, N>::Identity();
  55. static Scalar const half(0.5);
  56. static Scalar const one(1);
  57. static Scalar const two(2);
  58. Matrix<Scalar, N, N> const Omega2 = Omega * Omega;
  59. Scalar const scale_sq = scale * scale;
  60. Scalar const theta_sq = theta * theta;
  61. Scalar const sin_theta = sin(theta);
  62. Scalar const cos_theta = cos(theta);
  63. Scalar a, b, c;
  64. if (abs(sigma * sigma) < Constants<Scalar>::epsilon()) {
  65. c = one - half * sigma;
  66. a = -half;
  67. if (abs(theta_sq) < Constants<Scalar>::epsilon()) {
  68. b = Scalar(1. / 12.);
  69. } else {
  70. b = (theta * sin_theta + two * cos_theta - two) /
  71. (two * theta_sq * (cos_theta - one));
  72. }
  73. } else {
  74. Scalar const scale_cu = scale_sq * scale;
  75. c = sigma / (scale - one);
  76. if (abs(theta_sq) < Constants<Scalar>::epsilon()) {
  77. a = (-sigma * scale + scale - one) / ((scale - one) * (scale - one));
  78. b = (scale_sq * sigma - two * scale_sq + scale * sigma + two * scale) /
  79. (two * scale_cu - Scalar(6) * scale_sq + Scalar(6) * scale - two);
  80. } else {
  81. Scalar const s_sin_theta = scale * sin_theta;
  82. Scalar const s_cos_theta = scale * cos_theta;
  83. a = (theta * s_cos_theta - theta - sigma * s_sin_theta) /
  84. (theta * (scale_sq - two * s_cos_theta + one));
  85. b = -scale *
  86. (theta * s_sin_theta - theta * sin_theta + sigma * s_cos_theta -
  87. scale * sigma + sigma * cos_theta - sigma) /
  88. (theta_sq * (scale_cu - two * scale * s_cos_theta - scale_sq +
  89. two * s_cos_theta + scale - one));
  90. }
  91. }
  92. return a * Omega + b * Omega2 + c * I;
  93. }
  94. } // namespace details
  95. } // namespace Sophus
  96. #endif