NDEVR
API Documentation
se3mat.h
1#pragma once
2#include "DLLInfo.h"
3#include <Eigen/Geometry>
4
5namespace NDEVR {
6
8 class SE3mat
9 {
10 public:
13 {
14 R = Eigen::Matrix3<g_type>::Identity();
15 t.setZero();
16 }
17
21 SE3mat(const Eigen::Matrix3<g_type>& R_, const Eigen::Vector3<g_type>& t_)
22 : R(R_)
23 , t(t_)
24 {}
25
26
30 void Retract(const Eigen::Vector3<g_type> dr, const Eigen::Vector3<g_type>& dt)
31 {
32 t += R * dt;
33 R = R * ExpSO3(dr);
34 }
35
36
39 inline Eigen::Vector3<g_type> operator* (const Eigen::Vector3<g_type>& v) const {
40 return R * v + t;
41 }
42
44 inline SE3mat& operator*= (const SE3mat& T2) {
45 t += R * T2.t;
46 R *= T2.R;
47 return *this;
48 }
49
51 inline SE3mat inverse() const {
52 Eigen::Matrix3<g_type> Rt = R.transpose();
53 return SE3mat(Rt, -Rt * t);
54 }
55
56 protected:
57 Eigen::Matrix3<g_type> R;
58 Eigen::Vector3<g_type> t;
59
60 public:
64 static Eigen::Matrix3<g_type> ExpSO3(const Eigen::Vector3<g_type> r)
65 {
66 Eigen::Matrix3<g_type> W;
67 W << 0, -r[2], r[1],
68 r[2], 0, -r[0],
69 -r[1], r[0], 0;
70
71 const g_type theta = r.norm();
72
73 if (theta < g_type(1e-6))
74 return Eigen::Matrix3<g_type>::Identity() + W + g_type(0.5) * W * W;
75 else
76 return Eigen::Matrix3<g_type>::Identity() + W * sin(theta) / theta + W * W * (1 - cos(theta)) / (theta * theta);
77 }
78
82 static Eigen::Vector3<g_type> LogSO3(const Eigen::Matrix3<g_type> R)
83 {
84 const g_type tr = R(0, 0) + R(1, 1) + R(2, 2);
85 const g_type theta = acos((tr - static_cast<g_type>(1)) * static_cast<g_type>(0.5));
86 Eigen::Vector3<g_type> w;
87 w << R(2, 1) - R(1, 2), R(0, 2) - R(2, 0), R(1, 0) - R(0, 1);
88 if (theta < g_type(1e-6))
89 return g_type(0.5) * w;
90 else
91 {
92 const g_type sin_theta = sin(theta);
93 if (std::abs(sin_theta) < g_type(1e-10))
94 {
95 // theta near pi: use alternative formula
96 // Find the column of R+I with the largest diagonal for numerical stability
97 Eigen::Matrix3<g_type> RpI = R + Eigen::Matrix3<g_type>::Identity();
98 int max_col = 0;
99 if (RpI(1, 1) > RpI(0, 0)) max_col = 1;
100 if (RpI(2, 2) > RpI(max_col, max_col)) max_col = 2;
101 Eigen::Vector3<g_type> v = RpI.col(max_col).normalized();
102 return theta * v;
103 }
104 return theta * w / (g_type(2.0) * sin_theta);
105 }
106 }
107
108 };
109
110}
SE3mat(const Eigen::Matrix3< g_type > &R_, const Eigen::Vector3< g_type > &t_)
Constructs from a rotation matrix and translation vector.
Definition se3mat.h:21
SE3mat()
Default constructor.
Definition se3mat.h:12
static Eigen::Matrix3< g_type > ExpSO3(const Eigen::Vector3< g_type > r)
Computes the exponential map from so(3) to SO(3) (Rodrigues formula).
Definition se3mat.h:64
Eigen::Matrix3< g_type > R
The 3x3 rotation matrix.
Definition se3mat.h:57
Eigen::Vector3< g_type > t
The 3D translation vector.
Definition se3mat.h:58
Eigen::Vector3< g_type > operator*(const Eigen::Vector3< g_type > &v) const
Transforms a 3D point: R*v + t.
Definition se3mat.h:39
static Eigen::Vector3< g_type > LogSO3(const Eigen::Matrix3< g_type > R)
Computes the logarithmic map from SO(3) to so(3).
Definition se3mat.h:82
SE3mat & operator*=(const SE3mat &T2)
In-place composition with another SE3mat transform.
Definition se3mat.h:44
SE3mat inverse() const
Computes the inverse of this rigid transform.
Definition se3mat.h:51
void Retract(const Eigen::Vector3< g_type > dr, const Eigen::Vector3< g_type > &dt)
Applies a retraction update: t += R*dt, R *= ExpSO3(dr).
Definition se3mat.h:30
The primary namespace for the NDEVR SDK.
std::enable_if<!ObjectInfo< t_type >::Float, fltp08 >::type sin(const Angle< t_type > &angle)
Performs optimized sine operation on the given angle using pre-computed lookup table for optimal spee...
std::enable_if<!ObjectInfo< t_type >::Float, fltp08 >::type cos(const Angle< t_type > &angle)
Performs optimized cosine operation on the given angle using pre-computed lookup table for optimal sp...