54 #ifndef _GAMS_POSE_REFERENCE_FRAME_H_ 55 #define _GAMS_POSE_REFERENCE_FRAME_H_ 71 #include "madara/knowledge/EvalSettings.h" 73 namespace gams {
namespace pose {
75 class ReferenceFrameVersion;
88 static std::map<std::string,
89 std::weak_ptr<ReferenceFrameIdentity>>
idents_;
95 mutable std::map<uint64_t, std::weak_ptr<ReferenceFrameVersion>>
98 mutable uint64_t expiry_ = -1;
105 : id_(
std::move(id)), expiry_(expiry) {}
107 static std::shared_ptr<ReferenceFrameIdentity> lookup(std::string
id);
109 static std::shared_ptr<ReferenceFrameIdentity> find(std::string
id);
111 static std::shared_ptr<ReferenceFrameIdentity> make_guid();
114 std::shared_ptr<ReferenceFrameVersion> ver)
const 116 std::lock_guard<std::mutex> guard(versions_lock_);
118 std::weak_ptr<ReferenceFrameVersion> weak(std::move(ver));
119 versions_[timestamp] = ver;
122 std::shared_ptr<ReferenceFrameVersion>
get_version(uint64_t timestamp)
const 124 std::lock_guard<std::mutex> guard(versions_lock_);
126 auto find = versions_.find(timestamp);
128 if (find == versions_.end()) {
132 return find->second.lock();
135 const std::string &
id()
const {
return id_; }
155 std::lock_guard<std::mutex> guard(idents_lock_);
157 uint64_t ret = default_expiry_;
158 default_expiry_ = age;
164 std::lock_guard<std::mutex> guard(idents_lock_);
165 return default_expiry_;
183 std::lock_guard<std::mutex> guard(versions_lock_);
185 uint64_t ret = expiry_;
192 std::lock_guard<std::mutex> guard(versions_lock_);
196 void expire_older_than(madara::knowledge::KnowledgeBase &kb,
214 const std::string &
id)
216 prefix.reserve(prefix.capacity() + 1 +
id.size());
225 std::string &prefix, uint64_t timestamp)
227 if (timestamp == (uint64_t)-1) {
232 std::ostringstream oss;
235 oss << std::hex << timestamp;
245 const std::string &
id, uint64_t timestamp)
255 (x.nanos(), x.nanos(0UL)));
264 template<
typename T,
typename... Args>
266 typename std::enable_if<supports_nano_timestamp<T>::value, uint64_t>::type
272 template<
typename T,
typename... Args>
274 typename std::enable_if<!supports_nano_timestamp<T>::value, uint64_t>::type
286 public std::enable_shared_from_this<ReferenceFrameVersion>
289 mutable std::shared_ptr<ReferenceFrameIdentity>
ident_;
291 uint64_t timestamp_ = -1;
293 mutable bool interpolated_ =
false;
299 if (given == (uint64_t)-1) {
317 typename std::enable_if<
318 supports_transform_to<P>::value,
void*>::type =
nullptr>
321 uint64_t timestamp = -1)
323 std::forward<P>(origin),
338 typename std::enable_if<
339 supports_transform_to<P>::value,
void*>::type =
nullptr>
343 uint64_t timestamp = -1)
345 std::forward<P>(origin), timestamp) {}
358 typename std::enable_if<
359 supports_transform_to<P>::value,
void*>::type =
nullptr>
363 uint64_t timestamp = -1)
366 std::forward<P>(origin), timestamp) {}
380 typename std::enable_if<
381 supports_transform_to<P>::value,
void*>::type =
nullptr>
386 uint64_t timestamp = -1)
389 std::forward<P>(origin), timestamp) {}
404 typename std::enable_if<
405 supports_transform_to<P>::value,
void*>::type =
nullptr>
407 std::shared_ptr<ReferenceFrameIdentity> ident,
410 uint64_t timestamp = -1)
411 : ident_(
std::move(ident)),
413 timestamp_(init_timestamp(timestamp, origin)),
414 origin_(
std::forward<P>(origin)) {}
465 return pose(new_origin, timestamp_);
475 return move(new_origin, timestamp_);
485 return orient(new_origin, timestamp_);
497 ident_, type(), new_origin, timestamp));
508 uint64_t timestamp)
const {
520 uint64_t timestamp)
const {
521 return pose(
Pose(
Position(origin_), new_origin), timestamp);
529 return origin_.
frame();
582 const std::string &
id()
const {
606 return has_id() ?
nullptr : &id();
623 ident_, type(), origin(), timestamp));
632 return interpolated_;
643 std::string prefix = settings.prefix();
657 void save(madara::knowledge::KnowledgeBase &kb,
660 std::string key = this->key(settings);
661 save_as(kb, std::move(key), expiry, settings);
672 void save(madara::knowledge::KnowledgeBase &kb,
674 std::string key = this->key(settings);
675 save_as(kb, std::move(key), settings);
693 madara::knowledge::KnowledgeBase &kb,
694 const std::string &
id,
695 uint64_t timestamp = -1,
696 uint64_t parent_timestamp = -1,
712 madara::knowledge::KnowledgeBase &kb,
713 const std::string &
id,
714 uint64_t timestamp = -1,
727 static uint64_t latest_timestamp(
728 madara::knowledge::KnowledgeBase &kb,
729 const std::string &
id,
746 template<
typename ForwardIterator>
748 madara::knowledge::KnowledgeBase &kb,
749 ForwardIterator begin,
753 madara::knowledge::ContextGuard guard(kb);
755 uint64_t timestamp = -1;
756 ForwardIterator cur = begin;
758 uint64_t time = latest_timestamp(kb, *cur, settings);
759 if (time < timestamp) {
779 template<
typename Container>
781 madara::knowledge::KnowledgeBase &kb,
782 const Container &ids,
785 madara::knowledge::ContextGuard guard(kb);
787 return latest_common_timestamp(kb, ids.cbegin(), ids.cend(), settings);
806 template<
typename ForwardIterator>
808 madara::knowledge::KnowledgeBase &kb,
809 ForwardIterator begin,
811 uint64_t timestamp = -1,
814 std::vector<ReferenceFrame> ret;
815 if (std::is_same<
typename ForwardIterator::iterator_category,
816 std::random_access_iterator_tag>::value) {
817 size_t count = std::distance(begin, end);
821 madara::knowledge::ContextGuard guard(kb);
823 if (timestamp == (uint64_t)-1) {
824 timestamp = latest_common_timestamp(kb, begin, end, settings);
826 while (begin != end) {
828 if (!frame.
valid()) {
831 ret.push_back(frame);
853 template<
typename Container>
855 madara::knowledge::KnowledgeBase &kb,
856 const Container &ids,
857 uint64_t timestamp = -1,
860 return load_tree(kb, ids.cbegin(), ids.cend(),
861 timestamp, std::move(settings));
872 void save_as(madara::knowledge::KnowledgeBase &kb,
873 std::string key, uint64_t expiry,
882 void save_as(madara::knowledge::KnowledgeBase &kb,
886 save_as(kb, key, ident().expiry(), settings);
904 auto ret = ident().get_version(time);
909 double fraction = (time - timestamp()) / (
double)(other.
timestamp() - timestamp());
911 Pose interp = origin();
914 interp.
frame(std::move(parent));
916 interp.x((fraction * (opose.x() - interp.x())) + interp.x());
917 interp.y((fraction * (opose.y() - interp.y())) + interp.y());
918 interp.z((fraction * (opose.z() - interp.z())) + interp.z());
928 auto ret = std::make_shared<ReferenceFrameVersion>(
929 ident_, type(), std::move(interp), time);
932 ident().register_version(time, ret);
935 ret->interpolated_ =
true;
939 template<
typename CoordType>
943 bool check_consistent()
const;
959 mutable madara::knowledge::KnowledgeBase
kb_;
974 : kb_(
std::move(kb)), settings_(
std::move(settings)), expiry_(expiry) {}
994 FrameStore(madara::knowledge::KnowledgeBase kb, uint64_t expiry)
1017 const madara::knowledge::KnowledgeBase &
kb()
const {
return kb_; }
1028 return frame.
save(kb_, expiry_, settings_);
1062 template<
typename InputIterator>
1064 InputIterator begin,
1066 uint64_t timestamp = -1)
const {
1086 template<
typename Container>
1088 const Container &ids,
1089 uint64_t timestamp = -1)
const {
1105 std::vector<const ReferenceFrame *> *to_stack =
nullptr);
1154 bool is_child_to_parent,
1155 bool unsupported_angular =
false);
1172 namespace simple_rotate {
1183 double &x,
double &y,
double &z,
1184 double rx,
double ry,
double rz,
1185 bool reverse =
false);
1197 double orx,
double ory,
double orz,
1198 double &rx,
double &ry,
double &rz);
1210 double orx,
double ory,
double orz,
1211 double &rx,
double &ry,
double &rz);
1227 double ox,
double oy,
double oz,
1228 double orx,
double ory,
double orz,
1229 double &x,
double &y,
double &z,
1230 double &rx,
double &ry,
double &rz,
1247 double ox,
double oy,
double oz,
1248 double orx,
double ory,
double orz,
1249 double &x,
double &y,
double &z,
1250 double &rx,
double &ry,
double &rz,
1266 double rx1,
double ry1,
double rz1,
1267 double rx2,
double ry2,
double rz2);
1272 double &,
double &,
double &) {}
1276 double &,
double &,
double &) {}
1280 double &x,
double &y,
double &z,
1281 double &rx,
double &ry,
double &rz)
1283 self->normalize_linear(
self, x, y, z);
1284 self->normalize_angular(
self, rx, ry, rz);
1289 #include "ReferenceFrame.inl" ReferenceFrameIdentity(std::string id, uint64_t expiry)
Public by necessity. Use lookup instead.
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 ...
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.
uint64_t expiry() const
Return the current expiry.
static const FrameEvalSettings DEFAULT
static const std::string & default_prefix()
static uint64_t default_expiry_
static std::vector< ReferenceFrame > load_tree(madara::knowledge::KnowledgeBase &kb, const Container &ids, uint64_t timestamp=-1, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT)
Load ReferenceFrames, by ID, and their common ancestors.
ReferenceFrameVersion(const ReferenceFrameType *type, std::string name, P &&origin, uint64_t timestamp=-1)
Constructor from a type, id, an origin, and optional timestamp.
void save(const ReferenceFrame &frame) const
Save a ReferenceFrame to the knowledge base, The saved frames will be marked with their timestamp for...
Pose & mut_origin()
Gets the origin of this Frame.
static std::string & make_kb_key(std::string &prefix, const std::string &id)
FrameStore(madara::knowledge::KnowledgeBase kb, uint64_t expiry)
Constructor for FrameStore Uses default FrameEvalSettings.
static std::string & make_kb_key(std::string &prefix, const std::string &id, uint64_t timestamp)
ReferenceFrame move(const Position &new_origin, uint64_t timestamp) const
Creates a new ReferenceFrame with modified origin and timestamp.
gams::pose::undefined_transform undefined_transform
Thrown when an attempt is made to transform between two frame types, and there's not transform define...
ReferenceFrame move(Position new_origin) const
Creates a new ReferenceFrame with modified origin.
void to_angular_vector(double &rx, double &ry, double &rz) const
Settings class for saving/loading reference frames.
std::vector< ReferenceFrame > load_tree(const Container &ids, uint64_t timestamp=-1) const
Load ReferenceFrames, by ID, and their common ancestors.
std::vector< ReferenceFrame > load_tree(InputIterator begin, InputIterator end, uint64_t timestamp=-1) const
Load ReferenceFrames, by ID, and their common ancestors.
const FrameEvalSettings & settings() const
Return the current settings for frames saved/loaded with this FrameStore.
ReferenceFrame timestamp(uint64_t timestamp) const
Clone the this frame, but with new timestamp.
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.
const ReferenceFrameIdentity & ident() const
Get the ReferenceFrameIdentity object associated with this frame, creating one with random ID if none...
const Pose & origin() const
Gets the origin of this Frame.
MADARA_MAKE_VAL_SUPPORT_TEST(nano_timestamp, x,(x.nanos(), x.nanos(0UL)))
Type trait to detect stamped types.
ReferenceFrameVersion(std::shared_ptr< ReferenceFrameIdentity > ident, const ReferenceFrameType *type, P &&origin, uint64_t timestamp=-1)
Constructor from an existing ReferenceFrameIdentity, an origin, and optional timestamp.
const madara::knowledge::KnowledgeBase & kb() const
Return the KnowledgeBase to load/save with this FrameStore.
ReferenceFrame load(const std::string &id, uint64_t timestamp=-1)
Load a single ReferenceFrame, by ID.
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...
Class for storing and loading frames in a given KnowledgeBase, using given settings, with a set expiry.
static ReferenceFrame load(madara::knowledge::KnowledgeBase &kb, const std::string &id, uint64_t timestamp=-1, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT)
Load a single ReferenceFrame, by ID.
void default_normalize_pose(const ReferenceFrameType *self, double &x, double &y, double &z, double &rx, double &ry, double &rz)
gams::pose::unrelated_frames unrelated_frames
Thrown when an an attempt is made to transform between frames that do not belong to the same frame tr...
ReferenceFrameVersion(P &&origin, uint64_t timestamp=-1)
Constructor from an origin, and optional timestamp.
const ReferenceFrameType * type_
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.
const char * name() const
Returns a human-readable name for the reference frame type.
static std::vector< ReferenceFrame > load_tree(madara::knowledge::KnowledgeBase &kb, ForwardIterator begin, ForwardIterator end, uint64_t timestamp=-1, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT)
Load ReferenceFrames, by ID, and their common ancestors.
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 ...
void default_normalize_linear(const ReferenceFrameType *, double &, double &, double &)
const std::string & id() const
Get the ID string of this frame.
static std::vector< ReferenceFrame > load_tree(madara::knowledge::KnowledgeBase &kb, InputIterator begin, InputIterator end, uint64_t timestamp=-1, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT)
Load ReferenceFrames, by ID, and their common ancestors.
static const std::string & default_prefix()
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...
bool interpolated() const
Returns true if this frame was interpolated from two stored frames.
OrientationVector & as_orientation_vec()
Gets a reference to this object's Orientation part.
Contains all GAMS-related tools, classes and code.
void default_normalize_angular(const ReferenceFrameType *, double &, double &, double &)
std::shared_ptr< ReferenceFrameIdentity > ident_
const Pose & origin() const
Gets the origin of this Frame.
gams::pose::Orientation Orientation
Represents a orientation or orientation within a reference frame.
ReferenceFrame orient(Orientation new_origin) const
Creates a new ReferenceFrame with modified origin.
static uint64_t latest_common_timestamp(madara::knowledge::KnowledgeBase &kb, ForwardIterator begin, ForwardIterator end, const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT)
Get the latest available timestamp in the knowledge base common to all the given ids.
Used internally to implement angle operations.
ReferenceFrame orient(const Orientation &new_origin, uint64_t timestamp) const
Creates a new ReferenceFrame with modified origin and timestamp.
static uint64_t default_expiry()
Return the default expiry for new frame IDs.
const std::string * id_ptr() const
Get the ID string of this frame.
const std::string & id() const
FrameStore(madara::knowledge::KnowledgeBase kb, FrameEvalSettings settings, uint64_t expiry)
Primary constructor for FrameStore.
ReferenceFrame origin_frame() const
Gets the parent frame (the one the origin is within).
void slerp_this(const Quaternion &o, double t)
If *this and o are unit quaternions, interpolate a quaternion that is partially between them...
bool has_id() const
Does this frame have an ID? Frames gain an ID either at construction, or lazily as needed (by having ...
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 ...
ReferenceFrameVersion(const ReferenceFrameType *type, P &&origin, uint64_t timestamp=-1)
Constructor from a type, an origin, and optional timestamp.
void register_version(uint64_t timestamp, std::shared_ptr< ReferenceFrameVersion > ver) const
ReferenceFrame pose(const Pose &new_origin, uint64_t timestamp) const
Creates a new ReferenceFrame with modified origin and timestamp.
static uint64_t init_timestamp(uint64_t given, const T &p)
static std::mutex idents_lock_
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.
ReferenceFrameVersion(std::string name, P &&origin, uint64_t timestamp=-1)
Constructor from a id, an origin, and optional timestamp.
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.
std::shared_ptr< ReferenceFrameVersion > get_version(uint64_t timestamp) const
bool operator!=(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
ReferenceFrame pose(Pose new_origin) const
Creates a new ReferenceFrame with modified origin.
std::map< uint64_t, std::weak_ptr< ReferenceFrameVersion > > versions_
static std::map< std::string, std::weak_ptr< ReferenceFrameIdentity > > idents_
const ReferenceFrameType * Cartesian
ReferenceFrameType struct for Cartesian frames.
gams::pose::ReferenceFrame ReferenceFrame
Base class for Reference Frames.
gams::pose::Pose Pose
Represents a combination of Location and Orientation within a single reference frame.
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.
Provides Reference Frame (i.e., coordinate systemm) transforms.
static uint64_t default_expiry(uint64_t age)
Set the default expiry value for new frames IDs.
static std::shared_ptr< ReferenceFrameIdentity > make_guid()
FrameStore(madara::knowledge::KnowledgeBase kb, FrameEvalSettings settings)
Constructor for FrameStore Uses ReferenceFrame::default_expiry() for expiration.
double calc_angle(const ReferenceFrameType *self, double rx1, double ry1, double rz1, double rx2, double ry2, double rz2)
Calculates smallest angle between two AngularVectors.
bool valid() const
Test whether this frame is valid.
const ReferenceFrameType * type() const
Retrieve the frame type object for this frame.
uint64_t timestamp() const
Get the timestamp assigned to this frame.
madara::knowledge::KnowledgeBase kb_
uint64_t expiry() const
Return the current expiry for all frames saved with this FrameStore See ReferenceFrame::expiry(uint64...
ReferenceFrame interpolate(const ReferenceFrame &other, ReferenceFrame parent, uint64_t time) const
Interpolate a frame between the given frame; use the given parent.
uint64_t try_get_nano_time(uint64_t def)
Base case: return default.
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.
std::mutex versions_lock_
uint64_t timestamp() const
Get the timestamp assigned to this frame.
FrameStore(madara::knowledge::KnowledgeBase kb)
Constructor for FrameStore Uses default FrameEvalSettings Uses ReferenceFrame::default_expiry() for e...
bool operator==(const BasicVector< LDerived, Units > &lhs, const BasicVector< RDerived, Units > &rhs)
const ReferenceFrame & frame() const
Getter for the ReferenceFrame this Coordinate belongs to.
std::string key(const FrameEvalSettings &settings=FrameEvalSettings::DEFAULT) const
Returns the key that save() will use to store this frame.
static const std::string & default_prefix()
gams::pose::Coordinate< CoordType > Coordinate
New coordinate types which are frame-dependant can inherit from this class.