GAMS  1.4.0
Coordinate.h
Go to the documentation of this file.
1 
54 #include "ReferenceFrame.h"
55 
56 #ifndef _GAMS_POSE_COORDINATE_H_
57 #define _GAMS_POSE_COORDINATE_H_
58 
59 #include "gams/GamsExport.h"
60 #include <string>
61 #include <cfloat>
62 #include <utility>
63 #include "gams/CPP11_compat.h"
64 #include "madara/knowledge/containers/DoubleVector.h"
65 #include "madara/knowledge/containers/NativeDoubleVector.h"
66 #include "ReferenceFrameFwd.h"
67 
68 
69 #ifdef __GNUC__
70 #pragma GCC diagnostic push
71 #pragma GCC diagnostic ignored "-Wunused-parameter"
72  #include "Eigen/Geometry"
73 #pragma GCC diagnostic pop
74 #elif defined _WIN32
75  #include "Eigen/Geometry"
76 #endif
77 
78 #define INVAL_COORD DBL_MAX
79 
80 namespace gams { namespace pose {
81 
83 namespace units {
85  template<typename T>
86  struct absolute {};
87 
88  struct length {};
89  struct velocity {};
90  struct acceleration {};
91  struct plane_angle {};
92  struct angular_velocity {};
94 
96  template<typename T>
97  struct base_of
98  {
99  using type = T;
100  };
101 
102  template<typename T>
103  struct base_of<absolute<T>>
104  {
105  using type = T;
106  };
107 
109  template<typename L, typename R>
110  struct same_base :
111  std::is_same<typename base_of<L>::type,
112  typename base_of<R>::type> {};
113 }
114 
116 template<typename Units>
118 {
119  static_assert(sizeof(Units) < 0, "Unit type not supported by BasicVector");
120 };
121 
124 {
126  {
127  private:
128  Eigen::Vector3d vec_;
129 
130  public:
132  : vec_(0, 0, 0) {}
133 
134  storage_mixin(double x, double y)
135  : vec_(x, y, 0) {}
136 
137  storage_mixin(double x, double y, double z)
138  : vec_(x, y, z) {}
139 
140  template<typename T, size_t N,
141  typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0>
142  storage_mixin(T (&a)[N])
143  : vec_(N>0 ? a[0] : 0, N>1 ? a[1] : 0, N>2 ? a[2] : 0) {}
144 
145  explicit storage_mixin(const Eigen::Vector3d &vec) : vec_(vec) {}
146 
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) {}
151 
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) {}
156 
157  Eigen::Vector3d &vec() { return vec_; }
158  const Eigen::Vector3d &vec() const { return vec_; }
159  };
160 };
161 
164 {
165  static const bool positional = true;
166 };
167 
168 class Quaternion;
169 
170 inline Eigen::Vector3d quat_to_axis_angle(const Eigen::Quaterniond &quat)
171 {
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)
178  {
179  return {0, 0, 0};
180  }
181  return {(quat.x() / sin_half_angle) * angle,
182  (quat.y() / sin_half_angle) * angle,
183  (quat.z() / sin_half_angle) * angle};
184 }
185 
188 {
189  static const bool positional = false;
190 
192  {
193  public:
195  using Base::Base;
196 
197  storage_mixin() = default;
198 
199  storage_mixin(const Quaternion &quat);
200 
201  template<typename Units>
202  storage_mixin(double rx, double ry, double rz, Units units)
203  : Base(units.to_radians(rx),
204  units.to_radians(ry),
205  units.to_radians(rz)) {}
206 
207  template<typename T, typename Units, size_t N,
208  typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0>
209  storage_mixin(T (&a)[N], Units units)
210  : Base(
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) {}
214 
215  public:
220  storage_mixin(const Eigen::Quaterniond &quat)
221  : Base(quat_to_axis_angle(quat)) {}
222  };
223 };
224 
226 template<typename Derived>
228 {
229  using derived_type = Derived;
230  Derived &self() { return static_cast<Derived&>(*this); }
231  const Derived &self() const { return static_cast<const Derived&>(*this); }
232 
233  double x() const { return self().vec()[0]; }
234  double y() const { return self().vec()[1]; }
235  double z() const { return self().vec()[2]; }
236 
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); }
240 };
241 
242 template<>
243 struct unit_traits<units::absolute<units::length>>
245 {
246  static const bool free = false;
247 
248  template<typename Derived>
249  struct mixin : basic_positional_mixin<Derived> {
251  using Base::x;
252  using Base::y;
253  using Base::z;
254  using Base::self;
255 
256  double lng () const { return x(); }
257  double lon () const { return x(); }
258  double longitude () const { return x(); }
259 
260  double lat () const { return y(); }
261  double latitude () const { return y(); }
262 
263  double alt () const { return -z(); }
264  double altitude () const { return -z(); }
265 
266  double lng (double v) { return x(v); }
267  double lon (double v) { return x(v); }
268  double longitude (double v) { return x(v); }
269 
270  double lat (double v) { return y(v); }
271  double latitude (double v) { return y(v); }
272 
273  double alt (double v) { return z(-v); }
274  double altitude (double v) { return z(-v); }
275 
276  Eigen::Vector3d &pos_vec() { return self().vec(); }
277  const Eigen::Vector3d &pos_vec() const { return self().vec(); }
278  };
279 };
280 
281 template<>
282 struct unit_traits<units::length>
284 {
285  static const bool free = true;
286 
287  template<typename Derived>
288  struct mixin : basic_positional_mixin<Derived> {
290  using Base::self;
291 
292  Eigen::Vector3d &dis_vec() { return self().vec(); }
293  const Eigen::Vector3d &dis_vec() const { return self().vec(); }
294  };
295 };
296 
297 template<>
298 struct unit_traits<units::velocity>
300 {
301  static const bool free = true;
302 
303  template<typename Derived>
304  struct mixin {
305  Derived &self() { return static_cast<Derived&>(*this); }
306  const Derived &self() const { return static_cast<const Derived&>(*this); }
307 
308  double dx() const { return self().vec()[0]; }
309  double dy() const { return self().vec()[1]; }
310  double dz() const { return self().vec()[2]; }
311 
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); }
315 
316  Eigen::Vector3d &vel_vec() { return self().vec(); }
317  const Eigen::Vector3d &vel_vec() const { return self().vec(); }
318  };
319 };
320 
321 template<>
322 struct unit_traits<units::acceleration>
324 {
325  static const bool positional = true;
326  static const bool free = true;
327 
328  template<typename Derived>
329  struct mixin {
330  Derived &self() { return static_cast<Derived&>(*this); }
331  const Derived &self() const { return static_cast<const Derived&>(*this); }
332 
333  double ddx() const { return self().vec()[0]; }
334  double ddy() const { return self().vec()[1]; }
335  double ddz() const { return self().vec()[2]; }
336 
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); }
340 
341  Eigen::Vector3d &acc_vec() { return self().vec(); }
342  const Eigen::Vector3d &acc_vec() const { return self().vec(); }
343  };
344 };
345 
347 template<typename Derived>
349 {
350  Derived &self() { return static_cast<Derived&>(*this); }
351  const Derived &self() const { return static_cast<const Derived&>(*this); }
352 
353  double angle_to(const Derived &target) const
354  {
355  return self().distance_to(target);
356  }
357 
358  template<typename U>
359  double angle_to (const Derived &target, U u) const
360  {
361  return u.from_radians (self().angle_to (target));
362  }
363 };
364 
366 template<typename Derived>
368 {
370  using Base::self;
371 
372  double rx() const { return self().vec()[0]; }
373  double ry() const { return self().vec()[1]; }
374  double rz() const { return self().vec()[2]; }
375 
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); }
379 
384  Eigen::Quaterniond into_quat() const
385  {
386  double magnitude = sqrt(rx() * rx() + ry() * ry() + rz() * rz());
387  if(magnitude == 0)
388  {
389  return {1, 0, 0, 0};
390  }
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};
398  }
399 
400  void from_quat(const Eigen::Quaterniond &quat)
401  {
402  this->vec() = quat_to_axis_angle(quat);
403  }
404 
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
409  {
410  return Derived(into_quat().slerp(scale, other.into_quat()));
411  }
412 
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
417  {
418  return slerp(scale, other);
419  }
420 
421  template<typename Other>
422  auto slerp_this(double scale, const Other &other) ->
423  decltype(other.into_quat(), void())
424  {
425  self() = Derived(into_quat().slerp(scale, other.into_quat()));
426  }
427 
428  template<typename Other>
429  auto slerp_this(const Other &other, double scale) ->
430  decltype(other.into_quat(), void())
431  {
432  return slerp_this(scale, other);
433  }
434 };
435 
436 template<>
437 struct unit_traits<units::absolute<units::plane_angle>>
439 {
440  static const bool free = false;
441 
442  template<typename Derived>
443  struct mixin : basic_rotational_mixin<Derived> {
445  using Base::self;
446 
447  Eigen::Vector3d &ori_vec() { return self().vec(); }
448  const Eigen::Vector3d &ori_vec() const { return self().vec(); }
449  };
450 };
451 
452 template<>
453 struct unit_traits<units::plane_angle>
455 {
456  static const bool free = true;
457 
458  template<typename Derived>
459  struct mixin : basic_rotational_mixin<Derived> {
461  using Base::self;
462 
463  Eigen::Vector3d &rot_vec() { return self().vec(); }
464  const Eigen::Vector3d &rot_vec() const { return self().vec(); }
465  };
466 };
467 
468 template<>
469 struct unit_traits<units::angular_velocity>
471 {
472  static const bool free = true;
473 
474  template<typename Derived>
475  struct mixin {
476  Derived &self() { return static_cast<Derived&>(*this); }
477  const Derived &self() const { return static_cast<const Derived&>(*this); }
478 
479  double drx() const { return self().vec()[0]; }
480  double dry() const { return self().vec()[1]; }
481  double drz() const { return self().vec()[2]; }
482 
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); }
486 
487  Eigen::Vector3d &ang_vel_vec() { return self().vec(); }
488  const Eigen::Vector3d &ang_vel_vec() const { return self().vec(); }
489  };
490 };
491 
492 template<>
493 struct unit_traits<units::angular_acceleration>
495 {
496  static const bool positional = true;
497  static const bool free = true;
498 
499  template<typename Derived>
500  struct mixin {
501  Derived &self() { return static_cast<Derived&>(*this); }
502  const Derived &self() const { return static_cast<const Derived&>(*this); }
503 
504  double ddrx() const { return self().vec()[0]; }
505  double ddry() const { return self().vec()[1]; }
506  double ddrz() const { return self().vec()[2]; }
507 
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); }
511 
512  Eigen::Vector3d &ang_acc_vec() { return self().vec(); }
513  const Eigen::Vector3d &ang_acc_vec() const { return self().vec(); }
514  };
515 };
516 
517 template<typename T>
518 struct is_positional : std::integral_constant<bool, T::positional()> {};
519 
520 template<typename T>
521 struct is_rotational : std::integral_constant<bool, T::rotational()> {};
522 
524 template<typename Derived, typename Units>
526  : public unit_traits<Units>::storage_mixin,
527  public unit_traits<Units>::template mixin<Derived>
528 {
529 private:
530  Eigen::Vector3d vec_;
531 
535 
536 public:
537  using storage_mixin::storage_mixin;
538  using storage_mixin::vec;
539 
540  using mixin::self;
541 
542  using derived_type = Derived;
543  using units_type = Units;
544 
545  BasicVector() = default;
546 
548  template<typename Derived2>
550 
552  static constexpr bool positional() { return traits::positional; }
553 
555  static constexpr bool rotational() { return !positional(); }
556 
558  static constexpr bool free() { return traits::free; }
559 
561  static constexpr bool fixed() { return !free(); }
562 
564  size_t size() const { return (size_t)vec().size(); }
565 
569  double get(size_t i) const { return vec()[i]; }
570 
578  double set(size_t i, double v) { return (vec()[i] = v); }
579 
581  bool is_set() const
582  {
583  for (int i = 0; i < vec().size(); ++i) {
584  if (vec()[i] != INVAL_COORD) {
585  return true;
586  }
587  }
588  return false;
589  }
590 
592  bool is_zero() const
593  {
594  for (int i = 0; i < vec().size(); ++i) {
595  if (vec()[i] != 0) {
596  return false;
597  }
598  }
599  return true;
600  }
601 
615  template<typename ContainType>
616  void to_array(ContainType &out) const
617  {
618  for(size_t i = 0; i < size(); i++)
619  {
620  out[i] = get(i);
621  }
622  }
623 
636  template<typename ContainType>
637  void from_array(const ContainType &in)
638  {
639  for(size_t i = 0; i < size(); i++)
640  {
641  set(i, in[i]);
642  }
643  }
644 
651  std::string to_string (
652  const std::string & delimiter = ",",
653  const std::string & unset_identifier = "<unset>") const
654  {
655  std::stringstream buffer;
656  bool first = true;
657 
658  for (int i = 0; i < vec().size(); ++i)
659  {
660  auto x = vec()[i];
661 
662  if (!first) {
663  buffer << delimiter;
664  } else {
665  first = false;
666  }
667 
668  if (x != INVAL_COORD)
669  buffer << x;
670  else
671  buffer << unset_identifier;
672  }
673 
674  return buffer.str ();
675  }
676 
682  madara::knowledge::containers::NativeDoubleVector &container) const
683  {
684  container.set (0, this->get (0));
685  container.set (1, this->get (1));
686  container.set (2, this->get (2));
687  }
688 
694  const madara::knowledge::containers::NativeDoubleVector &container)
695  {
696  this->set (0, container[0]);
697  this->set (1, container[1]);
698  this->set (2, container[2]);
699  }
700 
704  template<typename Other>
705  double dot(const BasicVector<Other, Units> &other) const
706  {
707  return this->vec().dot(other.vec());
708  }
709 
713  template<typename Other>
714  Derived cross(const BasicVector<Other, Units> &other) const
715  {
716  Derived ret = this->self();
717  ret.vec() = this->vec().cross(other.vec());
718  return ret;
719  }
720 
724  double norm() const
725  {
726  return this->vec().norm();
727  }
728 
732  double squaredNorm() const
733  {
734  return this->vec().squaredNorm();
735  }
736 
740  Derived normalized() const
741  {
742  Derived ret = this->self();
743  ret.vec().normalize();
744  return ret;
745  }
746 
757  /*template<typename Derived2>
758  bool approximately_equal(const BasicVector<Derived2, Units> &other,
759  double epsilon) const
760  {
761  return std::fabs(self().distance_to(other.self())) < epsilon;
762  }*/
763 
780  /*template<typename Derived2>
781  double distance_to(const BasicVector<Derived2, Units> &target) const {
782  return (target.vec() - vec()).norm();
783  }*/
784 };
785 
786 } }
787 
788 #include "Coordinate.inl"
789 
790 #include "Framed.h"
791 #include "Stamped.h"
792 
793 namespace gams { namespace pose {
794 
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 \
802 { \
803  vec.vec() op##= scalar; \
804  return vec.self(); \
805 }
806 
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 \
814 { \
815  typename BasicVector<Derived, Units>::derived_type ret = vec.self(); \
816  ret op##= scalar; \
817  return ret; \
818 } \
819 \
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) \
823 { \
824  return vec op scalar; \
825 }
826 
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)
830 
833 
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, \
841  LDerived &>::type \
842 { \
843  lhs.vec() op##= rhs; \
844  return lhs.self(); \
845 } \
846 \
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 \
853 { \
854  lhs.vec() op##= rhs.vec(); \
855  return lhs.self(); \
856 } \
857 \
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 \
864 { \
865  lhs.vec() op##= rhs.vec(); \
866  return lhs.self(); \
867 } \
868 
871 
874 template<typename LDerived, typename LUnits,
875  typename RDerived, typename RUnits>
876 inline auto operator+(const BasicVector<LDerived, LUnits> &lhs,
877  const BasicVector<RDerived, RUnits> &rhs) ->
878  typename std::enable_if<RDerived::free(), LDerived>::type
879 {
880  LDerived ret = lhs.self();
881  ret += rhs;
882  return ret;
883 }
884 
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
892 {
893  RDerived ret = rhs.self();
894  ret += lhs;
895  return ret;
896 }
897 
900 template<typename LDerived, typename LUnits,
901  typename RDerived, typename RUnits>
903  const BasicVector<RDerived, RUnits> &rhs) ->
904  typename std::enable_if<LDerived::free() && RDerived::free(), LDerived>::type
905 {
906  LDerived ret = lhs.self();
907  ret -= rhs;
908  return ret;
909 }
910 
913 template<typename T>
914 struct fixed_into_free {};
915 
918 template<typename LDerived, typename LUnits,
919  typename RDerived, typename RUnits>
920 inline auto operator-(const BasicVector<LDerived, LUnits> &lhs,
921  const BasicVector<RDerived, RUnits> &rhs) ->
922  typename std::enable_if<LDerived::fixed() && RDerived::fixed(),
923  typename fixed_into_free<LDerived>::type>::type
924 {
925  typename fixed_into_free<LDerived>::type ret(lhs);
926  ret.vec() -= rhs.vec();
927  return ret;
928 }
929 
935 template<typename LDerived, typename RDerived, typename Units>
936 inline bool operator == (
937  const BasicVector<LDerived, Units> &lhs,
938  const BasicVector<RDerived, Units> &rhs)
939 {
940  for (int i = 0; i < lhs.vec().size(); ++i) {
941  if (!(lhs.vec()[i] == rhs.vec()[i])) {
942  return false;
943  }
944  }
945  return true;
946 }
947 
953 template<typename LDerived, typename RDerived, typename Units>
954 inline bool operator == (
957 {
958  return lhs.frame() == rhs.frame() &&
959  static_cast<const BasicVector<LDerived, Units> &>(lhs) ==
960  static_cast<const BasicVector<RDerived, Units> &>(rhs);
961 }
962 
968 template<typename LDerived, typename RDerived, typename Units>
969 inline bool operator == (
972 {
973  return lhs.time() == rhs.time() &&
974  static_cast<const Framed<BasicVector<LDerived, Units> &>>(lhs) ==
975  static_cast<const Framed<BasicVector<RDerived, Units> &>>(rhs);
976 }
977 
983 template<typename LDerived, typename RDerived, typename Units>
984 inline bool operator != (
985  const BasicVector<LDerived, Units> &lhs,
986  const BasicVector<RDerived, Units> &rhs)
987 {
988  return !(lhs == rhs);
989 }
990 
996 template<typename LDerived, typename RDerived, typename Units>
997 inline bool operator != (
1000 {
1001  return !(lhs == rhs);
1002 }
1003 
1009 template<typename LDerived, typename RDerived, typename Units>
1010 inline bool operator != (
1013 {
1014  return !(lhs == rhs);
1015 }
1016 
1017 template<typename LDerived, typename RDerived, typename Units>
1018 inline bool operator < (
1019  const BasicVector<LDerived, Units> &lhs,
1020  const BasicVector<RDerived, Units> &rhs)
1021 {
1022  for (int i = 0; i < lhs.vec().size(); ++i) {
1023  const auto &l = lhs.vec()[i];
1024  const auto &r = rhs.vec()[i];
1025 
1026  if (l > r) {
1027  return false;
1028  }
1029 
1030  if (l < r) {
1031  return true;
1032  }
1033  }
1034  return false;
1035 }
1036 
1037 template<typename LDerived, typename RDerived, typename Units>
1038 inline bool operator < (
1041 {
1042  return &lhs.frame() < &rhs.frame() || (lhs.frame() == rhs.frame() &&
1043  static_cast<const BasicVector<LDerived, Units> &>(lhs) ==
1044  static_cast<const BasicVector<RDerived, Units> &>(rhs));
1045 }
1046 
1047 template<typename LDerived, typename RDerived, typename Units>
1048 inline bool operator < (
1051 {
1052  return lhs.time() < rhs.time() || (lhs.time() == rhs.time() &&
1053  static_cast<const Framed<BasicVector<LDerived, Units> &>>(lhs) ==
1054  static_cast<const Framed<BasicVector<RDerived, Units> &>>(rhs));
1055 }
1056 
1057 template<typename LDerived, typename RDerived, typename Units>
1058 inline bool operator <= (
1059  const BasicVector<LDerived, Units> &lhs,
1060  const BasicVector<RDerived, Units> &rhs)
1061 {
1062  return (lhs == rhs) || (lhs < rhs);
1063 }
1064 
1065 template<typename LDerived, typename RDerived, typename Units>
1066 inline bool operator <= (
1069 {
1070  return (lhs == rhs) || (lhs < rhs);
1071 }
1072 
1073 template<typename LDerived, typename RDerived, typename Units>
1074 inline bool operator <= (
1077 {
1078  return (lhs == rhs) || (lhs < rhs);
1079 }
1080 
1081 template<typename LDerived, typename RDerived, typename Units>
1082 inline bool operator >= (
1083  const BasicVector<LDerived, Units> &lhs,
1084  const BasicVector<RDerived, Units> &rhs)
1085 {
1086  return !(lhs < rhs);
1087 }
1088 
1089 template<typename LDerived, typename RDerived, typename Units>
1090 inline bool operator >= (
1093 {
1094  return !(lhs < rhs);
1095 }
1096 
1097 template<typename LDerived, typename RDerived, typename Units>
1098 inline bool operator >= (
1101 {
1102  return !(lhs < rhs);
1103 }
1104 
1105 template<typename LDerived, typename RDerived, typename Units>
1106 inline bool operator > (
1107  const BasicVector<LDerived, Units> &lhs,
1108  const BasicVector<RDerived, Units> &rhs)
1109 {
1110  return !(lhs <= rhs);
1111 }
1112 
1113 template<typename LDerived, typename RDerived, typename Units>
1114 inline bool operator > (
1117 {
1118  return !(lhs <= rhs);
1119 }
1120 
1121 template<typename LDerived, typename RDerived, typename Units>
1122 inline bool operator > (
1125 {
1126  return !(lhs <= rhs);
1127 }
1128 
1133 #define GAMS_POSE_MAKE_COORDINATE_TYPE(name, units) \
1134 class name##Vector : \
1135  public BasicVector<name##Vector, units> \
1136 { \
1137 public: \
1138  using Base = BasicVector<name##Vector, units>; \
1139  using Base::Base; \
1140  static constexpr const char * type_name = #name "Vector"; \
1141 }; \
1142 \
1143 class name : \
1144  public Framed<BasicVector<name, units>> \
1145 { \
1146 public: \
1147  using Base = Framed<BasicVector<name, units>>; \
1148  using Base::Base; \
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()) {} \
1152  name() = default; \
1153 }; \
1154 \
1155 class Stamped##name : \
1156  public Stamped<Framed<BasicVector<Stamped##name, units>>> \
1157 { \
1158 public: \
1159  using Base = Stamped<Framed<BasicVector<Stamped##name, units>>>; \
1160  using Base::Base; \
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; \
1167 }
1168 
1172 class Position;
1173 
1178 class Position;
1179 
1183 class Velocity;
1184 
1188 class Accelerations;
1189 
1196 class Orientation;
1197 
1204 class Rotation;
1205 
1211 class AngularVelocity;
1212 
1218 class AngularAccelerations;
1219 
1224 
1229 
1230 template<>
1232 {
1234 };
1235 
1236 template<>
1238 {
1240 };
1241 
1242 template<>
1244 {
1246 };
1247 
1248 template<>
1250 {
1252 };
1253 
1254 template<>
1256 {
1257  using type = Rotation;
1258 };
1259 
1260 template<>
1262 {
1264 };
1265 
1266 inline std::ostream &operator<<(std::ostream &o, const Eigen::Vector3d &v)
1267 {
1268  bool first = true;
1269  for (int i = 0; i < v.size(); ++i)
1270  {
1271  auto x = v[i];
1272 
1273  if (!first) {
1274  o << ",";
1275  } else {
1276  first = false;
1277  }
1278 
1279  if (x != INVAL_COORD) {
1280  o << x;
1281  } else {
1282  o << "<unset>";
1283  }
1284  }
1285  return o;
1286 }
1287 
1288 template<typename Derived, typename Units>
1289 inline std::ostream &operator<<(std::ostream &o, const BasicVector<Derived, Units> &v)
1290 {
1291  o << Derived::type_name << "(";
1292  o << v.vec();
1293  o << ")";
1294  return o;
1295 }
1296 
1297 } }
1298 
1299 #endif
Copyright (c) 2015 Carnegie Mellon University.
Copyright (c) 2015 Carnegie Mellon University.
For internal use. The underlying template for all coordinate types.
Definition: Coordinate.h:528
double norm() const
Passthrough to Eigen vector norm method.
Definition: Coordinate.h:724
void to_array(ContainType &out) const
Outputs this Coordinates values to the referenced container.
Definition: Coordinate.h:616
static constexpr bool free()
Is this coordinate a free vector?
Definition: Coordinate.h:558
static constexpr bool fixed()
Is this coordinate a fixed vector?
Definition: Coordinate.h:561
bool is_set() const
Does this coordinate have any values not INVAL_COORD?
Definition: Coordinate.h:581
static constexpr bool positional()
Is this coordinate a positional one?
Definition: Coordinate.h:552
double get(size_t i) const
Get i'th value in this Coordinate.
Definition: Coordinate.h:569
static constexpr bool rotational()
Is this coordinate a rotational one?
Definition: Coordinate.h:555
void from_container(const madara::knowledge::containers::NativeDoubleVector &container)
Assign values from a NativeDoubleVector container.
Definition: Coordinate.h:693
void to_container(madara::knowledge::containers::NativeDoubleVector &container) const
Assign values into a NativeDoubleVector container.
Definition: Coordinate.h:681
size_t size() const
Get number of values in this coordinate.
Definition: Coordinate.h:564
Eigen::Vector3d vec_
Definition: Coordinate.h:530
void from_array(const ContainType &in)
Overwrites this Coordinate's values with those pulled from the referenced array.
Definition: Coordinate.h:637
double squaredNorm() const
Passthrough to Eigen vector squaredNorm method.
Definition: Coordinate.h:732
std::string to_string(const std::string &delimiter=",", const std::string &unset_identifier="<unset>") const
Returns a string of the values x, y, z.
Definition: Coordinate.h:651
BasicVector(const BasicVector< Derived2, Units > &v)
Construct from a vector of same units, but different derived type.
Definition: Coordinate.h:549
typename unit_traits< Units >::storage_mixin storage_mixin
Definition: Coordinate.h:533
double set(size_t i, double v)
Set i'th value in this Coordinate.
Definition: Coordinate.h:578
Derived cross(const BasicVector< Other, Units > &other) const
Passthrough to Eigen vector cross method.
Definition: Coordinate.h:714
Derived normalized() const
Passthrough to Eigen vector normalized method.
Definition: Coordinate.h:740
bool is_zero() const
Does this coordinate have values all zeroes?
Definition: Coordinate.h:592
double dot(const BasicVector< Other, Units > &other) const
Passthrough to Eigen vector dot method.
Definition: Coordinate.h:705
typename unit_traits< Units >::template mixin< Derived > mixin
Definition: Coordinate.h:534
Internal class implementing coordinates bound to reference frame.
Definition: Framed.h:108
Used internally to implement angle operations.
Definition: Quaternion.h:75
Internal class implementing coordinates stamped with timestamp.
Definition: Stamped.h:103
storage_mixin(double rx, double ry, double rz, Units units)
Definition: Coordinate.h:202
storage_mixin(const Eigen::Quaterniond &quat)
Construct from a Quaternion.
Definition: Coordinate.h:220
const Eigen::Vector3d & vec() const
Definition: Coordinate.h:158
storage_mixin(double x, double y, double z)
Definition: Coordinate.h:137
storage_mixin(const Eigen::Vector3d &vec)
Definition: Coordinate.h:145
storage_mixin(const madara::knowledge::containers::NativeDoubleVector &v)
Definition: Coordinate.h:152
storage_mixin(const madara::knowledge::containers::DoubleVector &v)
Definition: Coordinate.h:147
BaseAlgorithm Base
std::ostream & operator<<(std::ostream &o, const Eigen::Vector3d &v)
Definition: Coordinate.h:1266
bool operator>(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
Definition: Coordinate.h:1106
Eigen::Vector3d quat_to_axis_angle(const Eigen::Quaterniond &quat)
Definition: Coordinate.h:170
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.
Definition: Coordinate.h:876
bool operator<=(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
Definition: Coordinate.h:1058
bool operator==(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
Equality operator for coordinates.
Definition: Coordinate.h:936
bool operator<(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
Definition: Coordinate.h:1018
bool operator!=(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
Inequality operator for coordinates.
Definition: Coordinate.h:984
bool operator>=(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
Definition: Coordinate.h:1082
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.
Definition: Coordinate.h:902
gams::pose::Orientation Orientation
Represents a orientation or orientation within a reference frame.
Definition: Orientation.h:94
Contains all GAMS-related tools, classes and code.
#define INVAL_COORD
Definition: Coordinate.h:78
#define GAMS_POSE_MAKE_COORDINATE_TYPE(name, units)
Creates the three variants for each coordinate type: {Coordinate}Vector: just the coordinate values a...
Definition: Coordinate.h:1133
#define GAMS_POSE_MAKE_COMPOSITE_VECS_OP(op)
Generates Eigen passthroughs on vectors.
Definition: Coordinate.h:835
#define GAMS_POSE_MAKE_VEC_SCALAR_OPS(op)
Definition: Coordinate.h:827
void from_quat(const Eigen::Quaterniond &quat)
Definition: Coordinate.h:400
auto slerp(const Other &other, double scale) -> typename std::decay< decltype(other.into_quat(), std::declval< Derived >())>::type
Definition: Coordinate.h:414
auto slerp(double scale, const Other &other) -> typename std::decay< decltype(other.into_quat(), std::declval< Derived >())>::type
Definition: Coordinate.h:406
auto slerp_this(const Other &other, double scale) -> decltype(other.into_quat(), void())
Definition: Coordinate.h:429
Eigen::Quaterniond into_quat() const
Represent this rotation as a quaternion.
Definition: Coordinate.h:384
auto slerp_this(double scale, const Other &other) -> decltype(other.into_quat(), void())
Definition: Coordinate.h:422
double angle_to(const Derived &target, U u) const
Definition: Coordinate.h:359
double angle_to(const Derived &target) const
Definition: Coordinate.h:353
Helper struct for defining which fixed coordinate types map to which free vector coordinate types.
Definition: Coordinate.h:914
const Eigen::Vector3d & dis_vec() const
Definition: Coordinate.h:293
const Eigen::Vector3d & vel_vec() const
Definition: Coordinate.h:317
Helper trait to customize BasicVector based on unit.
Definition: Coordinate.h:118
Tag that coordinate is a fixed vector, not free.
Definition: Coordinate.h:86
Trait to strip absolute off a unit tag.
Definition: Coordinate.h:98
Trait to compare types, ignoring absolute.
Definition: Coordinate.h:112
Copyright (c) 2015 Carnegie Mellon University.