00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00032 #ifndef TF2_BUFFER_CORE_H
00033 #define TF2_BUFFER_CORE_H
00034
00035 #include "transform_storage.h"
00036
00037 #include <boost/signals2.hpp>
00038
00039 #include <string>
00040
00041 #include "ros/duration.h"
00042 #include "ros/time.h"
00043
00044 #include "geometry_msgs/TransformStamped.h"
00045
00047
00048
00049 #include <boost/unordered_map.hpp>
00050 #include <boost/thread/mutex.hpp>
00051 #include <boost/function.hpp>
00052 #include <boost/shared_ptr.hpp>
00053
00054 namespace tf2
00055 {
00056
00057 typedef std::pair<ros::Time, CompactFrameID> P_TimeAndFrameID;
00058 typedef uint32_t TransformableCallbackHandle;
00059 typedef uint64_t TransformableRequestHandle;
00060
00061 class TimeCacheInterface;
00062 typedef boost::shared_ptr<TimeCacheInterface> TimeCacheInterfacePtr;
00063
00064 enum TransformableResult
00065 {
00066 TransformAvailable,
00067 TransformFailure,
00068 };
00069
00088 class BufferCore
00089 {
00090 public:
00091
00092 static const int DEFAULT_CACHE_TIME = 10;
00093 static const uint32_t MAX_GRAPH_DEPTH = 1000UL;
00094
00100 BufferCore(ros::Duration cache_time_ = ros::Duration(DEFAULT_CACHE_TIME));
00101 virtual ~BufferCore(void);
00102
00104 void clear();
00105
00112 bool setTransform(const geometry_msgs::TransformStamped& transform, const std::string & authority, bool is_static = false);
00113
00114
00115
00125 geometry_msgs::TransformStamped
00126 lookupTransform(const std::string& target_frame, const std::string& source_frame,
00127 const ros::Time& time) const;
00128
00141 geometry_msgs::TransformStamped
00142 lookupTransform(const std::string& target_frame, const ros::Time& target_time,
00143 const std::string& source_frame, const ros::Time& source_time,
00144 const std::string& fixed_frame) const;
00145
00166
00167
00168
00169
00170
00171
00184
00185
00186
00187
00188
00196 bool canTransform(const std::string& target_frame, const std::string& source_frame,
00197 const ros::Time& time, std::string* error_msg = NULL) const;
00198
00208 bool canTransform(const std::string& target_frame, const ros::Time& target_time,
00209 const std::string& source_frame, const ros::Time& source_time,
00210 const std::string& fixed_frame, std::string* error_msg = NULL) const;
00211
00215 std::string allFramesAsYAML(double current_time) const;
00216
00219 std::string allFramesAsYAML() const;
00220
00224 std::string allFramesAsString() const;
00225
00226 typedef boost::function<void(TransformableRequestHandle request_handle, const std::string& target_frame, const std::string& source_frame,
00227 ros::Time time, TransformableResult result)> TransformableCallback;
00228
00230 TransformableCallbackHandle addTransformableCallback(const TransformableCallback& cb);
00232 void removeTransformableCallback(TransformableCallbackHandle handle);
00234 TransformableRequestHandle addTransformableRequest(TransformableCallbackHandle handle, const std::string& target_frame, const std::string& source_frame, ros::Time time);
00236 void cancelTransformableRequest(TransformableRequestHandle handle);
00237
00238
00239
00240
00241
00242
00243 void setUsingDedicatedThread(bool value) { using_dedicated_thread_ = value;};
00244
00245 bool isUsingDedicatedThread() const { return using_dedicated_thread_;};
00246
00247
00248
00249
00250
00251
00252
00260 boost::signals2::connection _addTransformsChangedListener(boost::function<void(void)> callback);
00261 void _removeTransformsChangedListener(boost::signals2::connection c);
00262
00263
00266 bool _frameExists(const std::string& frame_id_str) const;
00267
00272 bool _getParent(const std::string& frame_id, ros::Time time, std::string& parent) const;
00273
00275 void _getFrameStrings(std::vector<std::string>& ids) const;
00276
00277
00278 CompactFrameID _lookupFrameNumber(const std::string& frameid_str) const {
00279 return lookupFrameNumber(frameid_str);
00280 }
00281 CompactFrameID _lookupOrInsertFrameNumber(const std::string& frameid_str) {
00282 return lookupOrInsertFrameNumber(frameid_str);
00283 }
00284
00285 int _getLatestCommonTime(CompactFrameID target_frame, CompactFrameID source_frame, ros::Time& time, std::string* error_string) const {
00286 boost::mutex::scoped_lock lock(frame_mutex_);
00287 return getLatestCommonTime(target_frame, source_frame, time, error_string);
00288 }
00289
00290 CompactFrameID _validateFrameId(const char* function_name_arg, const std::string& frame_id) const {
00291 return validateFrameId(function_name_arg, frame_id);
00292 }
00293
00295 ros::Duration getCacheLength() { return cache_time_;}
00296
00300 std::string _allFramesAsDot(double current_time) const;
00301 std::string _allFramesAsDot() const;
00302
00306 void _chainAsVector(const std::string & target_frame, ros::Time target_time, const std::string & source_frame, ros::Time source_time, const std::string & fixed_frame, std::vector<std::string>& output) const;
00307
00308 private:
00309
00313 std::string allFramesAsStringNoLock() const;
00314
00315
00316
00317
00320 typedef std::vector<TimeCacheInterfacePtr> V_TimeCacheInterface;
00321 V_TimeCacheInterface frames_;
00322
00324 mutable boost::mutex frame_mutex_;
00325
00327 typedef boost::unordered_map<std::string, CompactFrameID> M_StringToCompactFrameID;
00328 M_StringToCompactFrameID frameIDs_;
00330 std::vector<std::string> frameIDs_reverse;
00332 std::map<CompactFrameID, std::string> frame_authority_;
00333
00334
00336 ros::Duration cache_time_;
00337
00338 typedef boost::unordered_map<TransformableCallbackHandle, TransformableCallback> M_TransformableCallback;
00339 M_TransformableCallback transformable_callbacks_;
00340 uint32_t transformable_callbacks_counter_;
00341 boost::mutex transformable_callbacks_mutex_;
00342
00343 struct TransformableRequest
00344 {
00345 ros::Time time;
00346 TransformableRequestHandle request_handle;
00347 TransformableCallbackHandle cb_handle;
00348 CompactFrameID target_id;
00349 CompactFrameID source_id;
00350 std::string target_string;
00351 std::string source_string;
00352 };
00353 typedef std::vector<TransformableRequest> V_TransformableRequest;
00354 V_TransformableRequest transformable_requests_;
00355 boost::mutex transformable_requests_mutex_;
00356 uint64_t transformable_requests_counter_;
00357
00358 struct RemoveRequestByCallback;
00359 struct RemoveRequestByID;
00360
00361
00362 typedef boost::signals2::signal<void(void)> TransformsChangedSignal;
00364 TransformsChangedSignal _transforms_changed_;
00365
00366
00367
00368
00375 TimeCacheInterfacePtr getFrame(CompactFrameID c_frame_id) const;
00376
00377 TimeCacheInterfacePtr allocateFrame(CompactFrameID cfid, bool is_static);
00378
00379
00380 bool warnFrameId(const char* function_name_arg, const std::string& frame_id) const;
00381 CompactFrameID validateFrameId(const char* function_name_arg, const std::string& frame_id) const;
00382
00384 CompactFrameID lookupFrameNumber(const std::string& frameid_str) const;
00385
00387 CompactFrameID lookupOrInsertFrameNumber(const std::string& frameid_str);
00388
00390 const std::string& lookupFrameString(CompactFrameID frame_id_num) const;
00391
00392 void createConnectivityErrorString(CompactFrameID source_frame, CompactFrameID target_frame, std::string* out) const;
00393
00396 int getLatestCommonTime(CompactFrameID target_frame, CompactFrameID source_frame, ros::Time& time, std::string* error_string) const;
00397
00398 template<typename F>
00399 int walkToTopParent(F& f, ros::Time time, CompactFrameID target_id, CompactFrameID source_id, std::string* error_string) const;
00400
00403 template<typename F>
00404 int walkToTopParent(F& f, ros::Time time, CompactFrameID target_id, CompactFrameID source_id, std::string* error_string, std::vector<CompactFrameID> *frame_chain) const;
00405
00406 void testTransformableRequests();
00407 bool canTransformInternal(CompactFrameID target_id, CompactFrameID source_id,
00408 const ros::Time& time, std::string* error_msg) const;
00409 bool canTransformNoLock(CompactFrameID target_id, CompactFrameID source_id,
00410 const ros::Time& time, std::string* error_msg) const;
00411
00412
00413
00414 bool using_dedicated_thread_;
00415
00416 };
00417
00418
00419
00420
00421 };
00422
00423 #endif //TF2_CORE_H