56 #ifndef _GAMS_POSE_COORDINATE_H_ 57 #define _GAMS_POSE_COORDINATE_H_ 64 #include "madara/knowledge/containers/DoubleVector.h" 65 #include "madara/knowledge/containers/NativeDoubleVector.h" 70 #pragma GCC diagnostic push 71 #pragma GCC diagnostic ignored "-Wunused-parameter" 72 #include "Eigen/Geometry" 73 #pragma GCC diagnostic pop 76 #define INVAL_COORD DBL_MAX 78 namespace gams {
namespace pose {
107 template<
typename L,
typename R>
109 std::is_same<typename base_of<L>::type,
110 typename base_of<R>::type> {};
114 template<
typename Units>
117 static_assert(
sizeof(Units) < 0,
"Unit type not supported by BasicVector");
138 template<
typename T,
size_t N,
139 typename std::enable_if<std::is_floating_point<T>::value,
int>::type = 0>
141 : vec_(N>0 ? a[0] : 0, N>1 ? a[1] : 0, N>2 ? a[2] : 0) {}
145 explicit storage_mixin(
const madara::knowledge::containers::DoubleVector &v)
146 : vec_(v.size() > 0 ? v[0] : 0,
147 v.size() > 1 ? v[1] : 0,
148 v.size() > 2 ? v[2] : 0) {}
150 explicit storage_mixin(
const madara::knowledge::containers::NativeDoubleVector &v)
151 : vec_(v.size() > 0 ? v[0] : 0,
152 v.size() > 1 ? v[1] : 0,
153 v.size() > 2 ? v[2] : 0) {}
155 Eigen::Vector3d &
vec() {
return vec_; }
156 const Eigen::Vector3d &
vec()
const {
return vec_; }
163 static const bool positional =
true;
170 double norm = sqrt(quat.x() * quat.x() +
171 quat.y() * quat.y() +
172 quat.z() * quat.z());
173 double angle = 2 * atan2(norm, quat.w());
174 double sin_half_angle = sin(angle / 2);
175 if(sin_half_angle < 1e-10)
179 return {(quat.x() / sin_half_angle) * angle,
180 (quat.y() / sin_half_angle) * angle,
181 (quat.z() / sin_half_angle) * angle};
187 static const bool positional =
false;
199 template<
typename Units>
201 :
Base(units.to_radians(rx),
202 units.to_radians(ry),
203 units.to_radians(rz)) {}
205 template<
typename T,
typename Units,
size_t N,
206 typename std::enable_if<std::is_floating_point<T>::value,
int>::type = 0>
209 N>0 ? units.to_radians(a[0]) : 0,
210 N>1 ? units.to_radians(a[1]) : 0,
211 N>2 ? units.to_radians(a[2]) : 0) {}
224 template<
typename Derived>
227 Derived &
self() {
return static_cast<Derived&
>(*this); }
228 const Derived &
self()
const {
return static_cast<const Derived&
>(*this); }
230 double x()
const {
return self().vec()[0]; }
231 double y()
const {
return self().vec()[1]; }
232 double z()
const {
return self().vec()[2]; }
234 double x(
double v) {
return (
self().vec()[0] = v); }
235 double y(
double v) {
return (
self().vec()[1] = v); }
236 double z(
double v) {
return (
self().vec()[2] = v); }
243 static const bool free =
false;
245 template<
typename Derived>
253 double lng ()
const {
return x(); }
254 double lon ()
const {
return x(); }
257 double lat ()
const {
return y(); }
260 double alt ()
const {
return -z(); }
263 double lng (
double v) {
return x(v); }
264 double lon (
double v) {
return x(v); }
267 double lat (
double v) {
return y(v); }
270 double alt (
double v) {
return z(-v); }
273 Eigen::Vector3d &
pos_vec() {
return self().vec(); }
274 const Eigen::Vector3d &
pos_vec()
const {
return self().vec(); }
282 static const bool free =
true;
284 template<
typename Derived>
289 Eigen::Vector3d &
dis_vec() {
return self().vec(); }
290 const Eigen::Vector3d &
dis_vec()
const {
return self().vec(); }
298 static const bool free =
true;
300 template<
typename Derived>
302 Derived &
self() {
return static_cast<Derived&
>(*this); }
303 const Derived &
self()
const {
return static_cast<const Derived&
>(*this); }
305 double dx()
const {
return self().vec()[0]; }
306 double dy()
const {
return self().vec()[1]; }
307 double dz()
const {
return self().vec()[2]; }
309 double dx(
double v) {
return (
self().vec()[0] = v); }
310 double dy(
double v) {
return (
self().vec()[1] = v); }
311 double dz(
double v) {
return (
self().vec()[2] = v); }
313 Eigen::Vector3d &
vel_vec() {
return self().vec(); }
314 const Eigen::Vector3d &
vel_vec()
const {
return self().vec(); }
322 static const bool positional =
true;
323 static const bool free =
true;
325 template<
typename Derived>
327 Derived &
self() {
return static_cast<Derived&
>(*this); }
328 const Derived &
self()
const {
return static_cast<const Derived&
>(*this); }
330 double ddx()
const {
return self().vec()[0]; }
331 double ddy()
const {
return self().vec()[1]; }
332 double ddz()
const {
return self().vec()[2]; }
334 double ddx(
double v) {
return (
self().vec()[0] = v); }
335 double ddy(
double v) {
return (
self().vec()[1] = v); }
336 double ddz(
double v) {
return (
self().vec()[2] = v); }
338 Eigen::Vector3d &
acc_vec() {
return self().vec(); }
339 const Eigen::Vector3d &
acc_vec()
const {
return self().vec(); }
344 template<
typename Derived>
347 Derived &
self() {
return static_cast<Derived&
>(*this); }
348 const Derived &
self()
const {
return static_cast<const Derived&
>(*this); }
352 return self().distance_to(target);
358 return u.from_radians (
self().angle_to (target));
363 template<
typename Derived>
369 double rx()
const {
return self().vec()[0]; }
370 double ry()
const {
return self().vec()[1]; }
371 double rz()
const {
return self().vec()[2]; }
373 double rx(
double v) {
return (
self().vec()[0] = v); }
374 double ry(
double v) {
return (
self().vec()[1] = v); }
375 double rz(
double v) {
return (
self().vec()[2] = v); }
383 double magnitude = sqrt(rx() * rx() + ry() * ry() + rz() * rz());
388 double half_mag = magnitude / 2;
389 double cos_half_mag = cos(half_mag);
390 double sin_half_mag = sin(half_mag);
391 return {cos_half_mag,
392 (rx() / magnitude) * sin_half_mag,
393 (ry() / magnitude) * sin_half_mag,
394 (rz() / magnitude) * sin_half_mag};
402 template<
typename Other>
403 auto slerp(
double scale,
const Other &other) ->
404 typename std::decay<decltype(other.into_quat(),
405 std::declval<Derived>())>::type
407 return Derived(into_quat().slerp(scale, other.into_quat()));
410 template<
typename Other>
411 auto slerp(
const Other &other,
double scale) ->
412 typename std::decay<decltype(other.into_quat(),
413 std::declval<Derived>())>::type
415 return slerp(scale, other);
418 template<
typename Other>
420 decltype(other.into_quat(), void())
422 self() = Derived(into_quat().slerp(scale, other.into_quat()));
425 template<
typename Other>
427 decltype(other.into_quat(), void())
429 return slerp_this(scale, other);
437 static const bool free =
false;
439 template<
typename Derived>
444 Eigen::Vector3d &
ori_vec() {
return self().vec(); }
445 const Eigen::Vector3d &
ori_vec()
const {
return self().vec(); }
453 static const bool free =
true;
455 template<
typename Derived>
460 Eigen::Vector3d &
rot_vec() {
return self().vec(); }
461 const Eigen::Vector3d &
rot_vec()
const {
return self().vec(); }
469 static const bool free =
true;
471 template<
typename Derived>
473 Derived &
self() {
return static_cast<Derived&
>(*this); }
474 const Derived &
self()
const {
return static_cast<const Derived&
>(*this); }
476 double drx()
const {
return self().vec()[0]; }
477 double dry()
const {
return self().vec()[1]; }
478 double drz()
const {
return self().vec()[2]; }
480 double drx(
double v) {
return (
self().vec()[0] = v); }
481 double dry(
double v) {
return (
self().vec()[1] = v); }
482 double drz(
double v) {
return (
self().vec()[2] = v); }
485 const Eigen::Vector3d &
ang_vel_vec()
const {
return self().vec(); }
493 static const bool positional =
true;
494 static const bool free =
true;
496 template<
typename Derived>
498 Derived &
self() {
return static_cast<Derived&
>(*this); }
499 const Derived &
self()
const {
return static_cast<const Derived&
>(*this); }
501 double ddrx()
const {
return self().vec()[0]; }
502 double ddry()
const {
return self().vec()[1]; }
503 double ddrz()
const {
return self().vec()[2]; }
505 double ddrx(
double v) {
return (
self().vec()[0] = v); }
506 double ddry(
double v) {
return (
self().vec()[1] = v); }
507 double ddrz(
double v) {
return (
self().vec()[2] = v); }
510 const Eigen::Vector3d &
ang_acc_vec()
const {
return self().vec(); }
515 template<
typename Derived,
typename Units>
528 using storage_mixin::storage_mixin;
529 using storage_mixin::vec;
539 template<
typename Derived2>
543 static constexpr
bool positional() {
return traits::positional; }
549 static constexpr
bool free() {
return traits::free; }
552 static constexpr
bool fixed() {
return !free(); }
555 size_t size()
const {
return (
size_t)vec().size(); }
560 double get(
size_t i)
const {
return vec()[i]; }
568 double set(
size_t i,
double v) {
return (vec()[i] = v); }
573 for (
int i = 0; i < vec().size(); ++i) {
584 for (
int i = 0; i < vec().size(); ++i) {
605 template<
typename ContainType>
608 for(
size_t i = 0; i < size(); i++)
626 template<
typename ContainType>
629 for(
size_t i = 0; i < size(); i++)
642 const std::string & delimiter =
",",
643 const std::string & unset_identifier =
"<unset>")
const 645 std::stringstream buffer;
648 for (
int i = 0; i < vec().size(); ++i)
661 buffer << unset_identifier;
664 return buffer.str ();
672 madara::knowledge::containers::NativeDoubleVector &container)
const 674 container.set (0, this->
get (0));
675 container.set (1, this->
get (1));
676 container.set (2, this->
get (2));
684 const madara::knowledge::containers::NativeDoubleVector &container)
686 this->
set (0, container[0]);
687 this->
set (1, container[1]);
688 this->
set (2, container[2]);
694 template<
typename Other>
697 return this->vec().dot(other.vec());
703 template<
typename Other>
706 Derived ret = this->
self();
707 ret.vec() = this->vec().
cross(other.vec());
716 return this->vec().norm();
724 return this->vec().squaredNorm();
732 Derived ret = this->
self();
778 #include "Coordinate.inl" 783 namespace gams {
namespace pose {
786 #define GAMS_POSE_MAKE_COMPOSITE_VEC_SCALAR_OP(op) \ 787 template<typename Derived, typename Units, typename Scalar> \ 788 inline auto operator op##=(BasicVector<Derived, Units> &vec, Scalar scalar) -> \ 789 typename std::enable_if<std::is_arithmetic<Scalar>::value && \ 790 BasicVector<Derived, Units>::free(), \ 791 typename BasicVector<Derived, Units>::derived_type&>::type \ 793 vec.vec() op##= scalar; \ 798 #define GAMS_POSE_MAKE_BINARY_VEC_SCALAR_OP(op) \ 799 template<typename Derived, typename Units, typename Scalar> \ 800 inline auto operator op(const BasicVector<Derived, Units> &vec, Scalar scalar) -> \ 801 typename std::enable_if<std::is_arithmetic<Scalar>::value && \ 802 BasicVector<Derived, Units>::free(), \ 803 typename BasicVector<Derived, Units>::derived_type>::type \ 805 typename BasicVector<Derived, Units>::derived_type ret = vec.self(); \ 810 template<typename Derived, typename Units, typename Scalar> \ 811 inline auto operator op(Scalar scalar, const BasicVector<Derived, Units> &vec) -> \ 812 decltype(vec op scalar) \ 814 return vec op scalar; \ 817 #define GAMS_POSE_MAKE_VEC_SCALAR_OPS(op) \ 818 GAMS_POSE_MAKE_COMPOSITE_VEC_SCALAR_OP(op) \ 819 GAMS_POSE_MAKE_BINARY_VEC_SCALAR_OP(op) 825 #define GAMS_POSE_MAKE_COMPOSITE_VECS_OP(op) \ 826 template<typename LDerived, \ 827 typename RDerived, typename Units> \ 828 inline auto operator op##=(BasicVector<LDerived, Units> &lhs, \ 829 const Eigen::MatrixBase<RDerived> &rhs) -> \ 830 typename std::enable_if<unit_traits<Units>::positional, \ 833 lhs.vec() op##= rhs; \ 837 template<typename LDerived, \ 838 typename RDerived, typename Units> \ 839 inline auto operator op##=(BasicVector<LDerived, Units> &lhs, \ 840 const BasicVector<RDerived, Units> &rhs) -> \ 841 typename std::enable_if<unit_traits<Units>::positional && \ 842 unit_traits<Units>::free, LDerived &>::type \ 844 lhs.vec() op##= rhs.vec(); \ 848 template<typename LDerived, \ 849 typename RDerived, typename Units> \ 850 inline auto operator op##=(BasicVector<LDerived, units::absolute<Units>> &lhs, \ 851 const BasicVector<RDerived, Units> &rhs) -> \ 852 typename std::enable_if<unit_traits<Units>::positional && \ 853 unit_traits<Units>::free, LDerived &>::type \ 855 lhs.vec() op##= rhs.vec(); \ 864 template<typename LDerived, typename LUnits,
865 typename RDerived, typename RUnits>
868 typename
std::enable_if<RDerived::free(), LDerived>::type
870 LDerived ret = lhs.self();
877 template<
typename LDerived,
typename LUnits,
878 typename RDerived,
typename RUnits>
881 typename std::enable_if<LDerived::free() && RDerived::fixed(), RDerived>::type
883 RDerived ret = rhs.self();
890 template<
typename LDerived,
typename LUnits,
891 typename RDerived,
typename RUnits>
894 typename std::enable_if<LDerived::free() && RDerived::free(), LDerived>::type
896 LDerived ret = lhs.self();
908 template<
typename LDerived,
typename LUnits,
909 typename RDerived,
typename RUnits>
912 typename std::enable_if<LDerived::fixed() && RDerived::fixed(),
916 ret.vec() -= rhs.vec();
921 #define GAMS_POSE_MAKE_COORDINATE_COMPARE_OPS(op) \ 922 template<typename LDerived, typename RDerived, typename Units> \ 923 inline bool operator op ( \ 924 const BasicVector<LDerived, Units> &lhs, \ 925 const BasicVector<RDerived, Units> &rhs) \ 927 for (int i = 0; i < lhs.vec().size(); ++i) { \ 928 if (!(lhs.vec()[i] op rhs.vec()[i])) { \ 935 template<typename LDerived, typename RDerived, typename Units> \ 936 inline bool operator op ( \ 937 const Framed<BasicVector<LDerived, Units>> &lhs, \ 938 const Framed<BasicVector<RDerived, Units>> &rhs) \ 940 return lhs.frame() op rhs.frame() && \ 941 static_cast<const BasicVector<LDerived, Units> &>(lhs) op \ 942 static_cast<const BasicVector<RDerived, Units> &>(rhs); \ 945 template<typename LDerived, typename RDerived, typename Units> \ 946 inline bool operator op ( \ 947 const Stamped<Framed<BasicVector<LDerived, Units>>> &lhs, \ 948 const Stamped<Framed<BasicVector<RDerived, Units>>> &rhs) \ 950 return lhs.time() op rhs.time() && \ 951 static_cast<const Framed<BasicVector<LDerived, Units> &>>(lhs) op \ 952 static_cast<const Framed<BasicVector<RDerived, Units> &>>(rhs); \ 966 #define GAMS_POSE_MAKE_COORDINATE_TYPE(name, units) \ 967 class name##Vector : \ 968 public BasicVector<name##Vector, units> \ 971 using Base = BasicVector<name##Vector, units>; \ 973 static constexpr const char * type_name = #name "Vector"; \ 977 public Framed<BasicVector<name, units>> \ 980 using Base = Framed<BasicVector<name, units>>; \ 982 static constexpr const char * type_name = #name; \ 983 operator name##Vector () const { return name##Vector(this->vec()); } \ 984 name(name##Vector o) : Base(o.vec()) {} \ 988 class Stamped##name : \ 989 public Stamped<Framed<BasicVector<Stamped##name, units>>> \ 992 using Base = Stamped<Framed<BasicVector<Stamped##name, units>>>; \ 994 static constexpr const char * type_name = "Stamped" #name; \ 995 operator name##Vector () const { return name##Vector(this->vec()); } \ 996 operator name () const { return name(this->frame(), this->vec()); } \ 997 Stamped##name(name##Vector o) : Base(o.vec()) {} \ 998 Stamped##name(name o) : Base(o.frame(), o.vec()) {} \ 999 Stamped##name() = default; \ 1021 class Accelerations;
1044 class AngularVelocity;
1051 class AngularAccelerations;
1099 inline std::ostream &
operator<<(std::ostream &o,
const Eigen::Vector3d &v)
1102 for (
int i = 0; i < v.size(); ++i)
1121 template<
typename Derived,
typename Units>
1122 inline std::ostream &operator<<(std::ostream &o, const BasicVector<Derived, Units> &v)
1124 o << Derived::type_name <<
"(";
void from_container(const madara::knowledge::containers::NativeDoubleVector &container)
Assign values from a NativeDoubleVector container.
void to_array(ContainType &out) const
Outputs this Coordinates values to the referenced container.
auto slerp(const Other &other, double scale) -> typename std::decay< decltype(other.into_quat(), std::declval< Derived >())>::type
void from_quat(const Eigen::Quaterniond &quat)
double norm() const
Passthrough to Eigen vector norm method.
storage_mixin(const madara::knowledge::containers::DoubleVector &v)
double squaredNorm() const
Passthrough to Eigen vector squaredNorm method.
Derived cross(const BasicVector< Other, Units > &other) const
Passthrough to Eigen vector cross method.
Copyright (c) 2015 Carnegie Mellon University.
#define GAMS_POSE_MAKE_COMPOSITE_VECS_OP(op)
Generates Eigen passthroughs on vectors.
const Eigen::Vector3d & vec() const
static constexpr bool positional()
Is this coordinate a positional one?
bool is_zero() const
Does this coordinate have values all zeroes?
Trait to compare types, ignoring absolute.
Eigen::Vector3d & acc_vec()
auto slerp_this(double scale, const Other &other) -> decltype(other.into_quat(), void())
double longitude(double v)
static constexpr bool fixed()
Is this coordinate a fixed vector?
Helper trait to customize BasicVector based on unit.
auto slerp_this(const Other &other, double scale) -> decltype(other.into_quat(), void())
#define GAMS_POSE_MAKE_VEC_SCALAR_OPS(op)
static constexpr bool rotational()
Is this coordinate a rotational one?
const Eigen::Vector3d & rot_vec() const
const Eigen::Vector3d & ori_vec() const
Helper struct for defining which fixed coordinate types map to which free vector coordinate types...
const Eigen::Vector3d & vel_vec() const
Eigen::Quaterniond into_quat() const
Represent this rotation as a quaternion.
storage_mixin(double rx, double ry, double rz, Units units)
storage_mixin(const Eigen::Quaterniond &quat)
Construct from a Quaternion.
typename unit_traits< Units >::storage_mixin storage_mixin
Eigen::Vector3d & ang_acc_vec()
std::string to_string(const std::string &delimiter=",", const std::string &unset_identifier="<unset>") const
Returns a string of the values x, y, z.
bool is_set() const
Does this coordinate have any values not INVAL_COORD?
BasicVector(const BasicVector< Derived2, Units > &v)
Construct from a vector of same units, but different derived type.
#define GAMS_POSE_MAKE_COORDINATE_COMPARE_OPS(op)
Generates comparison operators for coordinate types.
const Eigen::Vector3d & dis_vec() const
Tag that coordinate is a fixed vector, not free.
double angle_to(const Derived &target, U u) const
Contains all GAMS-related tools, classes and code.
void to_container(madara::knowledge::containers::NativeDoubleVector &container) const
Assign values into a NativeDoubleVector container.
double dot(const BasicVector< Other, Units > &other) const
Passthrough to Eigen vector dot method.
const Eigen::Vector3d & acc_vec() const
Trait to strip absolute off a unit tag.
const Eigen::Vector3d & ang_vel_vec() const
gams::pose::Orientation Orientation
Represents a orientation or orientation within a reference frame.
Copyright (c) 2015 Carnegie Mellon University.
Used internally to implement angle operations.
For internal use. The underlying template for all coordinate types.
storage_mixin(double x, double y, double z)
void normalize()
Reduces this Coordinate to it's normalized form, should one exist.
typename unit_traits< Units >::template mixin< Derived > mixin
Eigen::Vector3d & vel_vec()
Eigen::Vector3d & ori_vec()
const Eigen::Vector3d & pos_vec() const
const Eigen::Vector3d & ang_acc_vec() const
Eigen::Vector3d quat_to_axis_angle(const Eigen::Quaterniond &quat)
auto operator-(const BasicVector< LDerived, LUnits > &lhs, const BasicVector< RDerived, RUnits > &rhs) -> typename std::enable_if< LDerived::free()&&RDerived::free(), LDerived >::type
Pass through to Eigen operator- on vectors, for free types.
storage_mixin(const Eigen::Vector3d &vec)
auto slerp(double scale, const Other &other) -> typename std::decay< decltype(other.into_quat(), std::declval< Derived >())>::type
size_t size() const
Get number of values in this coordinate.
void from_array(const ContainType &in)
Overwrites this Coordinate's values with those pulled from the referenced array.
storage_mixin(const madara::knowledge::containers::NativeDoubleVector &v)
auto operator+(const BasicVector< LDerived, LUnits > &lhs, const BasicVector< RDerived, RUnits > &rhs) -> typename std::enable_if< RDerived::free(), LDerived >::type
Pass through to Eigen operator- on vectors, if RHS is free.
Eigen::Vector3d & rot_vec()
Eigen::Vector3d & dis_vec()
static constexpr bool free()
Is this coordinate a free vector?
storage_mixin(double x, double y)
#define GAMS_POSE_MAKE_COORDINATE_TYPE(name, units)
Creates the three variants for each coordinate type: {Coordinate}Vector: just the coordinate values a...
Eigen::Vector3d & pos_vec()
storage_mixin(T(&a)[N], Units units)
Eigen::Vector3d & ang_vel_vec()
Derived normalized() const
Passthrough to Eigen vector normalized method.
double latitude(double v)
double altitude(double v)
double angle_to(const Derived &target) const
std::ostream & operator<<(std::ostream &o, const Eigen::Vector3d &v)