transform_relay.cpp
Go to the documentation of this file.
1 
26 
28 
29 #include <utility>
30 
31 namespace tf2_relay
32 {
33 
34 TransformRelay::TransformRelay(ros::NodeHandle origin, ros::NodeHandle target, double frequency, bool is_static,
36  : origin_(origin), target_(target), frame_id_processor_(frame_id_processor)
37 {
38  if (!is_static)
39  {
40  tf_subscriber_ = origin_.subscribe<tf2_msgs::TFMessage>
41  ("tf", 100, boost::bind(&TransformRelay::transformCb, this, _1));
42  tf_publisher_ = target_.advertise<tf2_msgs::TFMessage>("tf", 100);
43  }
44  else
45  {
46  tf_subscriber_ = origin_.subscribe<tf2_msgs::TFMessage>
47  ("tf_static", 100, boost::bind(&TransformRelay::transformCb, this, _1));
48  tf_publisher_ = target_.advertise<tf2_msgs::TFMessage>("tf_static", 100, true);
49  }
50 
51  if (!is_static && frequency > 0.0)
52  {
53  relay_timer_ = origin_.createTimer(ros::Duration(1 / frequency), boost::bind(&TransformRelay::relayCb, this));
54  }
55 }
56 
57 void TransformRelay::transformCb(const tf2_msgs::TFMessageConstPtr &transforms)
58 {
59  for (tf2_msgs::TFMessage::_transforms_type::const_iterator new_tf = transforms->transforms.begin();
60  new_tf != transforms->transforms.end(); ++new_tf)
61  {
62  processTransform(*new_tf);
63  }
64 
65  // If no timer is setup, publish immediately
66  if (!relay_timer_.isValid() && !transform_cache_.transforms.empty())
67  {
69  }
70 }
71 
73 {
74  if (!transform_cache_.transforms.empty())
75  {
77  }
78 
79  transform_cache_.transforms.clear();
81 }
82 
83 void TransformRelay::processTransform(const geometry_msgs::TransformStamped &new_tf)
84 {
85  const FrameIdPair frame_id_pair(new_tf.header.frame_id, new_tf.child_frame_id);
86 
87  // Check if incoming transform needs to be added to transform cache
88  if (transform_cache_index_map_.count(frame_id_pair) == 0)
89  {
90  geometry_msgs::TransformStamped::Ptr new_tf_ptr = boost::make_shared<geometry_msgs::TransformStamped>(new_tf);
92  new_tf_ptr, frame_id_processor_);
93  transform_cache_.transforms.push_back(*new_tf_ptr);
94  // Cache the index of the just-added transform
96  std::pair<FrameIdPair, std::size_t>(frame_id_pair, transform_cache_.transforms.size() - 1));
97  }
98  // Otherwise update the existing transform in cache
99  else
100  {
101  geometry_msgs::TransformStamped &tf =
102  transform_cache_.transforms[transform_cache_index_map_[frame_id_pair]];
103 
104  // Only update if new transform is newer
105  if (tf.header.stamp < new_tf.header.stamp)
106  {
107  tf.header.stamp = new_tf.header.stamp;
108  tf.transform = new_tf.transform;
109  }
110  }
111 }
112 
113 } // namespace tf2_relay
ros::Subscriber tf_subscriber_
void publish(const boost::shared_ptr< M > &message) const
ros::Publisher tf_publisher_
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
TransformRelay(ros::NodeHandle origin, ros::NodeHandle target, double frequency, bool is_static, message_relay::FrameIdProcessor::ConstPtr frame_id_processor)
boost::unordered_map< FrameIdPair, std::size_t > transform_cache_index_map_
void processTransform(const geometry_msgs::TransformStamped &new_tf)
tf2_msgs::TFMessage transform_cache_
Timer createTimer(Rate r, Handler h, Obj o, bool oneshot=false, bool autostart=true) const
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
std::pair< std::string, std::string > FrameIdPair
bool isValid()
message_relay::FrameIdProcessor::ConstPtr frame_id_processor_
static void processMessage(typename Message::Ptr &msg, typename Processor::ConstPtr &processor)
void transformCb(const tf2_msgs::TFMessageConstPtr &transforms)


tf2_relay
Author(s):
autogenerated on Wed Jul 17 2019 03:28:00