rtt_rostopic_ros_msg_transporter.hpp
Go to the documentation of this file.
1 /*
2  * (C) 2010 Ruben Smits, ruben.smits@mech.kuleuven.be
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. Neither the name of the copyright holder nor the names of its contributors
13  * may be used to endorse or promote products derived from this software
14  * without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef __RTT_ROSCOMM_ROS_MSG_TRANSPORTER_HPP_
31 #define __RTT_ROSCOMM_ROS_MSG_TRANSPORTER_HPP_
32 
33 #include <rtt/rtt-config.h>
35 #include <rtt/Port.hpp>
36 #include <rtt/TaskContext.hpp>
38 #include <ros/ros.h>
39 
41 
42 #ifndef RTT_VERSION_GTE
43  #define RTT_VERSION_GTE(major,minor,patch) \
44  ((RTT_VERSION_MAJOR > major) || (RTT_VERSION_MAJOR == major && \
45  (RTT_VERSION_MINOR > minor) || (RTT_VERSION_MINOR == minor && \
46  (RTT_VERSION_PATCH >= patch))))
47 #endif
48 
49 namespace rtt_roscomm {
50 
55  template <typename T>
57  {
58  typedef T OrocosType;
59  typedef T RosType;
60  static const RosType &toRos(const OrocosType &t) { return t; }
61  static const OrocosType &fromRos(const RosType &t) { return t; }
62  };
63 
67  template<typename T>
69  {
71  typedef typename adapter::RosType RosType;
72 
73  char hostname[1024];
74  std::string topicname;
80 
82 
83  public:
84 
96  ros_node(),
97  ros_node_private("~")
98  {
99  if ( policy.name_id.empty() ){
100  std::stringstream namestr;
101  gethostname(hostname, sizeof(hostname));
102 
103  if (port->getInterface() && port->getInterface()->getOwner()) {
104  namestr << hostname<<'/' << port->getInterface()->getOwner()->getName()
105  << '/' << port->getName() << '/'<<this << '/' << getpid();
106  } else {
107  namestr << hostname<<'/' << port->getName() << '/'<<this << '/' << getpid();
108  }
109  policy.name_id = namestr.str();
110  }
111  topicname=policy.name_id;
112  RTT::Logger::In in(topicname);
113 
114  if (port->getInterface() && port->getInterface()->getOwner()) {
115  RTT::log(RTT::Debug)<<"Creating ROS publisher for port "<<port->getInterface()->getOwner()->getName()<<"."<<port->getName()<<" on topic "<<policy.name_id<<RTT::endlog();
116  } else {
117  RTT::log(RTT::Debug)<<"Creating ROS publisher for port "<<port->getName()<<" on topic "<<policy.name_id<<RTT::endlog();
118  }
119 
120  // Handle private names
121  if(topicname.length() > 1 && topicname.at(0) == '~') {
122  ros_pub = ros_node_private.advertise<RosType>(policy.name_id.substr(1), policy.size > 0 ? policy.size : 1, policy.init); // minimum 1
123  } else {
124  ros_pub = ros_node.advertise<RosType>(policy.name_id, policy.size > 0 ? policy.size : 1, policy.init); // minimum 1
125  }
127  act->addPublisher( this );
128  }
129 
131  RTT::Logger::In in(topicname);
132 // RTT::log(RTT::Debug) << "Destroying RosPubChannelElement" << RTT::endlog();
133  act->removePublisher( this );
134  }
135 
141  virtual bool inputReady() {
142  return true;
143  }
144 
145  virtual bool isRemoteElement() const {
146  return true;
147  }
148 
149  virtual std::string getElementName() const {
150  return "RosPubChannelElement";
151  }
152 
153  virtual std::string getRemoteURI() const {
154  return ros_pub.getTopic();
155  }
156 
164 #if RTT_VERSION_GTE(2,8,99)
165  virtual RTT::WriteStatus data_sample(typename RTT::base::ChannelElement<T>::param_t sample)
166  {
167  this->sample = sample;
168  return RTT::WriteSuccess;
169  }
170 #else
172  {
173  this->sample = sample;
174  return true;
175  }
176 #endif
177 
183  bool signal(){
184  //RTT::Logger::In in(topicname);
185  //RTT::log(RTT::Debug) << "Requesting publish" << RTT::endlog();
186  return act->trigger();
187  }
188 
189  void publish(){
190  // this read should always succeed since signal() means 'data available in a data element'.
191  typename RTT::base::ChannelElement<T>::shared_ptr input = this->getInput();
192  while( input && (input->read(sample,false) == RTT::NewData) )
193  write(sample);
194  }
195 
196 #if RTT_VERSION_GTE(2,8,99)
198 #else
200 #endif
201  {
202  ros_pub.publish(adapter::toRos(sample));
203 #if RTT_VERSION_GTE(2,8,99)
204  return RTT::WriteSuccess;
205 #else
206  return true;
207 #endif
208  }
209 
210  };
211 
215  template<typename T>
217  {
219  typedef typename adapter::RosType RosType;
220 
221  std::string topicname;
225 
226  public:
237  ros_node(),
238  ros_node_private("~")
239  {
240  topicname=policy.name_id;
241  RTT::Logger::In in(topicname);
242  if (port->getInterface() && port->getInterface()->getOwner()) {
243  RTT::log(RTT::Debug)<<"Creating ROS subscriber for port "<<port->getInterface()->getOwner()->getName()<<"."<<port->getName()<<" on topic "<<policy.name_id<<RTT::endlog();
244  } else {
245  RTT::log(RTT::Debug)<<"Creating ROS subscriber for port "<<port->getName()<<" on topic "<<policy.name_id<<RTT::endlog();
246  }
247  if(topicname.length() > 1 && topicname.at(0) == '~') {
248  ros_sub = ros_node_private.subscribe(policy.name_id.substr(1), policy.size > 0 ? policy.size : 1, &RosSubChannelElement::newData, this); // minimum queue_size 1
249  } else {
250  ros_sub = ros_node.subscribe(policy.name_id, policy.size > 0 ? policy.size : 1, &RosSubChannelElement::newData, this); // minimum queue_size 1
251  }
252  }
253 
255  RTT::Logger::In in(topicname);
256 // RTT::log(RTT::Debug)<<"Destroying RosSubChannelElement"<<RTT::endlog();
257  }
258 
259  virtual bool inputReady() {
260  return true;
261  }
262 
263  virtual bool isRemoteElement() const {
264  return true;
265  }
266 
267  virtual std::string getElementName() const {
268  return "RosSubChannelElement";
269  }
270 
271  virtual std::string getRemoteURI() const {
272  return ros_sub.getTopic();
273  }
274 
280  void newData(const RosType& msg){
281  typename RTT::base::ChannelElement<T>::shared_ptr output = this->getOutput();
282  if (output)
283  output->write(adapter::fromRos(msg));
284  }
285  };
286 
287  template <class T>
289  {
292 
293  // Pull semantics are not supported by the ROS message transport.
294  if (policy.pull) {
295  RTT::log(RTT::Error) << "Pull connections are not supported by the ROS message transport." << RTT::endlog();
297  }
298 
299  // Check if this node is initialized
300  if (!ros::ok()) {
301  RTT::log(RTT::Error) << "Cannot create ROS message transport because the node is not initialized or already shutting down. Did you import package rtt_rosnode before?" << RTT::endlog();
303  }
304 
305  if (is_sender){
306  channel = new RosPubChannelElement<T>(port, policy);
307 
308  if (policy.type == RTT::ConnPolicy::UNBUFFERED){
309  RTT::log(RTT::Debug) << "Creating unbuffered publisher connection for port " << port->getName() << ". This may not be real-time safe!" << RTT::endlog();
310  return channel;
311  }
312 
313  RTT::base::ChannelElementBase::shared_ptr buf = RTT::internal::ConnFactory::buildDataStorage<T>(policy);
315 #if RTT_VERSION_GTE(2,8,99)
316  buf->connectTo(channel);
317 #else
318  buf->setOutput(channel);
319 #endif
320  return buf;
321 
322  } else {
323  channel = new RosSubChannelElement<T>(port, policy);
324 
325 #if !RTT_VERSION_GTE(2,8,99)
326  RTT::base::ChannelElementBase::shared_ptr buf = RTT::internal::ConnFactory::buildDataStorage<T>(policy);
328  channel->setOutput(buf);
329 #endif
330  }
331 
332  return channel;
333  }
334  };
335 }
336 #endif
boost::call_traits< T >::param_type param_t
boost::intrusive_ptr< ChannelElement< T > > shared_ptr
void publish(const boost::shared_ptr< M > &message) const
WriteSuccess
Subscriber subscribe(const std::string &topic, uint32_t queue_size, void(T::*fp)(M), T *obj, const TransportHints &transport_hints=TransportHints())
const std::string & getName() const
static const OrocosType & fromRos(const RosType &t)
RTT::base::ChannelElement< T >::value_t sample
RosPubChannelElement(RTT::base::PortInterface *port, const RTT::ConnPolicy &policy)
bool write(typename RTT::base::ChannelElement< T >::param_t sample)
DataFlowInterface * getInterface() const
RosPublishActivity::shared_ptr act
We must cache the RosPublishActivity object.
virtual RTT::base::ChannelElementBase::shared_ptr createStream(RTT::base::PortInterface *port, const RTT::ConnPolicy &policy, bool is_sender) const
std::string getTopic() const
ROSCPP_DECL bool ok()
static const RosType & toRos(const OrocosType &t)
virtual FlowStatus read(reference_t sample, bool copy_old_data=true)
Publisher advertise(const std::string &topic, uint32_t queue_size, bool latch=false)
RosSubChannelElement(RTT::base::PortInterface *port, const RTT::ConnPolicy &policy)
boost::intrusive_ptr< ChannelElementBase > shared_ptr
virtual bool data_sample(typename RTT::base::ChannelElement< T >::param_t sample)
virtual WriteStatus write(param_t sample)
std::string getTopic() const
std::string name_id
static Logger & log()
static Logger::LogFunction endlog()
WriteStatus
static const int UNBUFFERED
virtual const std::string & getName() const
TaskContext * getOwner() const


rtt_roscomm
Author(s): Ruben Smits, Jonathan Bohren
autogenerated on Mon May 10 2021 02:45:04