2010-10-14 12:54:38 +08:00
|
|
|
|
/* ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
* GTSAM Copyright 2010, Georgia Tech Research Corporation,
|
|
|
|
|
|
* Atlanta, Georgia 30332-0415
|
|
|
|
|
|
* All Rights Reserved
|
|
|
|
|
|
* Authors: Frank Dellaert, et al. (see THANKS for the full author list)
|
|
|
|
|
|
|
|
|
|
|
|
* See LICENSE for the license information
|
|
|
|
|
|
|
|
|
|
|
|
* -------------------------------------------------------------------------- */
|
|
|
|
|
|
|
2009-08-22 06:23:24 +08:00
|
|
|
|
/**
|
|
|
|
|
|
*@file Pose3.h
|
|
|
|
|
|
*@brief 3D Pose
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
// \callgraph
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
2013-05-01 01:17:51 +08:00
|
|
|
|
#include <gtsam/config.h>
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef GTSAM_POSE3_EXPMAP
|
|
|
|
|
|
#define POSE3_DEFAULT_COORDINATES_MODE Pose3::FIRST_ORDER
|
|
|
|
|
|
#else
|
2013-04-30 05:22:33 +08:00
|
|
|
|
#define POSE3_DEFAULT_COORDINATES_MODE Pose3::EXPMAP
|
2012-01-09 04:43:17 +08:00
|
|
|
|
#endif
|
|
|
|
|
|
|
2012-01-28 03:50:46 +08:00
|
|
|
|
#include <gtsam/base/DerivedValue.h>
|
2010-08-20 01:23:19 +08:00
|
|
|
|
#include <gtsam/geometry/Point3.h>
|
|
|
|
|
|
#include <gtsam/geometry/Rot3.h>
|
2009-08-22 06:23:24 +08:00
|
|
|
|
|
|
|
|
|
|
namespace gtsam {
|
|
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
class Pose2;
|
|
|
|
|
|
// forward declare
|
2012-01-10 13:05:36 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* A 3D pose (R,t) : (Rot3,Point3)
|
|
|
|
|
|
* @addtogroup geometry
|
|
|
|
|
|
* \nosubgrouping
|
|
|
|
|
|
*/
|
|
|
|
|
|
class GTSAM_EXPORT Pose3: public DerivedValue<Pose3> {
|
|
|
|
|
|
public:
|
|
|
|
|
|
static const size_t dimension = 6;
|
2011-11-06 07:01:50 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/** Pose Concept requirements */
|
|
|
|
|
|
typedef Rot3 Rotation;
|
|
|
|
|
|
typedef Point3 Translation;
|
2011-11-06 07:01:50 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
private:
|
|
|
|
|
|
Rot3 R_;
|
|
|
|
|
|
Point3 t_;
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
public:
|
2011-11-06 07:01:50 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// @name Standard Constructors
|
|
|
|
|
|
/// @{
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/** Default constructor is origin */
|
|
|
|
|
|
Pose3() {
|
|
|
|
|
|
}
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/** Copy constructor */
|
|
|
|
|
|
Pose3(const Pose3& pose) :
|
|
|
|
|
|
R_(pose.R_), t_(pose.t_) {
|
|
|
|
|
|
}
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/** Construct from R,t */
|
|
|
|
|
|
Pose3(const Rot3& R, const Point3& t) :
|
|
|
|
|
|
R_(R), t_(t) {
|
|
|
|
|
|
}
|
2012-01-10 13:05:36 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/** Construct from Pose2 */
|
|
|
|
|
|
explicit Pose3(const Pose2& pose2);
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/** Constructor from 4*4 matrix */
|
|
|
|
|
|
Pose3(const Matrix &T) :
|
|
|
|
|
|
R_(T(0, 0), T(0, 1), T(0, 2), T(1, 0), T(1, 1), T(1, 2), T(2, 0), T(2, 1),
|
|
|
|
|
|
T(2, 2)), t_(T(0, 3), T(1, 3), T(2, 3)) {
|
|
|
|
|
|
}
|
2011-11-18 03:12:05 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// @}
|
|
|
|
|
|
/// @name Testable
|
|
|
|
|
|
/// @{
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// print with optional string
|
|
|
|
|
|
void print(const std::string& s = "") const;
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// assert equality up to a tolerance
|
|
|
|
|
|
bool equals(const Pose3& pose, double tol = 1e-9) const;
|
2011-11-18 03:12:05 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// @}
|
|
|
|
|
|
/// @name Group
|
|
|
|
|
|
/// @{
|
2011-11-18 03:12:05 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// identity for group operation
|
|
|
|
|
|
static Pose3 identity() {
|
|
|
|
|
|
return Pose3();
|
|
|
|
|
|
}
|
2011-11-18 03:12:05 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// inverse transformation with derivatives
|
|
|
|
|
|
Pose3 inverse(boost::optional<Matrix&> H1 = boost::none) const;
|
2011-11-18 03:12:05 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
///compose this transformation onto another (first *this and then p2)
|
|
|
|
|
|
Pose3 compose(const Pose3& p2, boost::optional<Matrix&> H1 = boost::none,
|
|
|
|
|
|
boost::optional<Matrix&> H2 = boost::none) const;
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// compose syntactic sugar
|
|
|
|
|
|
Pose3 operator*(const Pose3& T) const {
|
|
|
|
|
|
return Pose3(R_ * T.R_, t_ + R_ * T.t_);
|
|
|
|
|
|
}
|
2012-01-24 12:13:16 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* Return relative pose between p1 and p2, in p1 coordinate frame
|
|
|
|
|
|
* as well as optionally the derivatives
|
|
|
|
|
|
*/
|
|
|
|
|
|
Pose3 between(const Pose3& p2, boost::optional<Matrix&> H1 = boost::none,
|
|
|
|
|
|
boost::optional<Matrix&> H2 = boost::none) const;
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// @}
|
|
|
|
|
|
/// @name Manifold
|
|
|
|
|
|
/// @{
|
2012-01-09 04:43:17 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/** Enum to indicate which method should be used in Pose3::retract() and
|
|
|
|
|
|
* Pose3::localCoordinates()
|
|
|
|
|
|
*/
|
|
|
|
|
|
enum CoordinatesMode {
|
|
|
|
|
|
EXPMAP, ///< The correct exponential map, computationally expensive.
|
|
|
|
|
|
FIRST_ORDER ///< A fast first-order approximation to the exponential map.
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/// Dimensionality of tangent space = 6 DOF - used to autodetect sizes
|
|
|
|
|
|
static size_t Dim() {
|
|
|
|
|
|
return dimension;
|
|
|
|
|
|
}
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// Dimensionality of the tangent space = 6 DOF
|
|
|
|
|
|
size_t dim() const {
|
|
|
|
|
|
return dimension;
|
|
|
|
|
|
}
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// Retraction from R^6 \f$ [R_x,R_y,R_z,T_x,T_y,T_z] \f$ from R^ with fast first-order approximation to the exponential map
|
|
|
|
|
|
Pose3 retractFirstOrder(const Vector& d) const;
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// Retraction from R^6 \f$ [R_x,R_y,R_z,T_x,T_y,T_z] \f$ to Pose3 manifold neighborhood around current pose
|
|
|
|
|
|
Pose3 retract(const Vector& d, Pose3::CoordinatesMode mode =
|
|
|
|
|
|
POSE3_DEFAULT_COORDINATES_MODE) const;
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/// Local 6D coordinates \f$ [R_x,R_y,R_z,T_x,T_y,T_z] \f$ of Pose3 manifold neighborhood around current pose
|
|
|
|
|
|
Vector6 localCoordinates(const Pose3& T2, Pose3::CoordinatesMode mode =POSE3_DEFAULT_COORDINATES_MODE) const;
|
2011-11-18 03:12:05 +08:00
|
|
|
|
|
|
|
|
|
|
/// @}
|
|
|
|
|
|
/// @name Lie Group
|
|
|
|
|
|
/// @{
|
|
|
|
|
|
|
2013-02-27 04:50:17 +08:00
|
|
|
|
/// Exponential map at identity - create a rotation from canonical coordinates \f$ [R_x,R_y,R_z,T_x,T_y,T_z] \f$
|
2011-11-18 03:12:05 +08:00
|
|
|
|
static Pose3 Expmap(const Vector& xi);
|
|
|
|
|
|
|
2013-02-27 04:50:17 +08:00
|
|
|
|
/// Log map at identity - return the canonical coordinates \f$ [R_x,R_y,R_z,T_x,T_y,T_z] \f$ of this rotation
|
2012-05-10 01:19:01 +08:00
|
|
|
|
static Vector6 Logmap(const Pose3& p);
|
2011-11-18 03:12:05 +08:00
|
|
|
|
|
2011-11-09 09:40:20 +08:00
|
|
|
|
/**
|
2013-04-21 13:50:07 +08:00
|
|
|
|
* Calculate Adjoint map, transforming a twist in the this pose's (i.e, body) frame to the world spatial frame
|
2013-02-27 04:50:17 +08:00
|
|
|
|
* Ad_pose is 6*6 matrix that when applied to twist xi \f$ [R_x,R_y,R_z,T_x,T_y,T_z] \f$, returns Ad_pose(xi)
|
2011-11-09 09:40:20 +08:00
|
|
|
|
*/
|
2013-04-21 13:50:07 +08:00
|
|
|
|
Matrix6 AdjointMap() const; /// FIXME Not tested - marked as incorrect
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Apply this pose's AdjointMap Ad_g to a twist \f$ \xi_b \f$, i.e. a body-fixed velocity, transforming it to the spatial frame
|
|
|
|
|
|
* \f$ \xi^s = g*\xi^b*g^{-1} = Ad_g * \xi^b \f$
|
|
|
|
|
|
*/
|
|
|
|
|
|
Vector Adjoint(const Vector& xi_b) const {return AdjointMap()*xi_b; } /// FIXME Not tested - marked as incorrect
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Compute the [ad(w,v)] operator as defined in [Kobilarov09siggraph], pg 11
|
|
|
|
|
|
* [ad(w,v)] = [w^, zero3; v^, w^]
|
|
|
|
|
|
* Note that this is the matrix representation of the adjoint operator for se3 Lie algebra,
|
|
|
|
|
|
* aka the Lie bracket, and also the derivative of Adjoint map for the Lie group SE3.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Let \f$ \hat{\xi}_i \f$ be the se3 Lie algebra, and \f$ \hat{\xi}_i^\vee = \xi_i = [\omega_i,v_i] \in \mathbb{R}^6\f$ be its
|
|
|
|
|
|
* vector representation.
|
|
|
|
|
|
* We have the following relationship:
|
|
|
|
|
|
* \f$ [\hat{\xi}_1,\hat{\xi}_2]^\vee = ad_{\xi_1}(\xi_2) = [ad_{(\omega_1,v_1)}]*\xi_2 \f$
|
|
|
|
|
|
*
|
|
|
|
|
|
* We use this to compute the discrete version of the inverse right-trivialized tangent map,
|
|
|
|
|
|
* and its inverse transpose in the discrete Euler Poincare' (DEP) operator.
|
|
|
|
|
|
*
|
|
|
|
|
|
*/
|
2013-04-30 05:22:33 +08:00
|
|
|
|
static Matrix6 adjointMap(const Vector& xi);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Action of the adjointMap on a Lie-algebra vector y, with optional derivatives
|
|
|
|
|
|
*/
|
|
|
|
|
|
static Vector adjoint(const Vector& xi, const Vector& y, boost::optional<Matrix&> H = boost::none);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* The dual version of adjoint action, acting on the dual space of the Lie-algebra vector space.
|
|
|
|
|
|
*/
|
|
|
|
|
|
static Vector adjointTranspose(const Vector& xi, const Vector& y, boost::optional<Matrix&> H = boost::none);
|
2013-04-21 13:50:07 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Compute the inverse right-trivialized tangent (derivative) map of the exponential map,
|
2013-04-30 05:22:33 +08:00
|
|
|
|
* as detailed in [Kobilarov09siggraph] eq. (15)
|
2013-04-21 13:50:07 +08:00
|
|
|
|
* The full formula is documented in [Celledoni99cmame]
|
|
|
|
|
|
* Elena Celledoni and Brynjulf Owren. Lie group methods for rigid body dynamics and
|
2013-04-30 02:06:33 +08:00
|
|
|
|
* time integration on manifolds. Comput. meth. in Appl. Mech. and Eng., 19(3,4):421<EFBFBD> 438, 2003.
|
2013-04-30 05:22:33 +08:00
|
|
|
|
* and in [Hairer06book] in formula (4.5), pg. 84, Lemma 4.2
|
|
|
|
|
|
* Ernst Hairer, et al., Geometric Numerical Integration,
|
|
|
|
|
|
* Structure-Preserving Algorithms for Ordinary Differential Equations, 2nd edition, Springer-Verlag, 2006.
|
2013-04-21 13:50:07 +08:00
|
|
|
|
*/
|
2013-04-30 05:22:33 +08:00
|
|
|
|
static Matrix6 dExpInv_exp(const Vector& xi);
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* wedge for Pose3:
|
|
|
|
|
|
* @param xi 6-dim twist (omega,v) where
|
|
|
|
|
|
* omega = (wx,wy,wz) 3D angular velocity
|
|
|
|
|
|
* v (vx,vy,vz) = 3D velocity
|
|
|
|
|
|
* @return xihat, 4*4 element of Lie algebra that can be exponentiated
|
|
|
|
|
|
*/
|
|
|
|
|
|
static Matrix wedge(double wx, double wy, double wz, double vx, double vy, double vz) {
|
2013-12-17 05:33:12 +08:00
|
|
|
|
return (Matrix(4,4) <<
|
2011-11-09 09:40:20 +08:00
|
|
|
|
0.,-wz, wy, vx,
|
|
|
|
|
|
wz, 0.,-wx, vy,
|
|
|
|
|
|
-wy, wx, 0., vz,
|
|
|
|
|
|
0., 0., 0., 0.);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2012-10-02 22:40:07 +08:00
|
|
|
|
/// @}
|
|
|
|
|
|
/// @name Group Action on Point3
|
|
|
|
|
|
/// @{
|
2012-01-24 13:03:56 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief takes point in Pose coordinates and transforms it to world coordinates
|
|
|
|
|
|
* @param p point in Pose coordinates
|
|
|
|
|
|
* @param Dpose optional 3*6 Jacobian wrpt this pose
|
|
|
|
|
|
* @param Dpoint optional 3*3 Jacobian wrpt point
|
|
|
|
|
|
* @return point in world coordinates
|
|
|
|
|
|
*/
|
2012-01-24 13:03:56 +08:00
|
|
|
|
Point3 transform_from(const Point3& p,
|
2013-10-12 13:13:36 +08:00
|
|
|
|
boost::optional<Matrix&> Dpose=boost::none, boost::optional<Matrix&> Dpoint=boost::none) const;
|
2012-01-24 13:03:56 +08:00
|
|
|
|
|
|
|
|
|
|
/** syntactic sugar for transform_from */
|
|
|
|
|
|
inline Point3 operator*(const Point3& p) const { return transform_from(p); }
|
|
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* @brief takes point in world coordinates and transforms it to Pose coordinates
|
|
|
|
|
|
* @param p point in world coordinates
|
|
|
|
|
|
* @param Dpose optional 3*6 Jacobian wrpt this pose
|
|
|
|
|
|
* @param Dpoint optional 3*3 Jacobian wrpt point
|
|
|
|
|
|
* @return point in Pose coordinates
|
|
|
|
|
|
*/
|
2012-01-24 13:03:56 +08:00
|
|
|
|
Point3 transform_to(const Point3& p,
|
2013-10-12 13:13:36 +08:00
|
|
|
|
boost::optional<Matrix&> Dpose=boost::none, boost::optional<Matrix&> Dpoint=boost::none) const;
|
2012-01-24 13:03:56 +08:00
|
|
|
|
|
2012-01-24 10:27:44 +08:00
|
|
|
|
/// @}
|
2012-10-02 22:40:07 +08:00
|
|
|
|
/// @name Standard Interface
|
|
|
|
|
|
/// @{
|
2012-01-24 10:27:44 +08:00
|
|
|
|
|
2012-01-24 12:13:16 +08:00
|
|
|
|
/// get rotation
|
2012-01-24 10:27:44 +08:00
|
|
|
|
const Rot3& rotation() const { return R_; }
|
2012-01-24 12:13:16 +08:00
|
|
|
|
|
|
|
|
|
|
/// get translation
|
2012-01-24 10:27:44 +08:00
|
|
|
|
const Point3& translation() const { return t_; }
|
|
|
|
|
|
|
2012-01-24 12:13:16 +08:00
|
|
|
|
/// get x
|
2012-01-24 10:27:44 +08:00
|
|
|
|
double x() const { return t_.x(); }
|
2012-01-24 12:13:16 +08:00
|
|
|
|
|
|
|
|
|
|
/// get y
|
2012-01-24 10:27:44 +08:00
|
|
|
|
double y() const { return t_.y(); }
|
2012-01-24 12:13:16 +08:00
|
|
|
|
|
|
|
|
|
|
/// get z
|
2012-01-24 10:27:44 +08:00
|
|
|
|
double z() const { return t_.z(); }
|
|
|
|
|
|
|
|
|
|
|
|
/** convert to 4*4 matrix */
|
2012-05-10 01:19:01 +08:00
|
|
|
|
Matrix4 matrix() const;
|
2012-01-24 10:27:44 +08:00
|
|
|
|
|
2012-01-24 13:03:56 +08:00
|
|
|
|
/** receives a pose in world coordinates and transforms it to local coordinates */
|
2012-01-24 10:27:44 +08:00
|
|
|
|
Pose3 transform_to(const Pose3& pose) const;
|
|
|
|
|
|
|
2011-11-09 09:40:20 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* Calculate range to a landmark
|
|
|
|
|
|
* @param point 3D location of landmark
|
|
|
|
|
|
* @return range (double)
|
|
|
|
|
|
*/
|
|
|
|
|
|
double range(const Point3& point,
|
|
|
|
|
|
boost::optional<Matrix&> H1=boost::none,
|
|
|
|
|
|
boost::optional<Matrix&> H2=boost::none) const;
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* Calculate range to another pose
|
2012-03-23 11:39:04 +08:00
|
|
|
|
* @param pose Other SO(3) pose
|
2011-11-09 09:40:20 +08:00
|
|
|
|
* @return range (double)
|
|
|
|
|
|
*/
|
2012-03-23 11:39:04 +08:00
|
|
|
|
double range(const Pose3& pose,
|
2011-11-09 09:40:20 +08:00
|
|
|
|
boost::optional<Matrix&> H1=boost::none,
|
|
|
|
|
|
boost::optional<Matrix&> H2=boost::none) const;
|
|
|
|
|
|
|
2012-01-11 11:04:35 +08:00
|
|
|
|
/// @}
|
2012-10-02 22:40:07 +08:00
|
|
|
|
/// @name Advanced Interface
|
|
|
|
|
|
/// @{
|
2012-01-11 11:04:35 +08:00
|
|
|
|
|
2012-06-15 04:00:51 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* Return the start and end indices (inclusive) of the translation component of the
|
|
|
|
|
|
* exponential map parameterization
|
|
|
|
|
|
* @return a pair of [start, end] indices into the tangent space vector
|
|
|
|
|
|
*/
|
2012-10-02 22:40:07 +08:00
|
|
|
|
inline static std::pair<size_t, size_t> translationInterval() { return std::make_pair(3, 5); }
|
2012-06-15 04:00:51 +08:00
|
|
|
|
|
2012-10-02 22:40:07 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* Return the start and end indices (inclusive) of the rotation component of the
|
|
|
|
|
|
* exponential map parameterization
|
|
|
|
|
|
* @return a pair of [start, end] indices into the tangent space vector
|
|
|
|
|
|
*/
|
|
|
|
|
|
static std::pair<size_t, size_t> rotationInterval() { return std::make_pair(0, 2); }
|
2012-06-15 04:00:51 +08:00
|
|
|
|
|
2013-06-06 09:21:34 +08:00
|
|
|
|
/// Output stream operator
|
2013-06-21 00:05:23 +08:00
|
|
|
|
GTSAM_EXPORT friend std::ostream &operator<<(std::ostream &os, const Pose3& p);
|
2013-06-06 09:21:34 +08:00
|
|
|
|
|
2011-11-09 09:40:20 +08:00
|
|
|
|
private:
|
|
|
|
|
|
/** Serialization function */
|
|
|
|
|
|
friend class boost::serialization::access;
|
|
|
|
|
|
template<class Archive>
|
|
|
|
|
|
void serialize(Archive & ar, const unsigned int version) {
|
2012-10-02 22:40:07 +08:00
|
|
|
|
ar & boost::serialization::make_nvp("Pose3",
|
|
|
|
|
|
boost::serialization::base_object<Value>(*this));
|
2011-11-09 09:40:20 +08:00
|
|
|
|
ar & BOOST_SERIALIZATION_NVP(R_);
|
|
|
|
|
|
ar & BOOST_SERIALIZATION_NVP(t_);
|
|
|
|
|
|
}
|
2012-10-02 22:40:07 +08:00
|
|
|
|
/// @}
|
2012-01-24 13:03:56 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
};// Pose3 class
|
2011-11-09 09:40:20 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* wedge for Pose3:
|
|
|
|
|
|
* @param xi 6-dim twist (omega,v) where
|
|
|
|
|
|
* omega = 3D angular velocity
|
|
|
|
|
|
* v = 3D velocity
|
|
|
|
|
|
* @return xihat, 4*4 element of Lie algebra that can be exponentiated
|
|
|
|
|
|
*/
|
2013-10-12 13:13:36 +08:00
|
|
|
|
template<>
|
|
|
|
|
|
inline Matrix wedge<Pose3>(const Vector& xi) {
|
|
|
|
|
|
return Pose3::wedge(xi(0), xi(1), xi(2), xi(3), xi(4), xi(5));
|
|
|
|
|
|
}
|
2010-03-02 10:25:27 +08:00
|
|
|
|
|
2013-10-12 13:13:36 +08:00
|
|
|
|
/**
|
|
|
|
|
|
* Calculate pose between a vector of 3D point correspondences (p,q)
|
|
|
|
|
|
* where q = Pose3::transform_from(p) = t + R*p
|
|
|
|
|
|
*/
|
|
|
|
|
|
typedef std::pair<Point3, Point3> Point3Pair;
|
|
|
|
|
|
GTSAM_EXPORT boost::optional<Pose3> align(const std::vector<Point3Pair>& pairs);
|
2013-04-30 02:06:33 +08:00
|
|
|
|
|
2009-08-22 06:23:24 +08:00
|
|
|
|
} // namespace gtsam
|