22template <
int K,
class Derived>
23size_t ExtendedPose3<K, Derived>::RuntimeK(
const TangentVector& xi) {
24 if constexpr (K == Eigen::Dynamic) {
25 assert(xi.size() >= 3 && (xi.size() - 3) % 3 == 0);
26 return static_cast<size_t>((xi.size() - 3) / 3);
28 return static_cast<size_t>(K);
32template <
int K,
class Derived>
33void ExtendedPose3<K, Derived>::ZeroJacobian(ChartJacobian H, Eigen::Index d) {
35 if constexpr (dimension == Eigen::Dynamic) {
43template <
int K,
class Derived>
47template <
int K,
class Derived>
48template <
int FixedK,
typename,
typename... Vecs,
typename>
50 :
R_(R),
t_(Matrix3K::Zero()) {
52 for (Eigen::Index i = 0; i < static_cast<Eigen::Index>(FixedK); ++i) {
53 t_.col(i) = columns[i];
57template <
int K,
class Derived>
59 const Eigen::Index n = T.rows();
60 if constexpr (K == Eigen::Dynamic) {
61 if (T.cols() != n || n < 3) {
62 throw std::invalid_argument(
"ExtendedPose3: invalid matrix shape.");
66 if (n != matrixDim || T.cols() != matrixDim) {
67 throw std::invalid_argument(
"ExtendedPose3: invalid matrix shape.");
71 R_ =
Rot3(T.template block<3, 3>(0, 0));
72 t_ = T.block(0, 3, 3, n - 3);
75template <
int K,
class Derived>
78 if constexpr (dimension == Eigen::Dynamic) {
79 H->setZero(3,
static_cast<Eigen::Index
>(
dim()));
83 H->template block<3, 3>(0, 0) = I_3x3;
88template <
int K,
class Derived>
90 if (i >=
k())
throw std::out_of_range(
"ExtendedPose3: x(i) out of range.");
92 if constexpr (dimension == Eigen::Dynamic) {
93 H->setZero(3,
static_cast<Eigen::Index
>(
dim()));
97 const Eigen::Index idx = 3 + 3 *
static_cast<Eigen::Index
>(i);
98 H->template block<3, 3>(0, idx) =
R_.matrix();
100 return t_.col(
static_cast<Eigen::Index
>(i));
103template <
int K,
class Derived>
104const typename ExtendedPose3<K, Derived>::Matrix3K&
109template <
int K,
class Derived>
110typename ExtendedPose3<K, Derived>::Matrix3K&
115template <
int K,
class Derived>
117 std::cout << (s.empty() ? s : s +
" ") << *
this << std::endl;
120template <
int K,
class Derived>
126template <
int K,
class Derived>
129 const Rot3 Rt =
R_.inverse();
134template <
int K,
class Derived>
136 const This& other)
const {
138 if constexpr (K == Eigen::Dynamic) {
139 if (
k() != otherBase.
k()) {
140 throw std::invalid_argument(
141 "ExtendedPose3: compose requires matching k.");
144 Matrix3K
x =
t_ +
R_.matrix() * otherBase.
t_;
151template <
int K,
class Derived>
153 const TangentVector& xi, ChartJacobian Hxi) {
155 const Vector3 w = xi.template head<3>();
161#ifdef GTSAM_USE_QUATERNIONS
168 const Eigen::Index
k =
static_cast<Eigen::Index
>(RuntimeK(xi));
179 if constexpr (K == Eigen::Dynamic)
x.resize(3,
k);
182 ZeroJacobian(Hxi, 3 + 3 *
k);
184 const Matrix3 Jr = jacobian.right();
186 Hxi->template block<3, 3>(0, 0) = Jr;
187 const Matrix3 Rt = R.transpose();
188 for (Eigen::Index i = 0; i <
k; ++i) {
190 const Eigen::Index idx = 3 + 3 * i;
191 const Vector3 rho = xi.template segment<3>(idx);
192 x.col(i) = jacobian.applyLeft(rho, &H_xi_w);
193 Hxi->template block<3, 3>(idx, 0) = Rt * H_xi_w;
194 Hxi->template block<3, 3>(idx, idx) = Jr;
199 const Matrix3 Jl = local.leftJacobian();
200 for (Eigen::Index i = 0; i <
k; ++i) {
201 x.col(i).noalias() = Jl * xi.template segment<3>(3 + 3 * i);
208template <
int K,
class Derived>
209typename ExtendedPose3<K, Derived>::TangentVector
216 if constexpr (K == Eigen::Dynamic)
217 xi.resize(
static_cast<Eigen::Index
>(poseBase.
dim()));
218 xi.template head<3>() = w;
219 const Eigen::Index
k =
static_cast<Eigen::Index
>(poseBase.
k());
221 const Matrix3 JlInv = local.InvJacobian().left();
222 for (Eigen::Index i = 0; i <
k; ++i) {
223 const Eigen::Index idx = 3 + 3 * i;
224 xi.template segment<3>(idx).noalias() = JlInv * poseBase.
t_.col(i);
232template <
int K,
class Derived>
233typename ExtendedPose3<K, Derived>::Jacobian
235 const Matrix3 R =
R_.matrix();
238 if constexpr (dimension == Eigen::Dynamic) {
239 adj.setZero(
dim(),
dim());
244 adj.template block<3, 3>(0, 0) = R;
245 const Eigen::Index
k =
static_cast<Eigen::Index
>(this->k());
246 for (Eigen::Index i = 0; i <
k; ++i) {
247 const Eigen::Index idx = 3 + 3 * i;
249 adj.template block<3, 3>(idx, idx) = R;
254template <
int K,
class Derived>
255typename ExtendedPose3<K, Derived>::Jacobian
259 const Eigen::Index
k =
static_cast<Eigen::Index
>(RuntimeK(xi));
262 if constexpr (dimension == Eigen::Dynamic) {
263 adj.setZero(3 + 3 *
k, 3 + 3 *
k);
268 adj.template block<3, 3>(0, 0) = w_hat;
269 for (Eigen::Index i = 0; i <
k; ++i) {
270 const Eigen::Index idx = 3 + 3 * i;
271 adj.template block<3, 3>(idx, 0) =
273 adj.template block<3, 3>(idx, idx) = w_hat;
278template <
int K,
class Derived>
279typename ExtendedPose3<K, Derived>::Jacobian
286template <
int K,
class Derived>
287typename ExtendedPose3<K, Derived>::Jacobian
289 const Vector3 w = xi.template head<3>();
294 const Eigen::Index
k =
static_cast<Eigen::Index
>(RuntimeK(xi));
296 const Matrix3 JrInv = inverseJacobian.right();
297 const Matrix3 JlInv = inverseJacobian.left();
300 if constexpr (dimension == Eigen::Dynamic) {
301 H.setZero(3 + 3 *
k, 3 + 3 *
k);
306 H.template block<3, 3>(0, 0) = JrInv;
308 for (Eigen::Index i = 0; i <
k; ++i) {
310 const Eigen::Index idx = 3 + 3 * i;
311 jacobian.applyLeft(xi.template segment<3>(idx), H_xi_w);
312 H.template block<3, 3>(idx, 0) = -JlInv * H_xi_w * JrInv;
313 H.template block<3, 3>(idx, idx) = JrInv;
318template <
int K,
class Derived>
319typename ExtendedPose3<K, Derived>::Jacobian
324template <
int K,
class Derived>
325typename ExtendedPose3<K, Derived>::This
331template <
int K,
class Derived>
332typename ExtendedPose3<K, Derived>::TangentVector
338template <
int K,
class Derived>
342 if constexpr (matrixDim == Eigen::Dynamic) {
343 const Eigen::Index
k =
static_cast<Eigen::Index
>(this->
k());
344 const Eigen::Index n = 3 +
k;
345 M = MatrixRep::Identity(n, n);
347 M = MatrixRep::Identity();
349 M.template block<3, 3>(0, 0) =
R_.matrix();
350 M.block(0, 3, 3,
static_cast<Eigen::Index
>(this->
k())) =
t_;
354template <
int K,
class Derived>
356 const TangentVector& xi) {
357 const Eigen::Index
k =
static_cast<Eigen::Index
>(RuntimeK(xi));
359 if constexpr (matrixDim == Eigen::Dynamic) {
360 X.setZero(3 +
k, 3 +
k);
364 X.template block<3, 3>(0, 0) =
366 for (Eigen::Index i = 0; i <
k; ++i) {
367 const Eigen::Index idx = 3 + 3 * i;
368 X.template block<3, 1>(0, 3 + i) = xi.template segment<3>(idx);
373template <
int K,
class Derived>
374typename ExtendedPose3<K, Derived>::TangentVector
376 if (X.rows() != X.cols() || X.rows() < 3) {
377 throw std::invalid_argument(
"ExtendedPose3::Vee: invalid matrix shape.");
380 const Eigen::Index
k = [&]() -> Eigen::Index {
381 if constexpr (K == Eigen::Dynamic) {
384 if (X.rows() != matrixDim) {
385 throw std::invalid_argument(
386 "ExtendedPose3::Vee: invalid matrix shape.");
388 return static_cast<Eigen::Index
>(K);
393 if constexpr (dimension == Eigen::Dynamic) {
394 xi.resize(3 + 3 *
k);
402 for (Eigen::Index i = 0; i <
k; ++i) {
403 const Eigen::Index idx = 3 + 3 * i;
404 xi.template segment<3>(idx) = X.template block<3, 1>(0, 3 + i);
Global functions in a separate testing namespace.
Definition chartTesting.h:28
Vector3 Point3
As of GTSAM 4, in order to make GTSAM more lean, it is now possible to just typedef Point3 to Vector3...
Definition Point3.h:38
Matrix3 skewSymmetric(double wx, double wy, double wz)
skew symmetric matrix returns this: 0 -wz wy wz 0 -wx -wy wx 0
Definition Matrix.h:365
@ Logmap
Use the SE_2(3) NavState Logmap for every backend.
Definition PreintegrationParams.h:32
bool equal_with_abs_tol(const Eigen::DenseBase< MATRIX > &A, const Eigen::DenseBase< MATRIX > &B, double tol=1e-9)
equals with a tolerance
Definition Matrix.h:81
MatrixRep matrix() const
Homogeneous matrix representation.
Definition ExtendedPose3-inl.h:340
static Jacobian adjointMap(const TangentVector &xi)
Lie algebra adjoint map.
Definition ExtendedPose3-inl.h:256
size_t dim() const
Definition ExtendedPose3.h:166
static LieAlgebra Hat(const TangentVector &xi)
Hat operator from tangent to Lie algebra.
Definition ExtendedPose3-inl.h:355
static This Expmap(const TangentVector &xi, ChartJacobian Hxi={})
Exponential map from tangent to group.
Definition ExtendedPose3-inl.h:152
Point3 x(size_t i, ComponentJacobian H={}) const
i-th R^3 component, returned by value.
Definition ExtendedPose3-inl.h:89
void print(const std::string &s="") const
Print this state.
Definition ExtendedPose3-inl.h:116
static TangentVector Logmap(const This &pose, ChartJacobian Hpose={})
Logarithm map from group to tangent.
Definition ExtendedPose3-inl.h:210
static Jacobian ExpmapDerivative(const TangentVector &xi)
Jacobian of Expmap.
Definition ExtendedPose3-inl.h:280
This operator*(const This &other) const
Group composition.
Definition ExtendedPose3-inl.h:135
Eigen::Matrix< double, matrixDim, matrixDim > MatrixRep
Homogeneous matrix representation in the group.
Definition ExtendedPose3.h:71
Rot3 R_
Rotation component.
Definition ExtendedPose3.h:80
size_t k() const
Definition ExtendedPose3.h:163
static TangentVector Vee(const LieAlgebra &X)
Vee operator from Lie algebra to tangent.
Definition ExtendedPose3-inl.h:375
This inverse() const
Group inverse.
Definition ExtendedPose3-inl.h:127
bool equals(const ExtendedPose3 &other, double tol=1e-9) const
Equality check with tolerance.
Definition ExtendedPose3-inl.h:121
Matrix3K t_
K translation-like columns in world frame.
Definition ExtendedPose3.h:81
ExtendedPose3()
Construct a fixed-size identity element.
Definition ExtendedPose3.h:99
Eigen::Matrix< double, matrixDim, matrixDim > LieAlgebra
Lie algebra matrix type used by Hat/Vee.
Definition ExtendedPose3.h:73
static Jacobian LogmapDerivative(const TangentVector &xi)
Jacobian of Logmap evaluated from tangent coordinates.
Definition ExtendedPose3-inl.h:288
const Rot3 & rotation(ComponentJacobian H={}) const
Rotation component.
Definition ExtendedPose3-inl.h:76
const Matrix3K & xMatrix() const
Access all x_i blocks.
Definition ExtendedPose3-inl.h:105
Jacobian AdjointMap() const
Adjoint map.
Definition ExtendedPose3-inl.h:234
static This Retract(const TangentVector &xi, ChartJacobian Hxi={})
Retract at identity.
Definition ExtendedPose3-inl.h:326
static TangentVector Local(const This &pose, ChartJacobian Hpose={})
Local coordinates at identity.
Definition ExtendedPose3-inl.h:333
Kernel: M(ω) = a I + b Ω + c Ω² with radial derivatives db,dc for Fréchet.
Definition Kernel.h:38
Rot3 is a 3D rotation represented as a rotation matrix if the preprocessor symbol GTSAM_USE_QUATERNIO...
Definition Rot3.h:65
static Rot3 Expmap(const Vector3 &v, OptionalJacobian< 3, 3 > H={})
Exponential map - create a rotation from canonical coordinates using Rodrigues' formula.
Definition Rot3M.cpp:173
static Vector3 Logmap(const Rot3 &R, OptionalJacobian< 3, 3 > H={})
Log map - returns the canonical coordinates of this rotation.
Definition Rot3M.cpp:183
Matrix3 matrix() const
return 3*3 rotation matrix
Definition Rot3M.cpp:261
Matrix3 expmap() const
Rodrigues formula.
Definition SO3.h:175
Functor that implements Exponential map and its derivatives Math extends Ethan theme of elegant I + a...
Definition SO3.h:184