28 #ifndef TOON_INCLUDE_SE3_H 29 #define TOON_INCLUDE_SE3_H 47 template <
typename Precision = DefaultPrecision>
51 inline SE3() : my_translation(Zeros) {}
53 template <
int S,
typename P,
typename A>
55 template <
int S,
typename P,
typename A>
58 template <
class IP,
int S,
typename P,
typename A>
74 template <
int S,
typename P,
typename A>
84 inline SE3 inverse()
const {
86 return SE3(rinv, -(rinv*my_translation));
105 inline SE3& left_multiply_by(
const SE3& left) {
117 result[(i+1)%3][(i+2)%3] = -1;
118 result[(i+2)%3][(i+1)%3] = 1;
123 template<
typename Base>
131 result[(i+1)%3] = - pos[(i+2)%3];
132 result[(i+2)%3] = pos[(i+1)%3];
141 template<
int S,
typename P2,
typename Accessor>
146 template<
int S,
typename P2,
typename Accessor>
150 template <
int R,
int C,
typename P2,
typename Accessor>
154 template <
int R,
int C,
typename P2,
typename Accessor>
165 template<
typename Precision>
166 template<
int S,
typename P2,
typename Accessor>
170 result.template slice<3,3>() =
get_rotation() * vect.template slice<3,3>();
171 result.template slice<0,3>() =
get_rotation() * vect.template slice<0,3>();
172 result.template slice<0,3>() +=
get_translation() ^ result.template slice<3,3>();
179 template<
typename Precision>
180 template<
int S,
typename P2,
typename Accessor>
184 result.template slice<3,3>() =
get_rotation() * vect.template slice<3,3>();
185 result.template slice<0,3>() =
get_rotation() * vect.template slice<0,3>();
186 result.template slice<3,3>() +=
get_translation() ^ result.template slice<0,3>();
190 template<
typename Precision>
191 template<
int R,
int C,
typename P2,
typename Accessor>
197 for(
int i=0; i<6; i++){
198 result.T()[i] =
adjoint(M.T()[i]);
200 for(
int i=0; i<6; i++){
201 result[i] =
adjoint(result[i]);
206 template<
typename Precision>
207 template<
int R,
int C,
typename P2,
typename Accessor>
213 for(
int i=0; i<6; i++){
216 for(
int i=0; i<6; i++){
224 template <
typename Precision>
225 inline std::ostream& operator <<(std::ostream& os, const SE3<Precision>& rhs){
226 std::streamsize fw = os.width();
227 for(
int i=0; i<3; i++){
229 os << rhs.get_rotation().get_matrix()[i];
231 os << rhs.get_translation()[i] <<
'\n';
239 template <
typename Precision>
241 for(
int i=0; i<3; i++){
254 template<
int S,
typename PV,
typename A,
typename P>
258 template<
int S,
typename PV,
typename A,
typename P>
265 template <
int S0,
typename P0,
typename A0>
268 res.template slice<0,3>()=lhs.get_rotation() * rhs.template slice<0,3>();
269 res.template slice<0,3>()+=TooN::operator*(lhs.get_translation(),rhs[3]);
272 int size()
const {
return 4; }
277 template<
int S,
typename PV,
typename A,
typename P>
inline 284 template <
typename PV,
typename A,
typename P>
inline 295 template<
int S,
typename PV,
typename A,
typename P>
299 template<
int S,
typename PV,
typename A,
typename P>
306 template <
int S0,
typename P0,
typename A0>
309 res.template slice<0,3>()=lhs.template slice<0,3>() * rhs.
get_rotation();
313 int size()
const {
return 4; }
318 template<
int S,
typename PV,
typename A,
typename P>
inline 329 template <
int R,
int C,
typename PM,
typename A,
typename P>
333 template<
int R,
int Cols,
typename PM,
typename A,
typename P>
334 struct Operator<Internal::SE3MMult<R, Cols, PM, A, P> > {
340 template <
int R0,
int C0,
typename P0,
typename A0>
343 for(
int i=0; i<rhs.num_cols(); ++i)
344 res.T()[i] = lhs * rhs.T()[i];
346 int num_cols()
const {
return rhs.num_cols(); }
347 int num_rows()
const {
return 4; }
352 template <
int R,
int Cols,
typename PM,
typename A,
typename P>
inline 363 template <
int Rows,
int C,
typename PM,
typename A,
typename P>
367 template<
int Rows,
int C,
typename PM,
typename A,
typename P>
368 struct Operator<Internal::MSE3Mult<Rows, C, PM, A, P> > {
374 template <
int R0,
int C0,
typename P0,
typename A0>
377 for(
int i=0; i<lhs.num_rows(); ++i)
378 res[i] = lhs[i] * rhs;
380 int num_cols()
const {
return 4; }
381 int num_rows()
const {
return lhs.num_rows(); }
386 template <
int Rows,
int C,
typename PM,
typename A,
typename P>
inline 391 template <
typename Precision>
392 template <
int S,
typename P,
typename VA>
395 static const Precision one_6th = 1.0/6.0;
396 static const Precision one_20th = 1.0/20.0;
402 const Precision theta_sq = w*w;
403 const Precision theta =
sqrt(theta_sq);
407 if (theta_sq < 1e-8) {
408 A = 1.0 - one_6th * theta_sq;
413 if (theta_sq < 1e-6) {
414 C = one_6th*(1.0 - one_20th * theta_sq);
415 A = 1.0 - theta_sq * C;
416 B = 0.5 - 0.25 * one_6th * theta_sq;
418 const Precision inv_theta = 1.0/theta;
419 A = sin(theta) * inv_theta;
420 B = (1 - cos(theta)) * (inv_theta * inv_theta);
421 C = (1 - A) * (inv_theta * inv_theta);
423 result.
get_translation() = mu.template slice<0,3>() + TooN::operator*(B, cross) + TooN::operator*(C, (w ^ cross));
425 rodrigues_so3_exp(w, A, B, result.
get_rotation().my_matrix);
429 template <
typename Precision>
433 const Precision theta =
sqrt(rot*rot);
435 Precision shtot = 0.5;
436 if(theta > 0.00001) {
437 shtot = sin(theta/2)/theta;
445 rottrans -= TooN::operator*(rot, ((se3.
get_translation() * rot) * (1-2*shtot) / (rot*rot)));
450 rottrans /= (2 * shtot);
453 result.template slice<0,3>()=rottrans;
454 result.template slice<3,3>()=rot;
458 template <
typename Precision>
463 #if 0 // should be moved to another header file 465 template <
class A>
inline 468 template <
class A>
inline 469 Vector<3> transform_inverse_depth(
const SE3& pose,
const FixedVector<3,A>& uvq)
472 const Vector<3> DqT = R.template slice<0,0,3,2>() * uvq.template slice<0,2>() + R.T()[2] + uvq[2] * pose.
get_translation();
473 const double inv_z = 1.0/ DqT[2];
474 return makeVector(DqT[0]*inv_z, DqT[1]*inv_z, uvq[2]*inv_z);
477 template <
class A1,
class A2>
inline 478 Vector<3> transform(
const SE3& pose,
const FixedVector<3,A1>& x, FixedMatrix<3,3,A2>& J_x)
485 template <
class A1,
class A2>
inline 486 Vector<3> inverse_depth_point_jacobian(
const SE3& pose,
const double q,
const FixedVector<3,A1>& DqT,
const double inv_z, FixedMatrix<3,3,A2>& J_uvq)
490 const double u1 = DqT[0] * inv_z;
491 J_uvq[0][0] = inv_z * (R[0][0] - u1*R[2][0]);
492 J_uvq[0][1] = inv_z * (R[0][1] - u1*R[2][1]);
493 J_uvq[0][2] = inv_z * (T[0] - u1 * T[2]);
495 const double v1 = DqT[1] * inv_z;
496 J_uvq[1][0] = inv_z * (R[1][0] - v1*R[2][0]);
497 J_uvq[1][1] = inv_z * (R[1][1] - v1*R[2][1]);
498 J_uvq[1][2] = inv_z * (T[1] - v1 * T[2]);
500 const double q1 = q * inv_z;
501 J_uvq[2][0] = inv_z * (-q1 * R[2][0]);
502 J_uvq[2][1] = inv_z * (-q1 * R[2][1]);
503 J_uvq[2][2] = inv_z * (1.0 - q1 * T[2]);
505 return makeVector(u1, v1, q1);
509 template <
class A1,
class A2>
inline 510 Vector<3> transform_inverse_depth(
const SE3& pose,
const FixedVector<3,A1>& uvq, FixedMatrix<3,3,A2>& J_uvq)
514 const double q = uvq[2];
515 const Vector<3> DqT = R.template slice<0,0,3,2>() * uvq.template slice<0,2>() + R.T()[2] + q * T;
516 const double inv_z = 1.0 / DqT[2];
518 return inverse_depth_point_jacobian(pose, q, DqT, inv_z, J_uvq);
521 template <
class A1,
class A2,
class A3>
inline 522 Vector<3> transform(
const SE3& pose,
const FixedVector<3,A1>& x, FixedMatrix<3,3,A2>& J_x, FixedMatrix<3,6,A3>& J_pose)
525 Identity(J_pose.template slice<0,0,3,3>());
527 J_pose[0][3] = J_pose[1][4] = J_pose[2][5] = 0;
528 J_pose[1][3] = -(J_pose[0][4] = cx[2]);
529 J_pose[0][5] = -(J_pose[2][3] = cx[1]);
530 J_pose[2][4] = -(J_pose[1][5] = cx[0]);
534 template <
class A1,
class A2,
class A3>
inline 535 Vector<3> transform_inverse_depth(
const SE3& pose,
const FixedVector<3,A1>& uvq, FixedMatrix<3,3,A2>& J_uvq, FixedMatrix<3,6,A3>& J_pose)
539 const double q = uvq[2];
540 const Vector<3> DqT = R.template slice<0,0,3,2>() * uvq.template slice<0,2>() + R.T()[2] + q * T;
541 const double inv_z = 1.0 / DqT[2];
543 const Vector<3> uvq1 = inverse_depth_point_jacobian(pose, q, DqT, inv_z, J_uvq);
544 const double q1 = uvq1[2];
546 J_pose[0][1] = J_pose[1][0] = J_pose[2][0] = J_pose[2][1] = 0;
547 J_pose[0][0] = J_pose[1][1] = q1;
548 J_pose[0][2] = -uvq1[0] * q1;
549 J_pose[1][2] = -uvq1[1] * q1;
550 J_pose[2][2] = -q1 * q1;
552 J_pose[0][3] = -uvq1[1]*uvq1[0];
553 J_pose[0][4] = 1 + uvq1[0]*uvq1[0];
554 J_pose[0][5] = -uvq1[1];
556 J_pose[1][3] = -1 - uvq1[1]*uvq1[1];
557 J_pose[1][4] = uvq1[0] * uvq1[1];
558 J_pose[1][5] = uvq1[0];
560 J_pose[2][3] = -uvq1[1]*q1;
561 J_pose[2][4] = uvq1[0]*q1;
567 template <
class A1,
class A2,
class A3>
inline 568 Vector<2> project_transformed_point(
const SE3& pose,
const FixedVector<3,A1>& in_frame, FixedMatrix<2,3,A2>& J_x, FixedMatrix<2,6,A3>& J_pose)
570 const double z_inv = 1.0/in_frame[2];
571 const double x_z_inv = in_frame[0]*z_inv;
572 const double y_z_inv = in_frame[1]*z_inv;
573 const double cross = x_z_inv * y_z_inv;
574 J_pose[0][0] = J_pose[1][1] = z_inv;
575 J_pose[0][1] = J_pose[1][0] = 0;
576 J_pose[0][2] = -x_z_inv * z_inv;
577 J_pose[1][2] = -y_z_inv * z_inv;
578 J_pose[0][3] = -cross;
579 J_pose[0][4] = 1 + x_z_inv*x_z_inv;
580 J_pose[0][5] = -y_z_inv;
581 J_pose[1][3] = -1 - y_z_inv*y_z_inv;
582 J_pose[1][4] = cross;
583 J_pose[1][5] = x_z_inv;
586 J_x[0][0] = z_inv*(R[0][0] - x_z_inv * R[2][0]);
587 J_x[0][1] = z_inv*(R[0][1] - x_z_inv * R[2][1]);
588 J_x[0][2] = z_inv*(R[0][2] - x_z_inv * R[2][2]);
589 J_x[1][0] = z_inv*(R[1][0] - y_z_inv * R[2][0]);
590 J_x[1][1] = z_inv*(R[1][1] - y_z_inv * R[2][1]);
591 J_x[1][2] = z_inv*(R[1][2] - y_z_inv * R[2][2]);
593 return makeVector(x_z_inv, y_z_inv);
597 template <
class A1>
inline 598 Vector<2> transform_and_project(
const SE3& pose,
const FixedVector<3,A1>& x)
600 return project(transform(pose,x));
603 template <
class A1>
inline 604 Vector<2> transform_and_project_inverse_depth(
const SE3& pose,
const FixedVector<3,A1>& uvq)
608 const Vector<3> DqT = R.template slice<0,0,3,2>() * uvq.template slice<0,2>() + R.T()[2] + uvq[2] * T;
612 template <
class A1,
class A2,
class A3>
inline 613 Vector<2> transform_and_project(
const SE3& pose,
const FixedVector<3,A1>& x, FixedMatrix<2,3,A2>& J_x, FixedMatrix<2,6,A3>& J_pose)
615 return project_transformed_point(pose, transform(pose,x), J_x, J_pose);
618 template <
class A1,
class A2,
class A3>
inline 619 Vector<2> transform_and_project_inverse_depth(
const SE3& pose,
const FixedVector<3,A1>& uvq, FixedMatrix<2,3,A2>& J_uvq, FixedMatrix<2,6,A3>& J_pose)
623 const double q = uvq[2];
624 const Vector<3> DqT = R.template slice<0,0,3,2>() * uvq.template slice<0,2>() + R.T()[2] + q * T;
625 const Vector<2> uv = project_transformed_point(pose, DqT, J_uvq, J_pose);
626 J_uvq.T()[2] = J_pose.template slice<0,0,2,3>() * pose.
get_translation();
627 J_pose.template slice<0,0,2,3>() *= q;
Represent a three-dimensional Euclidean transformation (a rotation and a translation).
Definition: se3.h:48
Vector<(Size==Dynamic?Dynamic:Size-1)+0, Precision > project(const Vector< Size, Precision, Base > &v)
For a vector v of length i, return .
Definition: helpers.h:182
Vector< 3, typename Internal::MultiplyType< P, PV >::type > operator*(const SE3< P > &lhs, const Vector< 3, PV, A > &rhs)
Right-multiply by a Vector.
Definition: se3.h:285
static SO3 exp(const Vector< S, VP, A > &vect)
Exponentiate a vector in the Lie algebra to generate a new SO3.
Pretty generic SFINAE introspection generator.
Definition: vec_test.cc:21
static Vector< 4, Precision > generator_field(int i, const Vector< 4, Precision, Base > &pos)
Returns the i-th generator times pos.
Definition: se3.h:124
std::istream & operator>>(std::istream &is, SE3< Precision > &rhs)
Reads an SE3 from a stream.
Definition: se3.h:240
SE3 & operator*=(const SE3< P > &rhs)
Right-multiply by another SE3 (concatenate the two transformations)
Definition: se3.h:92
Vector< 4, typename Internal::MultiplyType< P, PV >::type > operator*(const Vector< S, PV, A > &lhs, const SE3< P > &rhs)
Left-multiply by a Vector.
Definition: se3.h:319
A matrix.
Definition: matrix.hh:105
Vector< 4, typename Internal::MultiplyType< P, PV >::type > operator*(const SE3< P > &lhs, const Vector< S, PV, A > &rhs)
Right-multiply by a Vector.
Definition: se3.h:278
Vector< 6, Precision > ln() const
Definition: se3.h:82
const SO3< Precision > & get_rotation() const
Definition: se3.h:64
Matrix< 4, Cols, typename Internal::MultiplyType< P, PM >::type > operator*(const SE3< P > &lhs, const Matrix< R, Cols, PM, A > &rhs)
Right-multiply by a Matrix.
Definition: se3.h:353
Definition: operators.hh:119
Vector< 6, Precision > trinvadjoint(const Vector< S, P2, Accessor > &vect) const
Transfer covectors between frames (using the transpose of the inverse of the adjoint) so that trinvad...
Definition: se3.h:181
Vector< 6, Precision > adjoint(const Vector< S, P2, Accessor > &vect) const
Transfer a matrix in the Lie Algebra from one co-ordinate frame to another.
Definition: se3.h:167
Class to represent a three-dimensional rotation matrix.
Definition: so3.h:37
const Vector< 3, Precision > & get_translation() const
Definition: se3.h:69
SE3< typename Internal::MultiplyType< Precision, P >::type > operator*(const SE3< P > &rhs) const
Right-multiply by another SE3 (concatenate the two transformations)
Definition: se3.h:101
SE3()
Default constructor. Initialises the the rotation to zero (the identity) and the translation to zero...
Definition: se3.h:51
Matrix< R, C, P > sqrt(const Matrix< R, C, P, B > &m)
computes a matrix square root of a matrix m by the product form of the Denman and Beavers iteration a...
Definition: helpers.h:350
Definition: size_mismatch.hh:103
Vector< 3, Precision > & get_translation()
Returns the translation part of the transformation as a Vector.
Definition: se3.h:67
static SE3 exp(const Vector< S, P, A > &vect)
Exponentiate a Vector in the Lie Algebra to generate a new SE3.
SO3< Precision > & get_rotation()
Returns the rotation part of the transformation as a SO3.
Definition: se3.h:62
Matrix< Rows, 4, typename Internal::MultiplyType< PM, P >::type > operator*(const Matrix< Rows, C, PM, A > &lhs, const SE3< P > &rhs)
Left-multiply by a Matrix.
Definition: se3.h:387