GAMS  1.4.0
ReferenceFrame.h
Go to the documentation of this file.
1 
54 #ifndef _GAMS_POSE_REFERENCE_FRAME_H_
55 #define _GAMS_POSE_REFERENCE_FRAME_H_
56 
57 #include "gams/GamsExport.h"
58 #include "gams/CPP11_compat.h"
59 #include <vector>
60 #include <string>
61 #include <cstring>
62 #include <sstream>
63 #include <utility>
64 #include <memory>
65 #include <stdexcept>
66 #include <mutex>
67 #include "ReferenceFrameFwd.h"
68 #include "CartesianFrame.h"
69 #include "Pose.h"
70 #include "Quaternion.h"
71 #include "madara/knowledge/EvalSettings.h"
73 
74 namespace gams { namespace pose {
75 
76 class ReferenceFrameVersion;
77 class ReferenceFrameIdentity;
78 
80 {
81 private:
82  std::map<std::string,
83  std::weak_ptr<ReferenceFrameIdentity>> idents_;
84 
85 public:
86  std::shared_ptr<ReferenceFrameIdentity> lookup(std::string id);
87 
88  std::shared_ptr<ReferenceFrameIdentity> find(std::string id) const;
89 
90  std::shared_ptr<ReferenceFrameIdentity> make_guid();
91 
96  void gc();
97 };
98 
106 {
107 public:
108  static const uint64_t ETERNAL = ReferenceFrame::ETERNAL;
109  static const uint64_t TEMP = ReferenceFrame::TEMP;
110 
111 private:
112  std::string id_;
113 
115  //static std::map<std::string,
116  //std::weak_ptr<ReferenceFrameIdentity>> idents_;
117 
118  static uint64_t default_expiry_;
119 
120  static std::recursive_mutex idents_lock_;
121 
122  mutable std::map<uint64_t, std::weak_ptr<ReferenceFrameVersion>>
124 
125  mutable uint64_t expiry_ = ETERNAL;
126 
127  mutable std::recursive_mutex versions_lock_;
128 
129 public:
131  ReferenceFrameIdentity(std::string id, uint64_t expiry)
132  : id_(std::move(id)), expiry_(expiry) {}
133 
134  static std::shared_ptr<ReferenceFrameIdentity> lookup(std::string id)
135  {
136  std::lock_guard<std::recursive_mutex> guard(idents_lock_);
137 
138  return arena_.lookup(std::move(id));
139  }
140 
141  static std::shared_ptr<ReferenceFrameIdentity> find(std::string id)
142  {
143  std::lock_guard<std::recursive_mutex> guard(idents_lock_);
144 
145  return arena_.find(std::move(id));
146  }
147 
148  static std::shared_ptr<ReferenceFrameIdentity> make_guid()
149  {
150  std::lock_guard<std::recursive_mutex> guard(idents_lock_);
151 
152  return arena_.make_guid();
153  }
154 
155  void register_version(uint64_t timestamp,
156  std::shared_ptr<ReferenceFrameVersion> ver) const
157  {
158  std::lock_guard<std::recursive_mutex> guard(versions_lock_);
159 
160  std::weak_ptr<ReferenceFrameVersion> weak(std::move(ver));
161  versions_[timestamp] = ver;
162  }
163 
164  std::shared_ptr<ReferenceFrameVersion> get_version(uint64_t timestamp) const
165  {
166  std::lock_guard<std::recursive_mutex> guard(versions_lock_);
167 
168  auto find = versions_.find(timestamp);
169 
170  if (find == versions_.end()) {
171  return nullptr;
172  }
173 
174  return find->second.lock();
175  }
176 
177  const std::string &id() const { return id_; }
178 
196  static uint64_t default_expiry(uint64_t age) {
197  std::lock_guard<std::recursive_mutex> guard(idents_lock_);
198 
199  uint64_t ret = default_expiry_;
200  default_expiry_ = age;
201  return ret;
202  }
203 
205  static uint64_t default_expiry() {
206  std::lock_guard<std::recursive_mutex> guard(idents_lock_);
207  return default_expiry_;
208  }
209 
224  uint64_t expiry(uint64_t age) const {
225  std::lock_guard<std::recursive_mutex> guard(versions_lock_);
226 
227  uint64_t ret = expiry_;
228  expiry_ = age;
229  return ret;
230  }
231 
233  uint64_t expiry() const {
234  std::lock_guard<std::recursive_mutex> guard(versions_lock_);
235  return expiry_;
236  }
237 
238  void expire_older_than(madara::knowledge::KnowledgeBase &kb,
239  uint64_t time, const FrameEvalSettings &settings = FrameEvalSettings::DEFAULT) const;
240 
241  static const std::string &default_prefix() {
242  std::lock_guard<std::recursive_mutex> guard(idents_lock_);
244  }
245 
250  static void gc()
251  {
252  std::lock_guard<std::recursive_mutex> guard(idents_lock_);
253 
254  return arena_.gc();
255  }
256 
257  void gc_versions();
258 };
259 
261 namespace impl {
262  inline static std::string &make_kb_key(
263  std::string &prefix,
264  const std::string &id)
265  {
266  prefix.reserve(prefix.capacity() + 1 + id.size());
267 
268  prefix += ".";
269  prefix += id;
270 
271  return prefix;
272  }
273 
274  inline static std::string &make_kb_key(
275  std::string &prefix, uint64_t timestamp)
276  {
277  if (timestamp == ReferenceFrameIdentity::ETERNAL) {
278  prefix += ".inf";
279  } else {
280  prefix += ".";
281 
282  std::ostringstream oss;
283  oss.fill('0');
284  oss.width(16);
285  oss << std::hex << timestamp;
286 
287  prefix += oss.str();
288  }
289 
290  return prefix;
291  }
292 
293  inline static std::string &make_kb_key(
294  std::string &prefix,
295  const std::string &id, uint64_t timestamp)
296  {
297  make_kb_key(prefix, id);
298  make_kb_key(prefix, timestamp);
299  return prefix;
300  }
301 }
302 
305  (x.nanos(), x.nanos(0UL)));
306 
308 inline uint64_t try_get_nano_time(uint64_t def)
309 {
310  return def;
311 }
312 
314 template<typename T, typename... Args>
315 inline auto try_get_nano_time(uint64_t, const T& v, Args&&...) ->
316  typename std::enable_if<supports_nano_timestamp<T>::value, uint64_t>::type
317 {
318  return v.nanos();
319 }
320 
322 template<typename T, typename... Args>
323 inline auto try_get_nano_time(uint64_t def, const T&, Args&&... args) ->
324  typename std::enable_if<!supports_nano_timestamp<T>::value, uint64_t>::type
325 {
326  return try_get_nano_time(def, std::forward<Args>(args)...);
327 }
328 
336  public std::enable_shared_from_this<ReferenceFrameVersion>
337 {
338 private:
339  mutable std::shared_ptr<ReferenceFrameIdentity> ident_;
341  uint64_t timestamp_ = ETERNAL;
343  mutable bool interpolated_ = false;
344  bool temp_ = false;
345 
346 private:
347  template<typename T>
348  static uint64_t init_timestamp(uint64_t given, const T &p)
349  {
350  if (given == ETERNAL) {
351  return try_get_nano_time(ETERNAL, p);
352  } else {
353  return given;
354  }
355  }
356 
357 public:
358  static const uint64_t ETERNAL = ReferenceFrameIdentity::ETERNAL;
359  static const uint64_t TEMP = ReferenceFrameIdentity::TEMP;
360 
370  template<typename P,
371  typename std::enable_if<
372  supports_transform_to<P>::value, void*>::type = nullptr>
374  P &&origin,
375  uint64_t timestamp = ETERNAL,
376  bool temp = false)
378  std::forward<P>(origin),
379  timestamp, temp) {}
380 
392  template<typename P,
393  typename std::enable_if<
394  supports_transform_to<P>::value, void*>::type = nullptr>
396  const ReferenceFrameType *type,
397  P &&origin,
398  uint64_t timestamp = ETERNAL,
399  bool temp = false)
400  : ReferenceFrameVersion({}, type,
401  std::forward<P>(origin), timestamp, temp) {}
402 
413  template<typename P,
414  typename std::enable_if<
415  supports_transform_to<P>::value, void*>::type = nullptr>
417  std::string name,
418  P &&origin,
419  uint64_t timestamp = ETERNAL,
420  bool temp = false)
422  ReferenceFrameIdentity::lookup(std::move(name)), Cartesian,
423  std::forward<P>(origin), timestamp, temp) {}
424 
436  template<typename P,
437  typename std::enable_if<
438  supports_transform_to<P>::value, void*>::type = nullptr>
440  const ReferenceFrameType *type,
441  std::string name,
442  P &&origin,
443  uint64_t timestamp = ETERNAL,
444  bool temp = false)
446  ReferenceFrameIdentity::lookup(std::move(name)), type,
447  std::forward<P>(origin), timestamp, temp) {}
448 
461  template<typename P,
462  typename std::enable_if<
463  supports_transform_to<P>::value, void*>::type = nullptr>
465  std::shared_ptr<ReferenceFrameIdentity> ident,
466  const ReferenceFrameType *type,
467  P &&origin,
468  uint64_t timestamp = ETERNAL,
469  bool temp = false)
470  : ident_(std::move(ident)),
471  type_(type),
472  timestamp_(init_timestamp(timestamp, origin)),
473  origin_(std::forward<P>(origin)),
474  temp_(temp) {}
475 
488  template<typename P,
489  typename std::enable_if<
490  supports_transform_to<P>::value, void*>::type = nullptr>
492  std::shared_ptr<ReferenceFrameIdentity> ident,
493  P &&origin,
494  uint64_t timestamp = ETERNAL,
495  bool temp = false)
496  : ReferenceFrameVersion(std::move(ident), Cartesian,
497  std::forward<P>(origin), timestamp, temp) {}
498 
503  const ReferenceFrameIdentity &ident() const {
504  if (!ident_) {
506  }
507  return *ident_;
508  }
509 
517  const ReferenceFrameType *type() const { return type_; }
518 
526  const Pose &origin() const {
527  return origin_;
528  }
529 
538  return origin_;
539  }
540 
547  ReferenceFrame pose(Pose new_origin) const {
548  return pose(new_origin, timestamp_);
549  }
550 
557  ReferenceFrame move(Position new_origin) const {
558  return move(new_origin, timestamp_);
559  }
560 
567  ReferenceFrame orient(Orientation new_origin) const {
568  return orient(new_origin, timestamp_);
569  }
570 
578  ReferenceFrame pose(const Pose &new_origin, uint64_t timestamp) const {
579  return ReferenceFrame(std::make_shared<ReferenceFrameVersion>(
580  ident_, type(), new_origin, timestamp));
581  }
582 
590  ReferenceFrame move(const Position &new_origin,
591  uint64_t timestamp) const {
592  return pose(Pose(new_origin, Orientation(origin_)), timestamp);
593  }
594 
602  ReferenceFrame orient(const Orientation &new_origin,
603  uint64_t timestamp) const {
604  return pose(Pose(Position(origin_), new_origin), timestamp);
605  }
606 
612  return origin_.frame();
613  }
614 
622  bool operator==(const ReferenceFrame &other) const;
623 
631  bool operator!=(const ReferenceFrame &other) const;
632 
640  bool operator==(const ReferenceFrameVersion &other) const;
641 
649  bool operator!=(const ReferenceFrameVersion &other) const;
650 
656  const char *name() const {
657  return type()->name;
658  }
659 
665  const std::string &id() const {
666  return ident().id();
667  }
668 
677  bool has_id() const {
678  return (bool)ident_;
679  }
680 
688  const std::string *id_ptr() const {
689  return has_id() ? nullptr : &id();
690  }
691 
695  uint64_t timestamp() const {
696  return timestamp_;
697  }
698 
704  ReferenceFrame timestamp(uint64_t timestamp) const {
705  return ReferenceFrame(std::make_shared<ReferenceFrameVersion>(
706  ident_, type(), origin(), timestamp));
707  }
708 
714  bool interpolated() const {
715  return interpolated_;
716  }
717 
722  bool temp() const {
723  return temp_;
724  }
725 
726  static const std::string &default_prefix() {
728  }
729 
733  std::string key(const FrameEvalSettings &settings = FrameEvalSettings::DEFAULT) const {
734  std::string prefix = settings.prefix();
735  impl::make_kb_key(prefix, id(), timestamp());
736  return prefix;
737  }
738 
748  void save(madara::knowledge::KnowledgeBase &kb,
749  uint64_t expiry,
750  const FrameEvalSettings &settings = FrameEvalSettings::DEFAULT) const {
751  std::string key = this->key(settings);
752  save_as(kb, std::move(key), expiry, settings);
753  }
754 
763  void save(madara::knowledge::KnowledgeBase &kb,
764  const FrameEvalSettings &settings = FrameEvalSettings::DEFAULT) const {
765  std::string key = this->key(settings);
766  save_as(kb, std::move(key), settings);
767  }
768 
784  madara::knowledge::KnowledgeBase &kb,
785  const std::string &id,
786  uint64_t timestamp = ETERNAL,
787  uint64_t parent_timestamp = ETERNAL,
789  bool throw_on_errors = true,
790  ReferenceFrameArena* arena = nullptr);
791 
792 private:
808  madara::knowledge::KnowledgeBase &kb,
809  const std::string &id,
810  uint64_t timestamp = ETERNAL,
811  uint64_t parent_timestamp = ETERNAL,
813  bool throw_on_errors = true,
814  ReferenceFrameArena* arena = nullptr);
815 
816 public:
830  madara::knowledge::KnowledgeBase &kb,
831  const std::string &id,
832  uint64_t timestamp = ETERNAL,
834  bool throw_on_errors = true,
835  ReferenceFrameArena* arena = nullptr);
836 
847  static uint64_t latest_timestamp(
848  madara::knowledge::KnowledgeBase &kb,
849  const std::string &id,
851 
852 private:
853  using ancestor_elem = std::pair<std::string, uint64_t>;
854  using ancestor_vec = std::vector<ancestor_elem>;
855 
856  static std::pair<uint64_t, uint64_t> find_nearest_neighbors(
857  madara::knowledge::KnowledgeBase &kb, const std::string &id,
858  uint64_t timestamp, const FrameEvalSettings &settings);
859 
861  madara::knowledge::KnowledgeBase &kb,
862  std::string name,
864 
866  const std::vector<ancestor_vec> &stamps);
867 
868 public:
882  template<typename InputIterator>
883  static uint64_t latest_common_timestamp(
884  madara::knowledge::KnowledgeBase &kb,
885  InputIterator begin,
886  InputIterator end,
888  {
889  if (begin == end) {
890  return 0UL - 1;
891  }
892 
893  std::vector<ancestor_vec> stamps;
894 
895  if (std::is_same<
896  typename std::iterator_traits<InputIterator>::iterator_category,
897  std::random_access_iterator_tag>::value) {
898  size_t count = std::distance(begin, end);
899 
900  if (count == 1) {
901  madara::knowledge::ContextGuard guard(kb);
902 
903  return find_nearest_neighbors(kb, *begin, -1, settings).first;
904  }
905 
906  stamps.reserve(count);
907  }
908 
909  {
910  madara::knowledge::ContextGuard guard(kb);
911 
912  InputIterator cur = begin;
913  while (cur != end) {
914  stamps.emplace_back(get_ancestry(kb, *cur, settings));
915  ++cur;
916  }
917  }
918 
919  return find_common_timestamp_to_first_ancestor(stamps);
920  }
921 
934  template<typename Container>
935  static uint64_t latest_common_timestamp(
936  madara::knowledge::KnowledgeBase &kb,
937  const Container &ids,
939  {
940  madara::knowledge::ContextGuard guard(kb);
941 
942  return latest_common_timestamp(kb, ids.cbegin(), ids.cend(),
943  settings);
944  }
945 
962  template<typename ForwardIterator>
963  static std::vector<ReferenceFrame> load_tree(
964  madara::knowledge::KnowledgeBase &kb,
965  ForwardIterator begin,
966  ForwardIterator end,
967  uint64_t timestamp = ETERNAL,
969  ReferenceFrameArena* arena = nullptr)
970  {
971  std::vector<ReferenceFrame> ret;
972  if (std::is_same<
973  typename std::iterator_traits<ForwardIterator>::iterator_category,
974  std::random_access_iterator_tag>::value) {
975  size_t count = std::distance(begin, end);
976  ret.reserve(count);
977  }
978 
979  madara::knowledge::ContextGuard guard(kb);
980 
981  if (timestamp == ETERNAL) {
982  timestamp = latest_common_timestamp(kb, begin, end, settings);
983  }
984 
985  ReferenceFrameArena local_arena;
986  if (arena == nullptr) {
987  arena = &local_arena;
988  }
989 
990  while (begin != end) {
991  ReferenceFrame frame = load(kb, *begin, timestamp, settings, arena);
992  if (!frame.valid()) {
993  std::stringstream msg;
994  msg << "ReferenceFrame::load_tree: could not find frame \"" <<
995  *begin << "\" at timestamp " << timestamp << std::endl;
996  throw exceptions::ReferenceFrameException(msg.str());
997  }
998  ret.push_back(frame);
999  ++begin;
1000  }
1001  throw_if_not_connected(ret);
1002  return ret;
1003  }
1004 
1005  static bool check_is_connected(const std::vector<ReferenceFrame> &frames);
1006  static void throw_if_not_connected(const std::vector<ReferenceFrame> &frames);
1007 
1024  template<typename Container>
1025  static std::vector<ReferenceFrame> load_tree(
1026  madara::knowledge::KnowledgeBase &kb, const Container &ids,
1027  uint64_t timestamp = ETERNAL,
1029  ReferenceFrameArena* arena = nullptr)
1030  {
1031  return load_tree(kb, ids.begin(), ids.end(),
1032  timestamp, std::move(settings), arena);
1033  }
1034 
1043  void save_as(madara::knowledge::KnowledgeBase &kb,
1044  std::string key, uint64_t expiry,
1045  const FrameEvalSettings &settings = FrameEvalSettings::DEFAULT) const;
1053  void save_as(madara::knowledge::KnowledgeBase &kb,
1054  std::string key,
1055  const FrameEvalSettings &settings = FrameEvalSettings::DEFAULT) const
1056  {
1057  save_as(kb, key, ident().expiry(), settings);
1058  }
1059 
1071  ReferenceFrame interpolate(const ReferenceFrame &other, ReferenceFrame parent, uint64_t time) const
1072  {
1073  //std::cerr << "Interpolate has_id: " << has_id() << std::endl;
1074  if (has_id()) {
1075  auto ret = ident().get_version(time);
1076  if (ret) {
1077  return ret;
1078  }
1079  }
1080  double fraction = (time - timestamp()) / (double)(other.timestamp() - timestamp());
1081 
1082  Pose interp = origin();
1083  const Pose &opose = other.origin();
1084 
1085  interp.frame(std::move(parent));
1086 
1087  interp.x((fraction * (opose.x() - interp.x())) + interp.x());
1088  interp.y((fraction * (opose.y() - interp.y())) + interp.y());
1089  interp.z((fraction * (opose.z() - interp.z())) + interp.z());
1090 
1091  Quaternion iq(origin().as_orientation_vec());
1092  Quaternion oq(opose.as_orientation_vec());
1093 
1094  iq.slerp_this(oq, fraction);
1096 
1097  //std::cerr << "Interp " << fraction << " " << origin() << " " << interp << " " << opose << std::endl;
1098 
1099  auto ret = std::make_shared<ReferenceFrameVersion>(
1100  ident_, type(), std::move(interp), time);
1101 
1102  if (has_id()) {
1103  ident().register_version(time, ret);
1104  }
1105 
1106  ret->interpolated_ = true;
1107  return ret;
1108  }
1109 
1110  template<typename CoordType>
1111  friend class Coordinate;
1112 
1113 private:
1114  bool check_consistent() const;
1115 };
1116 
1124 private:
1125  /*
1126  * KnowledgeBase uses const to indicate not changing the underlying
1127  * KnowledgeBaseImpl, as well as itself. We won't be changing the
1128  * KnowledgeBase object itself, and will only call thread-safe methods.
1129  */
1130  mutable madara::knowledge::KnowledgeBase kb_;
1131 
1133  uint64_t expiry_;
1134 
1135 public:
1136  static const uint64_t ETERNAL = ReferenceFrameIdentity::ETERNAL;
1137  static const uint64_t TEMP = ReferenceFrameIdentity::TEMP;
1138 
1146  FrameStore(madara::knowledge::KnowledgeBase kb,
1147  FrameEvalSettings settings, uint64_t expiry)
1148  : kb_(std::move(kb)), settings_(std::move(settings)), expiry_(expiry) {}
1149 
1157  FrameStore(madara::knowledge::KnowledgeBase kb, FrameEvalSettings settings)
1158  : FrameStore(std::move(kb), std::move(settings),
1159  ReferenceFrame::default_expiry()) {}
1160 
1168  FrameStore(madara::knowledge::KnowledgeBase kb, uint64_t expiry)
1169  : FrameStore(std::move(kb), FrameEvalSettings::DEFAULT, expiry) {}
1170 
1171 
1179  FrameStore(madara::knowledge::KnowledgeBase kb)
1180  : FrameStore(std::move(kb), FrameEvalSettings::DEFAULT,
1181  ReferenceFrame::default_expiry()) {}
1182 
1185  uint64_t expiry() const { return expiry_; }
1186 
1188  const FrameEvalSettings &settings() const { return settings_; }
1189 
1191  const madara::knowledge::KnowledgeBase &kb() const { return kb_; }
1192 
1201  void save(const ReferenceFrame &frame) const {
1202  return frame.save(kb_, expiry_, settings_);
1203  }
1204 
1216  ReferenceFrame load(const std::string &id, uint64_t timestamp = ETERNAL) {
1217  return ReferenceFrame::load(kb_, id, timestamp, settings_);
1218  }
1219 
1236  template<typename InputIterator>
1237  std::vector<ReferenceFrame> load_tree(
1238  InputIterator begin,
1239  InputIterator end,
1240  uint64_t timestamp = ETERNAL) const {
1241  return ReferenceFrame::load_tree(kb_, begin, end, timestamp, settings_);
1242  }
1243 
1260  template<typename Container>
1261  std::vector<ReferenceFrame> load_tree(
1262  const Container &ids,
1263  uint64_t timestamp = ETERNAL) const {
1264  return ReferenceFrame::load_tree(kb_, ids, timestamp, settings_);
1265  }
1266 };
1267 
1277  const ReferenceFrame *from,
1278  const ReferenceFrame *to,
1279  std::vector<const ReferenceFrame *> *to_stack = nullptr);
1280 
1285 class unrelated_frames : public std::runtime_error
1286 {
1287 public:
1296 
1299 };
1300 
1312 class undefined_transform : public std::runtime_error
1313 {
1314 public:
1326  const ReferenceFrameType *parent_frame,
1327  const ReferenceFrameType *child_frame,
1328  bool is_child_to_parent,
1329  bool unsupported_angular = false);
1331 
1332  const ReferenceFrameType *parent_frame;
1333  const ReferenceFrameType *child_frame;
1334  bool is_child_to_parent;
1335  bool unsupported_angular;
1336 };
1337 
1346 namespace simple_rotate {
1359  double &x, double &y, double &z,
1360  double rx, double ry, double rz,
1361  bool reverse = false);
1362 
1376  const ReferenceFrameType *origin,
1377  const ReferenceFrameType *self,
1378  double orx, double ory, double orz,
1379  double &rx, double &ry, double &rz);
1380 
1394  const ReferenceFrameType *origin,
1395  const ReferenceFrameType *self,
1396  double orx, double ory, double orz,
1397  double &rx, double &ry, double &rz);
1398 
1416  const ReferenceFrameType *origin,
1417  const ReferenceFrameType *self,
1418  double ox, double oy, double oz,
1419  double orx, double ory, double orz,
1420  double &x, double &y, double &z,
1421  double &rx, double &ry, double &rz,
1422  bool fixed);
1423 
1444  const ReferenceFrameType *origin,
1445  const ReferenceFrameType *self,
1446  double ox, double oy, double oz,
1447  double orx, double ory, double orz,
1448  double &x, double &y, double &z,
1449  double &rx, double &ry, double &rz,
1450  bool fixed);
1451 
1464  double calc_angle(
1465  const ReferenceFrameType *self,
1466  double rx1, double ry1, double rz1,
1467  double rx2, double ry2, double rz2);
1468 }
1469 
1474  const ReferenceFrameType *,
1475  double &, double &, double &) {}
1476 
1481  const ReferenceFrameType *,
1482  double &, double &, double &) {}
1483 
1497  const ReferenceFrameType *self,
1498  double &x, double &y, double &z,
1499  double &rx, double &ry, double &rz)
1500 {
1501  self->normalize_linear(self, x, y, z);
1502  self->normalize_angular(self, rx, ry, rz);
1503 }
1504 
1505 } }
1506 
1507 #include "ReferenceFrame.inl"
1508 
1509 #endif
#define GAMS_EXPORT
Definition: GamsExport.h:20
An exception class for ReferenceFrame errors subclassed from GamsException.
OrientationVector & as_orientation_vec()
Gets a reference to this object's Orientation part.
Settings class for saving/loading reference frames.
static const FrameEvalSettings DEFAULT
static const std::string & default_prefix()
Get default prefix for all FrameEvalSettings that don't have another prefix set.
Class for storing and loading frames in a given KnowledgeBase, using given settings,...
FrameStore(madara::knowledge::KnowledgeBase kb, FrameEvalSettings settings)
Constructor for FrameStore Uses ReferenceFrame::default_expiry() for expiration.
FrameStore(madara::knowledge::KnowledgeBase kb)
Constructor for FrameStore Uses default FrameEvalSettings Uses ReferenceFrame::default_expiry() for e...
const FrameEvalSettings & settings() const
Return the current settings for frames saved/loaded with this FrameStore.
madara::knowledge::KnowledgeBase kb_
uint64_t expiry() const
Return the current expiry for all frames saved with this FrameStore See ReferenceFrame::expiry(uint64...
std::vector< ReferenceFrame > load_tree(InputIterator begin, InputIterator end, uint64_t timestamp=ETERNAL) const
Load ReferenceFrames, by ID, and their common ancestors.
void save(const ReferenceFrame &frame) const
Save a ReferenceFrame to the knowledge base, The saved frames will be marked with their timestamp for...
std::vector< ReferenceFrame > load_tree(const Container &ids, uint64_t timestamp=ETERNAL) const
Load ReferenceFrames, by ID, and their common ancestors.
FrameStore(madara::knowledge::KnowledgeBase kb, uint64_t expiry)
Constructor for FrameStore Uses default FrameEvalSettings.
const madara::knowledge::KnowledgeBase & kb() const
Return the KnowledgeBase to load/save with this FrameStore.
FrameStore(madara::knowledge::KnowledgeBase kb, FrameEvalSettings settings, uint64_t expiry)
Primary constructor for FrameStore.
ReferenceFrame load(const std::string &id, uint64_t timestamp=ETERNAL)
Load a single ReferenceFrame, by ID.
const ReferenceFrame & frame() const
Getter for the ReferenceFrame this Coordinate belongs to.
Definition: Framed.h:179
Used internally to implement angle operations.
Definition: Quaternion.h:75
void to_angular_vector(double &rx, double &ry, double &rz) const
void slerp_this(const Quaternion &o, double t)
If *this and o are unit quaternions, interpolate a quaternion that is partially between them,...
std::shared_ptr< ReferenceFrameIdentity > find(std::string id) const
std::shared_ptr< ReferenceFrameIdentity > lookup(std::string id)
std::map< std::string, std::weak_ptr< ReferenceFrameIdentity > > idents_
void gc()
Old versions of frames can remain loaded in memory after they are no longer needed.
std::shared_ptr< ReferenceFrameIdentity > make_guid()
static uint64_t default_expiry(uint64_t age)
Set the default expiry value for new frames IDs.
static ReferenceFrameArena arena_
uint64_t expiry() const
Return the current expiry.
static std::shared_ptr< ReferenceFrameIdentity > find(std::string id)
static void gc()
Old versions of frames can remain loaded in memory after they are no longer needed.
uint64_t expiry(uint64_t age) const
If a frame newer than this time is saved, expire saved frames of the same ID older than this duration...
static std::shared_ptr< ReferenceFrameIdentity > make_guid()
void expire_older_than(madara::knowledge::KnowledgeBase &kb, uint64_t time, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT) const
static std::recursive_mutex idents_lock_
static std::shared_ptr< ReferenceFrameIdentity > lookup(std::string id)
static const std::string & default_prefix()
std::map< uint64_t, std::weak_ptr< ReferenceFrameVersion > > versions_
std::recursive_mutex versions_lock_
static uint64_t default_expiry()
Return the default expiry for new frame IDs.
const std::string & id() const
void register_version(uint64_t timestamp, std::shared_ptr< ReferenceFrameVersion > ver) const
std::shared_ptr< ReferenceFrameVersion > get_version(uint64_t timestamp) const
ReferenceFrameIdentity(std::string id, uint64_t expiry)
Public by necessity. Use lookup instead.
bool interpolated() const
Returns true if this frame was interpolated from two stored frames.
ReferenceFrameVersion(const ReferenceFrameType *type, P &&origin, uint64_t timestamp=ETERNAL, bool temp=false)
Constructor from a type, an origin, and optional timestamp.
static uint64_t latest_common_timestamp(madara::knowledge::KnowledgeBase &kb, const Container &ids, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT)
Get the latest available timestamp in the knowledge base common to all the given ids.
std::shared_ptr< ReferenceFrameIdentity > ident_
ReferenceFrame origin_frame() const
Gets the parent frame (the one the origin is within).
ReferenceFrameVersion(std::shared_ptr< ReferenceFrameIdentity > ident, P &&origin, uint64_t timestamp=ETERNAL, bool temp=false)
Constructor from an existing ReferenceFrameIdentity, an origin, and optional timestamp.
ReferenceFrame orient(const Orientation &new_origin, uint64_t timestamp) const
Creates a new ReferenceFrame with modified origin and timestamp.
static std::pair< uint64_t, uint64_t > find_nearest_neighbors(madara::knowledge::KnowledgeBase &kb, const std::string &id, uint64_t timestamp, const FrameEvalSettings &settings)
const std::string & id() const
Get the ID string of this frame.
bool operator==(const ReferenceFrameVersion &other) const
Equality operator.
static uint64_t find_common_timestamp_to_first_ancestor(const std::vector< ancestor_vec > &stamps)
ReferenceFrameVersion(const ReferenceFrameType *type, std::string name, P &&origin, uint64_t timestamp=ETERNAL, bool temp=false)
Constructor from a type, id, an origin, and optional timestamp.
const ReferenceFrameType * type_
ReferenceFrame move(const Position &new_origin, uint64_t timestamp) const
Creates a new ReferenceFrame with modified origin and timestamp.
ReferenceFrame orient(Orientation new_origin) const
Creates a new ReferenceFrame with modified origin.
static ReferenceFrame load_exact_internal(madara::knowledge::KnowledgeBase &kb, const std::string &id, uint64_t timestamp=ETERNAL, uint64_t parent_timestamp=ETERNAL, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT, bool throw_on_errors=true, ReferenceFrameArena *arena=nullptr)
Load a single ReferenceFrame, by ID and timestamp.
static ReferenceFrame load(madara::knowledge::KnowledgeBase &kb, const std::string &id, uint64_t timestamp=ETERNAL, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT, bool throw_on_errors=true, ReferenceFrameArena *arena=nullptr)
Load a single ReferenceFrame, by ID and timestamp, interpolated if applicable.
static std::vector< ReferenceFrame > load_tree(madara::knowledge::KnowledgeBase &kb, ForwardIterator begin, ForwardIterator end, uint64_t timestamp=ETERNAL, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT, ReferenceFrameArena *arena=nullptr)
Load ReferenceFrames, by ID, and their common ancestors.
ReferenceFrame timestamp(uint64_t timestamp) const
Clone the this frame, but with new timestamp.
std::string key(const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT) const
Returns the key that save() will use to store this frame.
static void throw_if_not_connected(const std::vector< ReferenceFrame > &frames)
bool operator!=(const ReferenceFrame &other) const
Inequality operator.
std::pair< std::string, uint64_t > ancestor_elem
bool operator==(const ReferenceFrame &other) const
Equality operator.
static const std::string & default_prefix()
static bool check_is_connected(const std::vector< ReferenceFrame > &frames)
std::vector< ancestor_elem > ancestor_vec
ReferenceFrame move(Position new_origin) const
Creates a new ReferenceFrame with modified origin.
uint64_t timestamp() const
Get the timestamp assigned to this frame.
ReferenceFrameVersion(std::string name, P &&origin, uint64_t timestamp=ETERNAL, bool temp=false)
Constructor from a id, an origin, and optional timestamp.
static ancestor_vec get_ancestry(madara::knowledge::KnowledgeBase &kb, std::string name, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT)
ReferenceFrame pose(Pose new_origin) const
Creates a new ReferenceFrame with modified origin.
ReferenceFrameVersion(P &&origin, uint64_t timestamp=ETERNAL, bool temp=false)
Constructor from an origin, and optional timestamp.
ReferenceFrame interpolate(const ReferenceFrame &other, ReferenceFrame parent, uint64_t time) const
Interpolate a frame between the given frame; use the given parent.
void save(madara::knowledge::KnowledgeBase &kb, uint64_t expiry, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT) const
Save this ReferenceFrame to the knowledge base, The saved frames will be marked with their timestamp ...
ReferenceFrameVersion(std::shared_ptr< ReferenceFrameIdentity > ident, const ReferenceFrameType *type, P &&origin, uint64_t timestamp=ETERNAL, bool temp=false)
Constructor from an existing ReferenceFrameIdentity, an origin, and optional timestamp.
void save(madara::knowledge::KnowledgeBase &kb, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT) const
Save this ReferenceFrame to the knowledge base, The saved frames will be marked with their timestamp ...
Pose & mut_origin()
Gets the origin of this Frame.
const Pose & origin() const
Gets the origin of this Frame.
const ReferenceFrameType * type() const
Retrieve the frame type object for this frame.
bool operator!=(const ReferenceFrameVersion &other) const
Inequality operator.
static uint64_t latest_common_timestamp(madara::knowledge::KnowledgeBase &kb, InputIterator begin, InputIterator end, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT)
Get the latest available timestamp in the knowledge base common to all the given ids.
const char * name() const
Returns a human-readable name for the reference frame type.
static std::vector< ReferenceFrame > load_tree(madara::knowledge::KnowledgeBase &kb, const Container &ids, uint64_t timestamp=ETERNAL, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT, ReferenceFrameArena *arena=nullptr)
Load ReferenceFrames, by ID, and their common ancestors.
const std::string * id_ptr() const
Get the ID string of this frame.
static ReferenceFrame load_exact(madara::knowledge::KnowledgeBase &kb, const std::string &id, uint64_t timestamp=ETERNAL, uint64_t parent_timestamp=ETERNAL, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT, bool throw_on_errors=true, ReferenceFrameArena *arena=nullptr)
Load a single ReferenceFrame, by ID and timestamp.
ReferenceFrame pose(const Pose &new_origin, uint64_t timestamp) const
Creates a new ReferenceFrame with modified origin and timestamp.
static uint64_t latest_timestamp(madara::knowledge::KnowledgeBase &kb, const std::string &id, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT)
Get the latest available timestamp in the knowledge base for the given id.
void save_as(madara::knowledge::KnowledgeBase &kb, std::string key, uint64_t expiry, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT) const
Save this ReferenceFrame to the knowledge base, with a specific key value.
const ReferenceFrameIdentity & ident() const
Get the ReferenceFrameIdentity object associated with this frame, creating one with random ID if none...
bool has_id() const
Does this frame have an ID? Frames gain an ID either at construction, or lazily as needed (by having ...
bool temp() const
Returns true if this frame is a temporary; one invented to serve as root of a frame tree.
void save_as(madara::knowledge::KnowledgeBase &kb, std::string key, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT) const
Save this ReferenceFrame to the knowledge base, with a specific key value.
static uint64_t init_timestamp(uint64_t given, const T &p)
Provides Reference Frame (i.e., coordinate systemm) transforms.
uint64_t timestamp() const
Get the timestamp assigned to this frame.
static const uint64_t ETERNAL
static const uint64_t TEMP
static ReferenceFrame load(madara::knowledge::KnowledgeBase &kb, const std::string &id, uint64_t timestamp=ETERNAL, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT)
Load a single ReferenceFrame, by ID.
bool valid() const
Test whether this frame is valid.
void save(madara::knowledge::KnowledgeBase &kb, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT) const
Save this ReferenceFrame to the knowledge base, The saved frames will be marked with their timestamp ...
static std::vector< ReferenceFrame > load_tree(madara::knowledge::KnowledgeBase &kb, InputIterator begin, InputIterator end, uint64_t timestamp=ETERNAL, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT, ReferenceFrameArena *arena=nullptr)
Load ReferenceFrames, by ID, and their common ancestors.
const Pose & origin() const
Gets the origin of this Frame.
Thrown when an attempt is made to transform between two frame types, and there's not transform define...
undefined_transform(const ReferenceFrameType *parent_frame, const ReferenceFrameType *child_frame, bool is_child_to_parent, bool unsupported_angular=false)
The only Constructor.
Thrown when an an attempt is made to transform between frames that do not belong to the same frame tr...
unrelated_frames(ReferenceFrame from_frame, ReferenceFrame to_frame)
The only Constructor.
static std::string & make_kb_key(std::string &prefix, const std::string &id)
double calc_angle(const ReferenceFrameType *self, double rx1, double ry1, double rz1, double rx2, double ry2, double rz2)
Calculates smallest angle between two AngularVectors.
void transform_angular_to_origin(const ReferenceFrameType *origin, const ReferenceFrameType *self, double orx, double ory, double orz, double &rx, double &ry, double &rz)
Transform AngularVector in-place into its origin frame from this frame.
void transform_pose_to_origin(const ReferenceFrameType *origin, const ReferenceFrameType *self, double ox, double oy, double oz, double orx, double ory, double orz, double &x, double &y, double &z, double &rx, double &ry, double &rz, bool fixed)
Transform pose in-place into its origin frame from this frame.
void orient_linear_vec(double &x, double &y, double &z, double rx, double ry, double rz, bool reverse=false)
Rotates a LinearVector according to a AngularVector.
void transform_angular_from_origin(const ReferenceFrameType *origin, const ReferenceFrameType *self, double orx, double ory, double orz, double &rx, double &ry, double &rz)
Transform AngularVector in-place from its origin frame.
void transform_pose_from_origin(const ReferenceFrameType *origin, const ReferenceFrameType *self, double ox, double oy, double oz, double orx, double ory, double orz, double &x, double &y, double &z, double &rx, double &ry, double &rz, bool fixed)
Transform pose in-place from its origin frame Simply applies linear and angular transforms independan...
GAMS_EXPORT const ReferenceFrame * find_common_frame(const ReferenceFrame *from, const ReferenceFrame *to, std::vector< const ReferenceFrame * > *to_stack=nullptr)
Helper function to find the common frame between two frames.
void default_normalize_linear(const ReferenceFrameType *, double &, double &, double &)
Returns a default normalized positional.
GAMS_EXPORT const ReferenceFrameType * Cartesian
ReferenceFrameType struct for Cartesian frames.
void default_normalize_angular(const ReferenceFrameType *, double &, double &, double &)
Returns a default normalized angular.
void default_normalize_pose(const ReferenceFrameType *self, double &x, double &y, double &z, double &rx, double &ry, double &rz)
Returns a default normalized pose.
MADARA_MAKE_VAL_SUPPORT_TEST(nano_timestamp, x,(x.nanos(), x.nanos(0UL)))
Type trait to detect stamped types.
uint64_t try_get_nano_time(uint64_t def)
Base case: return default.
gams::pose::Orientation Orientation
Represents a orientation or orientation within a reference frame.
Definition: Orientation.h:94
gams::pose::ReferenceFrame ReferenceFrame
Base class for Reference Frames.
gams::pose::Coordinate< CoordType > Coordinate
New coordinate types which are frame-dependant can inherit from this class.
Definition: Coordinate.h:137
gams::pose::Pose Pose
Represents a combination of Location and Orientation within a single reference frame.
Definition: Pose.h:79
Contains all GAMS-related tools, classes and code.
Copyright (c) 2015 Carnegie Mellon University.
Copyright (c) 2015 Carnegie Mellon University.
Copyright (c) 2015 Carnegie Mellon University.