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
75 #include "Eigen/Geometry"
78 #define INVAL_COORD DBL_MAX
80 namespace gams {
namespace pose {
109 template<
typename L,
typename R>
111 std::is_same<typename base_of<L>::type,
112 typename base_of<R>::type> {};
116 template<
typename Units>
119 static_assert(
sizeof(Units) < 0,
"Unit type not supported by BasicVector");
140 template<
typename T,
size_t N,
141 typename std::enable_if<std::is_floating_point<T>::value,
int>::type = 0>
143 :
vec_(N>0 ? a[0] : 0, N>1 ? a[1] : 0, N>2 ? a[2] : 0) {}
147 explicit storage_mixin(
const madara::knowledge::containers::DoubleVector &v)
148 :
vec_(v.size() > 0 ? v[0] : 0,
149 v.size() > 1 ? v[1] : 0,
150 v.size() > 2 ? v[2] : 0) {}
152 explicit storage_mixin(
const madara::knowledge::containers::NativeDoubleVector &v)
153 :
vec_(v.size() > 0 ? v[0] : 0,
154 v.size() > 1 ? v[1] : 0,
155 v.size() > 2 ? v[2] : 0) {}
158 const Eigen::Vector3d &
vec()
const {
return vec_; }
172 double norm = sqrt(quat.x() * quat.x() +
173 quat.y() * quat.y() +
174 quat.z() * quat.z());
175 double angle = 2 * atan2(norm, quat.w());
176 double sin_half_angle = sin(angle / 2);
177 if(sin_half_angle < 1e-10)
181 return {(quat.x() / sin_half_angle) * angle,
182 (quat.y() / sin_half_angle) * angle,
183 (quat.z() / sin_half_angle) * angle};
201 template<
typename Units>
203 :
Base(units.to_radians(rx),
204 units.to_radians(ry),
205 units.to_radians(rz)) {}
207 template<
typename T,
typename Units,
size_t N,
208 typename std::enable_if<std::is_floating_point<T>::value,
int>::type = 0>
211 N>0 ? units.to_radians(a[0]) : 0,
212 N>1 ? units.to_radians(a[1]) : 0,
213 N>2 ? units.to_radians(a[2]) : 0) {}
226 template<
typename Derived>
230 Derived &
self() {
return static_cast<Derived&
>(*this); }
231 const Derived &
self()
const {
return static_cast<const Derived&
>(*this); }
233 double x()
const {
return self().vec()[0]; }
234 double y()
const {
return self().vec()[1]; }
235 double z()
const {
return self().vec()[2]; }
237 double x(
double v) {
return (
self().vec()[0] = v); }
238 double y(
double v) {
return (
self().vec()[1] = v); }
239 double z(
double v) {
return (
self().vec()[2] = v); }
246 static const bool free =
false;
248 template<
typename Derived>
256 double lng ()
const {
return x(); }
257 double lon ()
const {
return x(); }
260 double lat ()
const {
return y(); }
263 double alt ()
const {
return -z(); }
266 double lng (
double v) {
return x(v); }
267 double lon (
double v) {
return x(v); }
270 double lat (
double v) {
return y(v); }
273 double alt (
double v) {
return z(-v); }
276 Eigen::Vector3d &
pos_vec() {
return self().vec(); }
277 const Eigen::Vector3d &
pos_vec()
const {
return self().vec(); }
285 static const bool free =
true;
287 template<
typename Derived>
292 Eigen::Vector3d &
dis_vec() {
return self().vec(); }
293 const Eigen::Vector3d &
dis_vec()
const {
return self().vec(); }
301 static const bool free =
true;
303 template<
typename Derived>
305 Derived &
self() {
return static_cast<Derived&
>(*this); }
306 const Derived &
self()
const {
return static_cast<const Derived&
>(*this); }
308 double dx()
const {
return self().vec()[0]; }
309 double dy()
const {
return self().vec()[1]; }
310 double dz()
const {
return self().vec()[2]; }
312 double dx(
double v) {
return (
self().vec()[0] = v); }
313 double dy(
double v) {
return (
self().vec()[1] = v); }
314 double dz(
double v) {
return (
self().vec()[2] = v); }
316 Eigen::Vector3d &
vel_vec() {
return self().vec(); }
317 const Eigen::Vector3d &
vel_vec()
const {
return self().vec(); }
325 static const bool positional =
true;
326 static const bool free =
true;
328 template<
typename Derived>
330 Derived &
self() {
return static_cast<Derived&
>(*this); }
331 const Derived &
self()
const {
return static_cast<const Derived&
>(*this); }
333 double ddx()
const {
return self().vec()[0]; }
334 double ddy()
const {
return self().vec()[1]; }
335 double ddz()
const {
return self().vec()[2]; }
337 double ddx(
double v) {
return (
self().vec()[0] = v); }
338 double ddy(
double v) {
return (
self().vec()[1] = v); }
339 double ddz(
double v) {
return (
self().vec()[2] = v); }
341 Eigen::Vector3d &
acc_vec() {
return self().vec(); }
342 const Eigen::Vector3d &
acc_vec()
const {
return self().vec(); }
347 template<
typename Derived>
350 Derived &
self() {
return static_cast<Derived&
>(*this); }
351 const Derived &
self()
const {
return static_cast<const Derived&
>(*this); }
355 return self().distance_to(target);
361 return u.from_radians (
self().
angle_to (target));
366 template<
typename Derived>
372 double rx()
const {
return self().vec()[0]; }
373 double ry()
const {
return self().vec()[1]; }
374 double rz()
const {
return self().vec()[2]; }
376 double rx(
double v) {
return (
self().vec()[0] = v); }
377 double ry(
double v) {
return (
self().vec()[1] = v); }
378 double rz(
double v) {
return (
self().vec()[2] = v); }
386 double magnitude = sqrt(
rx() *
rx() +
ry() *
ry() +
rz() *
rz());
391 double half_mag = magnitude / 2;
392 double cos_half_mag = cos(half_mag);
393 double sin_half_mag = sin(half_mag);
394 return {cos_half_mag,
395 (
rx() / magnitude) * sin_half_mag,
396 (
ry() / magnitude) * sin_half_mag,
397 (
rz() / magnitude) * sin_half_mag};
405 template<
typename Other>
406 auto slerp(
double scale,
const Other &other) ->
407 typename std::decay<decltype(other.into_quat(),
408 std::declval<Derived>())>::type
413 template<
typename Other>
414 auto slerp(
const Other &other,
double scale) ->
415 typename std::decay<decltype(other.into_quat(),
416 std::declval<Derived>())>::type
418 return slerp(scale, other);
421 template<
typename Other>
423 decltype(other.into_quat(),
void())
425 self() = Derived(
into_quat().slerp(scale, other.into_quat()));
428 template<
typename Other>
430 decltype(other.into_quat(),
void())
440 static const bool free =
false;
442 template<
typename Derived>
447 Eigen::Vector3d &
ori_vec() {
return self().vec(); }
448 const Eigen::Vector3d &
ori_vec()
const {
return self().vec(); }
456 static const bool free =
true;
458 template<
typename Derived>
463 Eigen::Vector3d &
rot_vec() {
return self().vec(); }
464 const Eigen::Vector3d &
rot_vec()
const {
return self().vec(); }
472 static const bool free =
true;
474 template<
typename Derived>
476 Derived &
self() {
return static_cast<Derived&
>(*this); }
477 const Derived &
self()
const {
return static_cast<const Derived&
>(*this); }
479 double drx()
const {
return self().vec()[0]; }
480 double dry()
const {
return self().vec()[1]; }
481 double drz()
const {
return self().vec()[2]; }
483 double drx(
double v) {
return (
self().vec()[0] = v); }
484 double dry(
double v) {
return (
self().vec()[1] = v); }
485 double drz(
double v) {
return (
self().vec()[2] = v); }
488 const Eigen::Vector3d &
ang_vel_vec()
const {
return self().vec(); }
496 static const bool positional =
true;
497 static const bool free =
true;
499 template<
typename Derived>
501 Derived &
self() {
return static_cast<Derived&
>(*this); }
502 const Derived &
self()
const {
return static_cast<const Derived&
>(*this); }
504 double ddrx()
const {
return self().vec()[0]; }
505 double ddry()
const {
return self().vec()[1]; }
506 double ddrz()
const {
return self().vec()[2]; }
508 double ddrx(
double v) {
return (
self().vec()[0] = v); }
509 double ddry(
double v) {
return (
self().vec()[1] = v); }
510 double ddrz(
double v) {
return (
self().vec()[2] = v); }
513 const Eigen::Vector3d &
ang_acc_vec()
const {
return self().vec(); }
524 template<
typename Derived,
typename Units>
537 using storage_mixin::storage_mixin;
538 using storage_mixin::vec;
548 template<
typename Derived2>
552 static constexpr
bool positional() {
return traits::positional; }
558 static constexpr
bool free() {
return traits::free; }
564 size_t size()
const {
return (
size_t)vec().size(); }
569 double get(
size_t i)
const {
return vec()[i]; }
578 double set(
size_t i,
double v) {
return (vec()[i] = v); }
583 for (
int i = 0; i < vec().size(); ++i) {
594 for (
int i = 0; i < vec().size(); ++i) {
615 template<
typename ContainType>
618 for(
size_t i = 0; i <
size(); i++)
636 template<
typename ContainType>
639 for(
size_t i = 0; i <
size(); i++)
652 const std::string & delimiter =
",",
653 const std::string & unset_identifier =
"<unset>")
const
655 std::stringstream buffer;
658 for (
int i = 0; i < vec().size(); ++i)
671 buffer << unset_identifier;
674 return buffer.str ();
682 madara::knowledge::containers::NativeDoubleVector &container)
const
684 container.set (0, this->
get (0));
685 container.set (1, this->
get (1));
686 container.set (2, this->
get (2));
694 const madara::knowledge::containers::NativeDoubleVector &container)
696 this->
set (0, container[0]);
697 this->
set (1, container[1]);
698 this->
set (2, container[2]);
704 template<
typename Other>
707 return this->vec().dot(other.vec());
713 template<
typename Other>
716 Derived ret = this->
self();
717 ret.vec() = this->vec().cross(other.vec());
726 return this->vec().norm();
734 return this->vec().squaredNorm();
742 Derived ret = this->
self();
743 ret.vec().normalize();
788 #include "Coordinate.inl"
793 namespace gams {
namespace pose {
796 #define GAMS_POSE_MAKE_COMPOSITE_VEC_SCALAR_OP(op) \
797 template<typename Derived, typename Units, typename Scalar> \
798 inline auto operator op##=(BasicVector<Derived, Units> &vec, Scalar scalar) -> \
799 typename std::enable_if<std::is_arithmetic<Scalar>::value && \
800 BasicVector<Derived, Units>::free(), \
801 typename BasicVector<Derived, Units>::derived_type&>::type \
803 vec.vec() op##= scalar; \
808 #define GAMS_POSE_MAKE_BINARY_VEC_SCALAR_OP(op) \
809 template<typename Derived, typename Units, typename Scalar> \
810 inline auto operator op(const BasicVector<Derived, Units> &vec, Scalar scalar) -> \
811 typename std::enable_if<std::is_arithmetic<Scalar>::value && \
812 BasicVector<Derived, Units>::free(), \
813 typename BasicVector<Derived, Units>::derived_type>::type \
815 typename BasicVector<Derived, Units>::derived_type ret = vec.self(); \
820 template<typename Derived, typename Units, typename Scalar> \
821 inline auto operator op(Scalar scalar, const BasicVector<Derived, Units> &vec) -> \
822 decltype(vec op scalar) \
824 return vec op scalar; \
827 #define GAMS_POSE_MAKE_VEC_SCALAR_OPS(op) \
828 GAMS_POSE_MAKE_COMPOSITE_VEC_SCALAR_OP(op) \
829 GAMS_POSE_MAKE_BINARY_VEC_SCALAR_OP(op)
835 #define GAMS_POSE_MAKE_COMPOSITE_VECS_OP(op) \
836 template<typename LDerived, \
837 typename RDerived, typename Units> \
838 inline auto operator op##=(BasicVector<LDerived, Units> &lhs, \
839 const Eigen::MatrixBase<RDerived> &rhs) -> \
840 typename std::enable_if<unit_traits<Units>::positional, \
843 lhs.vec() op##= rhs; \
847 template<typename LDerived, \
848 typename RDerived, typename Units> \
849 inline auto operator op##=(BasicVector<LDerived, Units> &lhs, \
850 const BasicVector<RDerived, Units> &rhs) -> \
851 typename std::enable_if<unit_traits<Units>::positional && \
852 unit_traits<Units>::free, LDerived &>::type \
854 lhs.vec() op##= rhs.vec(); \
858 template<typename LDerived, \
859 typename RDerived, typename Units> \
860 inline auto operator op##=(BasicVector<LDerived, units::absolute<Units>> &lhs, \
861 const BasicVector<RDerived, Units> &rhs) -> \
862 typename std::enable_if<unit_traits<Units>::positional && \
863 unit_traits<Units>::free, LDerived &>::type \
865 lhs.vec() op##= rhs.vec(); \
874 template<typename LDerived, typename LUnits,
875 typename RDerived, typename RUnits>
878 typename std::enable_if<RDerived::free(), LDerived>::type
880 LDerived ret = lhs.self();
887 template<
typename LDerived,
typename LUnits,
888 typename RDerived,
typename RUnits>
889 inline auto operator+(
const BasicVector<LDerived, LUnits> &lhs,
890 const BasicVector<RDerived, RUnits> &rhs) ->
891 typename std::enable_if<LDerived::free() && RDerived::fixed(), RDerived>::type
893 RDerived ret = rhs.self();
900 template<
typename LDerived,
typename LUnits,
901 typename RDerived,
typename RUnits>
904 typename std::enable_if<LDerived::free() && RDerived::free(), LDerived>::type
906 LDerived ret = lhs.self();
918 template<
typename LDerived,
typename LUnits,
919 typename RDerived,
typename RUnits>
922 typename std::enable_if<LDerived::fixed() && RDerived::fixed(),
926 ret.vec() -= rhs.vec();
935 template<
typename LDerived,
typename RDerived,
typename Units>
940 for (
int i = 0; i < lhs.vec().size(); ++i) {
941 if (!(lhs.vec()[i] == rhs.vec()[i])) {
953 template<
typename LDerived,
typename RDerived,
typename Units>
958 return lhs.frame() == rhs.frame() &&
968 template<
typename LDerived,
typename RDerived,
typename Units>
973 return lhs.time() == rhs.time() &&
983 template<
typename LDerived,
typename RDerived,
typename Units>
988 return !(lhs == rhs);
996 template<
typename LDerived,
typename RDerived,
typename Units>
1001 return !(lhs == rhs);
1009 template<
typename LDerived,
typename RDerived,
typename Units>
1014 return !(lhs == rhs);
1017 template<
typename LDerived,
typename RDerived,
typename Units>
1022 for (
int i = 0; i < lhs.vec().size(); ++i) {
1023 const auto &l = lhs.vec()[i];
1024 const auto &r = rhs.vec()[i];
1037 template<
typename LDerived,
typename RDerived,
typename Units>
1042 return &lhs.frame() < &rhs.frame() || (lhs.frame() == rhs.frame() &&
1047 template<
typename LDerived,
typename RDerived,
typename Units>
1052 return lhs.time() < rhs.time() || (lhs.time() == rhs.time() &&
1057 template<
typename LDerived,
typename RDerived,
typename Units>
1062 return (lhs == rhs) || (lhs < rhs);
1065 template<
typename LDerived,
typename RDerived,
typename Units>
1070 return (lhs == rhs) || (lhs < rhs);
1073 template<
typename LDerived,
typename RDerived,
typename Units>
1078 return (lhs == rhs) || (lhs < rhs);
1081 template<
typename LDerived,
typename RDerived,
typename Units>
1086 return !(lhs < rhs);
1089 template<
typename LDerived,
typename RDerived,
typename Units>
1094 return !(lhs < rhs);
1097 template<
typename LDerived,
typename RDerived,
typename Units>
1102 return !(lhs < rhs);
1105 template<
typename LDerived,
typename RDerived,
typename Units>
1110 return !(lhs <= rhs);
1113 template<
typename LDerived,
typename RDerived,
typename Units>
1118 return !(lhs <= rhs);
1121 template<
typename LDerived,
typename RDerived,
typename Units>
1126 return !(lhs <= rhs);
1133 #define GAMS_POSE_MAKE_COORDINATE_TYPE(name, units) \
1134 class name##Vector : \
1135 public BasicVector<name##Vector, units> \
1138 using Base = BasicVector<name##Vector, units>; \
1140 static constexpr const char * type_name = #name "Vector"; \
1144 public Framed<BasicVector<name, units>> \
1147 using Base = Framed<BasicVector<name, units>>; \
1149 static constexpr const char * type_name = #name; \
1150 operator name##Vector () const { return name##Vector(this->vec()); } \
1151 name(name##Vector o) : Base(o.vec()) {} \
1155 class Stamped##name : \
1156 public Stamped<Framed<BasicVector<Stamped##name, units>>> \
1159 using Base = Stamped<Framed<BasicVector<Stamped##name, units>>>; \
1161 static constexpr const char * type_name = "Stamped" #name; \
1162 operator name##Vector () const { return name##Vector(this->vec()); } \
1163 operator name () const { return name(this->frame(), this->vec()); } \
1164 Stamped##name(name##Vector o) : Base(o.vec()) {} \
1165 Stamped##name(name o) : Base(o.frame(), o.vec()) {} \
1166 Stamped##name() = default; \
1188 class Accelerations;
1211 class AngularVelocity;
1218 class AngularAccelerations;
1266 inline std::ostream &
operator<<(std::ostream &o,
const Eigen::Vector3d &v)
1269 for (
int i = 0; i < v.size(); ++i)
1288 template<
typename Derived,
typename Units>
1291 o << Derived::type_name <<
"(";
Copyright (c) 2015 Carnegie Mellon University.
Copyright (c) 2015 Carnegie Mellon University.
For internal use. The underlying template for all coordinate types.
double norm() const
Passthrough to Eigen vector norm method.
void to_array(ContainType &out) const
Outputs this Coordinates values to the referenced container.
static constexpr bool free()
Is this coordinate a free vector?
static constexpr bool fixed()
Is this coordinate a fixed vector?
bool is_set() const
Does this coordinate have any values not INVAL_COORD?
static constexpr bool positional()
Is this coordinate a positional one?
double get(size_t i) const
Get i'th value in this Coordinate.
static constexpr bool rotational()
Is this coordinate a rotational one?
void from_container(const madara::knowledge::containers::NativeDoubleVector &container)
Assign values from a NativeDoubleVector container.
void to_container(madara::knowledge::containers::NativeDoubleVector &container) const
Assign values into a NativeDoubleVector container.
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.
double squaredNorm() const
Passthrough to Eigen vector squaredNorm method.
std::string to_string(const std::string &delimiter=",", const std::string &unset_identifier="<unset>") const
Returns a string of the values x, y, z.
BasicVector(const BasicVector< Derived2, Units > &v)
Construct from a vector of same units, but different derived type.
typename unit_traits< Units >::storage_mixin storage_mixin
double set(size_t i, double v)
Set i'th value in this Coordinate.
Derived cross(const BasicVector< Other, Units > &other) const
Passthrough to Eigen vector cross method.
Derived normalized() const
Passthrough to Eigen vector normalized method.
bool is_zero() const
Does this coordinate have values all zeroes?
double dot(const BasicVector< Other, Units > &other) const
Passthrough to Eigen vector dot method.
typename unit_traits< Units >::template mixin< Derived > mixin
Internal class implementing coordinates bound to reference frame.
Used internally to implement angle operations.
Internal class implementing coordinates stamped with timestamp.
storage_mixin(double rx, double ry, double rz, Units units)
storage_mixin(T(&a)[N], Units units)
storage_mixin(const Eigen::Quaterniond &quat)
Construct from a Quaternion.
const Eigen::Vector3d & vec() const
storage_mixin(double x, double y, double z)
storage_mixin(const Eigen::Vector3d &vec)
storage_mixin(double x, double y)
storage_mixin(const madara::knowledge::containers::NativeDoubleVector &v)
storage_mixin(const madara::knowledge::containers::DoubleVector &v)
std::ostream & operator<<(std::ostream &o, const Eigen::Vector3d &v)
bool operator>(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
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< RDerived::free(), LDerived >::type
Pass through to Eigen operator- on vectors, if RHS is free.
bool operator<=(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
bool operator==(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
Equality operator for coordinates.
bool operator<(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
bool operator!=(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
Inequality operator for coordinates.
bool operator>=(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
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.
gams::pose::Orientation Orientation
Represents a orientation or orientation within a reference frame.
Contains all GAMS-related tools, classes and code.
#define GAMS_POSE_MAKE_COORDINATE_TYPE(name, units)
Creates the three variants for each coordinate type: {Coordinate}Vector: just the coordinate values a...
#define GAMS_POSE_MAKE_COMPOSITE_VECS_OP(op)
Generates Eigen passthroughs on vectors.
#define GAMS_POSE_MAKE_VEC_SCALAR_OPS(op)
void from_quat(const Eigen::Quaterniond &quat)
auto slerp(const Other &other, double scale) -> typename std::decay< decltype(other.into_quat(), std::declval< Derived >())>::type
auto slerp(double scale, const Other &other) -> typename std::decay< decltype(other.into_quat(), std::declval< Derived >())>::type
auto slerp_this(const Other &other, double scale) -> decltype(other.into_quat(), void())
Eigen::Quaterniond into_quat() const
Represent this rotation as a quaternion.
auto slerp_this(double scale, const Other &other) -> decltype(other.into_quat(), void())
double angle_to(const Derived &target, U u) const
double angle_to(const Derived &target) const
static const bool positional
static const bool positional
Helper struct for defining which fixed coordinate types map to which free vector coordinate types.
double longitude(double v)
Eigen::Vector3d & pos_vec()
double altitude(double v)
double latitude(double v)
const Eigen::Vector3d & pos_vec() const
const Eigen::Vector3d & ori_vec() const
Eigen::Vector3d & ori_vec()
const Eigen::Vector3d & acc_vec() const
Eigen::Vector3d & acc_vec()
Eigen::Vector3d & ang_acc_vec()
const Eigen::Vector3d & ang_acc_vec() const
Eigen::Vector3d & ang_vel_vec()
const Eigen::Vector3d & ang_vel_vec() const
Eigen::Vector3d & dis_vec()
const Eigen::Vector3d & dis_vec() const
Eigen::Vector3d & rot_vec()
const Eigen::Vector3d & rot_vec() const
const Eigen::Vector3d & vel_vec() const
Eigen::Vector3d & vel_vec()
Helper trait to customize BasicVector based on unit.
Tag that coordinate is a fixed vector, not free.
Trait to strip absolute off a unit tag.
Trait to compare types, ignoring absolute.
Copyright (c) 2015 Carnegie Mellon University.