00001
00010
00011
00012
00013
00014 #ifndef ECL_GEOMETRY_POSE2D_EIGEN2_HPP_
00015 #define ECL_GEOMETRY_POSE2D_EIGEN2_HPP_
00016
00017
00018
00019
00020
00021 #include <ecl/config/macros.hpp>
00022 #include <ecl/formatters.hpp>
00023 #include <ecl/linear_algebra.hpp>
00024 #include <ecl/math/constants.hpp>
00025 #include <ecl/exceptions/standard_exception.hpp>
00026 #include <ecl/mpl/enable_if.hpp>
00027 #include <ecl/type_traits/traits.hpp>
00028 #include <ecl/type_traits/fundamental_types.hpp>
00029 #include "angle.hpp"
00030
00031
00032
00033
00034
00035 namespace ecl {
00036
00037
00038
00039
00043 enum Pose2DStorageType {
00044 RotationAngleStorage,
00045 RotationMatrixStorage,
00046 };
00047
00048
00049
00050
00051
00052 template <typename Float, enum Pose2DStorageType Storage, typename Enable> class Pose2D;
00053
00054
00055
00056
00060 template <typename Float, enum Pose2DStorageType Storage, typename Enable>
00061 class ecl_traits< Pose2D<Float, Storage, Enable> > {};
00062
00066 template <typename Float, typename Enable>
00067 class ecl_traits< Pose2D<Float, RotationMatrixStorage, Enable> > {
00068 public:
00069 typedef Float Scalar;
00070 typedef ecl::linear_algebra::Matrix<Float,2,2> RotationType;
00071 };
00072
00076 template <typename Float, typename Enable>
00077 class ecl_traits< Pose2D<Float, RotationAngleStorage, Enable> > {
00078 public:
00079 typedef Float Scalar;
00080 typedef Angle<Float> RotationType;
00081 };
00082
00083 namespace geometry {
00084
00085
00086
00087
00091 template <typename Float, enum Pose2DStorageType Storage> class Pose2DMath {};
00099 template <typename Float>
00100 class ECL_LOCAL Pose2DMath<Float,RotationMatrixStorage> {
00101 public:
00102 typedef ecl::linear_algebra::Matrix<Float,2,2> RotationMatrixType;
00104 static RotationMatrixType Identity() { return RotationMatrixType::Identity(); }
00105 static RotationMatrixType Rotation(const RotationMatrixType &rotation) { return rotation; }
00106 static RotationMatrixType Rotation(const Angle<Float>& angle) { return angle.rotationMatrix(); }
00107 static Angle<Float> Heading(const RotationMatrixType &rotation) { return Angle<Float>(rotation); }
00108 static RotationMatrixType Product(const RotationMatrixType &rot1, const RotationMatrixType &rot2) { return rot1*rot2; }
00109 static RotationMatrixType Product(const RotationMatrixType &rotation, const Angle<Float> &angle) { return rotation*angle.rotationMatrix(); }
00110 static RotationMatrixType Inverse(const RotationMatrixType &rotation) { return rotation.transpose(); }
00111 };
00112
00120 template <typename Float>
00121 class ECL_LOCAL Pose2DMath<Float,RotationAngleStorage> {
00122 public:
00123 typedef ecl::linear_algebra::Matrix<Float,2,2> RotationMatrixType;
00124 static Angle<Float> Identity() { return Angle<Float>(0.0); }
00125 static Angle<Float> Rotation(const Angle<Float>& radians) { return Angle<Float>(radians); }
00126 static Angle<Float> Rotation(const RotationMatrixType &rotation) { return Pose2DMath<Float,RotationMatrixStorage>::Heading(rotation); }
00127 static Angle<Float> Heading(const Angle<Float> &angle) { return angle; }
00128 static Angle<Float> Product(const Angle<Float> &angle1, const Angle<Float> &angle2) { return angle1+angle2; }
00129 static Angle<Float> Product(const Angle<Float> &angle, RotationMatrixType &rotation) { return angle + Angle<Float>(rotation); }
00130 static Angle<Float> Inverse(const Angle<Float> &angle) { return Angle<Float>(-1*angle); }
00131 };
00132
00133 }
00134
00135
00136
00137
00143 template <class Float, enum Pose2DStorageType Storage = RotationMatrixStorage, typename Enable = void>
00144 class ECL_LOCAL Pose2D {
00145 typedef Float Scalar;
00146 private:
00147 Pose2D() {};
00148 };
00149
00166 template<typename Float, enum Pose2DStorageType Storage>
00167 class ECL_PUBLIC Pose2D<Float, Storage, typename enable_if<is_float<Float> >::type> {
00168 public:
00169
00170
00171
00172 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00173
00174
00175
00176
00177 typedef Float Scalar;
00178 typedef geometry::Pose2DMath<Float,Storage> RotationMath;
00179 typedef geometry::Pose2DMath<Float,RotationMatrixStorage> RotationMatrixMath;
00180 typedef geometry::Pose2DMath<Float,RotationAngleStorage> RotationAngleMath;
00181 typedef typename ecl_traits< Pose2D<Float,Storage,typename enable_if<is_float<Float> >::type> >::RotationType RotationType;
00182 typedef ecl::linear_algebra::Matrix<Float,2,2> RotationMatrix;
00183 typedef ecl::linear_algebra::Matrix<Float,2,1> Translation;
00185
00186
00187
00196 Pose2D() : rot( RotationMath::Identity()), trans(Translation::Zero()) {}
00197
00204 Pose2D(const Float &x, const Float &y, const Angle<Float> &angle) :
00205 rot( RotationMath::Rotation(angle)),
00206 trans( (Translation() << x,y).finished() )
00207 {}
00208
00220 template<typename Rot, typename Trans>
00221 Pose2D(const ecl::linear_algebra::MatrixBase<Rot>& R, const ecl::linear_algebra::MatrixBase<Trans>& T) :
00222 rot( RotationMath::Rotation(R) ),
00223 trans(T)
00224 {}
00235 template<typename Trans>
00236 Pose2D(const Angle<Float>& angle, const ecl::linear_algebra::MatrixBase<Trans>& T) :
00237 rot( RotationMath::Rotation(angle) ),
00238 trans(T)
00239 {}
00247 template <enum Pose2DStorageType Storage_>
00248 Pose2D(const Pose2D<Float,Storage_>& pose) :
00249 rot(RotationMath::Rotation(pose.rotation())),
00250 trans(pose.translation())
00251 {}
00252
00253 virtual ~Pose2D() {}
00254
00255
00256
00257
00263 template <enum Pose2DStorageType Storage_>
00264 Pose2D<Float,Storage>& operator=(const Pose2D<Float,Storage_>& pose) {
00265 trans = pose.translation();
00266 rot = RotationMath::Rotation(pose.rotation());
00267 return *this;
00268 }
00269
00270
00271
00272
00281 void rotation(const Angle<Float> &heading) {
00282 rot = RotationMath::Rotation(heading);
00283 }
00292 void rotation(const RotationMatrix &rotation_matrix) {
00293 rot = RotationMath::Rotation(rotation_matrix);
00294 }
00303 void translation(const Float &x, const Float &y) {
00304 this->trans << x, y;
00305 }
00315 template <typename Trans>
00316 void translation(const ecl::linear_algebra::MatrixBase<Trans>& T) {
00317 this->trans = T;
00318 }
00319
00323 void setIdentity() {
00324 rot = RotationMath::Identity();
00325 trans << 0.0, 0.0;
00326 }
00327
00333 static Pose2D<Float,Storage> Identity() {
00334 return Pose2D<Float,Storage>();
00335 }
00336
00337
00338
00339
00340
00341 void setPose(const Float& x, const Float& y, const Angle<Float>& heading) { trans << x,y; rot = RotationMath::Rotation(heading); }
00342 void x(const Float& value) { trans[0] = value; }
00343 void y(const Float& value) { trans[1] = value; }
00344 void heading(const Angle<Float>& value) { rot = RotationMath::Rotation(value); }
00345
00355 template <typename Rot>
00356 void rotationMatrix(const ecl::linear_algebra::MatrixBase<Rot>& rotation_matrix) {
00357 rot = RotationMath::Rotation(rotation_matrix);
00358 }
00359
00360
00361
00362
00363 RotationType& rotation() { return rot; }
00364 Translation& translation() { return trans; }
00365 const RotationType& rotation() const { return rot; }
00366 const Translation& translation() const { return trans; }
00368
00369
00370
00371 Float x() const { return trans[0]; }
00372 Float y() const { return trans[1]; }
00373 Angle<Float> heading() const { return RotationMath::Heading(rot); }
00374 RotationMatrix rotationMatrix() const { return RotationMatrixMath::Rotation(rot); }
00375
00376
00377
00378
00386 Pose2D<Float,Storage> inverse() const {
00387 Pose2D<Float,Storage> inverse;
00388 inverse.rotation(RotationMath::Inverse(rot));
00389 inverse.translation(-1*(RotationMatrixMath::Rotation(inverse.rot)*trans));
00390 return inverse;
00391 }
00392
00398 template <enum Pose2DStorageType Storage_>
00399 Pose2D<Float,Storage> operator*(const Pose2D<Float,Storage_> &pose) const {
00400 return Pose2D<Float,Storage>(RotationMath::Product(rot,pose.rot),trans + rotationMatrix()*pose.trans);
00401 }
00407 Pose2D<Float>& operator*=(const Pose2D<Float> &pose) {
00408
00409 *this = (*this)*pose;
00410 return (*this);
00411 }
00426 template <enum Pose2DStorageType Storage_>
00427 Pose2D<Float,Storage> relative(const Pose2D<Float,Storage_> &pose) const {
00428 return pose.inverse()*(*this);
00429 }
00430
00431
00432
00433
00434 template <typename OutputStream, typename Float_, enum Pose2DStorageType Storage_>
00435 friend OutputStream& operator<<(OutputStream &ostream , const Pose2D<Float_, Storage_> &pose);
00436
00437 private:
00438 RotationType rot;
00439 Translation trans;
00440 };
00441
00442
00443
00444
00454 template <typename OutputStream, typename Float_, enum Pose2DStorageType Storage_>
00455 OutputStream& operator<<(OutputStream &ostream , const Pose2D<Float_,Storage_> &pose) {
00456 ecl::Format<Float_> format;
00457 format.width(6);
00458 format.precision(3);
00459 ostream << "[ ";
00460 ostream << format(pose.x()) << " ";
00461 ostream << format(pose.y()) << " ";
00462 ostream << format(pose.heading());
00463 ostream << " ]";
00464 ostream.flush();
00465 return ostream;
00466 }
00467
00468 }
00469
00470
00471 #endif