#ifndef _COMMON_H_ #define _COMMON_H_ #include #include #include #include #include #include #include #include #include "space_lib/space_lib.h" namespace hlzn_slam { namespace common { typedef std::chrono::time_point Time; template T NormalizeAngleDifference(T difference) { const T kPi = T(M_PI); while (difference > kPi) difference -= 2. * kPi; while (difference < -kPi) difference += 2. * kPi; return difference; } struct PointCloud { std::vector data; Time time; }; template class Rigid2 { public: using Vector = Eigen::Matrix; using Rotation2D = Eigen::Rotation2D; Rigid2() : translation_(Vector::Zero()), rotation_(Rotation2D::Identity()) {} Rigid2(const Vector& translation, const Rotation2D& rotation) : translation_(translation) { rotation_ = Rotation2D(NormalizeAngleDifference(rotation.angle())); } Rigid2(const Vector& translation, const double rotation) : translation_(translation) { rotation_ = Rotation2D(NormalizeAngleDifference(rotation)); } static Rigid2 Rotation(const double rotation) { return Rigid2(Vector::Zero(), rotation); } static Rigid2 Rotation(const Rotation2D& rotation) { return Rigid2(Vector::Zero(), rotation); } static Rigid2 Translation(const Vector& vector) { return Rigid2(vector, Rotation2D::Identity()); } static Rigid2 Identity() { return Rigid2(); } template Rigid2 cast() const { return Rigid2(translation_.template cast(), rotation_.template cast()); } const Vector& translation() const { return translation_; } Rotation2D rotation() const { return rotation_; } Rigid2 inverse() const { const Rotation2D rotation = rotation_.inverse(); const Vector translation = -(rotation * translation_); return Rigid2(translation, rotation); } FloatType normalized_angle() { rotation_ = Rotation(NormalizeAngleDifference(rotation().angle())).rotation(); return NormalizeAngleDifference(rotation().angle()); } private: Vector translation_; Rotation2D rotation_; }; template Rigid2 operator*(const Rigid2& lhs, const Rigid2& rhs) { return Rigid2( lhs.rotation() * rhs.translation() + lhs.translation(), lhs.rotation() * rhs.rotation()); } template typename Rigid2::Vector operator*( const Rigid2& rigid, const typename Rigid2::Vector& point) { return rigid.rotation() * point + rigid.translation(); } using Rigid2d = Rigid2; using Rigid2f = Rigid2; struct TimeRigid2f { Rigid2f pose; Time stamp; float cost; }; template class Rigid3 { public: using Vector = Eigen::Matrix; using Quaternion = Eigen::Quaternion; using AngleAxis = Eigen::AngleAxis; Rigid3() : translation_(Vector::Zero()), rotation_(Quaternion::Identity()) {} Rigid3(const Vector& translation, const Quaternion& rotation) : translation_(translation), rotation_(rotation) {} Rigid3(const Vector& translation, const AngleAxis& rotation) : translation_(translation), rotation_(rotation) {} static Rigid3 Rotation(const AngleAxis& angle_axis) { return Rigid3(Vector::Zero(), Quaternion(angle_axis)); } static Rigid3 Rotation(const Quaternion& rotation) { return Rigid3(Vector::Zero(), rotation); } static Rigid3 Translation(const Vector& vector) { return Rigid3(vector, Quaternion::Identity()); } static Rigid3 FromArrays(const std::array& rotation, const std::array& translation) { return Rigid3(Eigen::Map(translation.data()), Eigen::Quaternion(rotation[0], rotation[1], rotation[2], rotation[3])); } static Rigid3 Identity() { return Rigid3(); } template Rigid3 cast() const { return Rigid3(translation_.template cast(), rotation_.template cast()); } const Vector& translation() const { return translation_; } const Quaternion& rotation() const { return rotation_; } Rigid3 inverse() const { const Quaternion rotation = rotation_.conjugate(); const Vector translation = -(rotation * translation_); return Rigid3(translation, rotation); } bool IsValid() const { return !std::isnan(translation_.x()) && !std::isnan(translation_.y()) && !std::isnan(translation_.z()) && std::abs(FloatType(1) - rotation_.norm()) < FloatType(1e-3); } private: Vector translation_; Quaternion rotation_; }; template Rigid3 operator*(const Rigid3& lhs, const Rigid3& rhs) { return Rigid3( lhs.rotation() * rhs.translation() + lhs.translation(), (lhs.rotation() * rhs.rotation()).normalized()); } template typename Rigid3::Vector operator*( const Rigid3& rigid, const typename Rigid3::Vector& point) { return rigid.rotation() * point + rigid.translation(); } using Rigid3d = Rigid3; using Rigid3f = Rigid3; struct laserScan { float angle_increment; float angle_max; float angle_min; float range_max; float range_min; std::vector ranges; }; } } #endif