$search
00001 /*************************************************************************** 00002 tag: Ruben Smits Tue Nov 16 09:18:49 CET 2010 ros_msg_transporter.hpp 00003 00004 ros_msg_transporter.hpp - description 00005 ------------------- 00006 begin : Tue November 16 2010 00007 copyright : (C) 2010 Ruben Smits 00008 email : first.last@mech.kuleuven.be 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU Lesser General Public * 00013 * License as published by the Free Software Foundation; either * 00014 * version 2.1 of the License, or (at your option) any later version. * 00015 * * 00016 * This library is distributed in the hope that it will be useful, * 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00019 * Lesser General Public License for more details. * 00020 * * 00021 * You should have received a copy of the GNU Lesser General Public * 00022 * License along with this library; if not, write to the Free Software * 00023 * Foundation, Inc., 59 Temple Place, * 00024 * Suite 330, Boston, MA 02111-1307 USA * 00025 * * 00026 ***************************************************************************/ 00027 00028 00029 // Copyright (C) 2010 Ruben Smits <ruben dot smits at mech dot kuleuven dot be> 00030 00031 // Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be> 00032 // Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be> 00033 00034 // This library is free software; you can redistribute it and/or 00035 // modify it under the terms of the GNU Lesser General Public 00036 // License as published by the Free Software Foundation; either 00037 // version 2.1 of the License, or (at your option) any later version. 00038 00039 // This library is distributed in the hope that it will be useful, 00040 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00041 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00042 // Lesser General Public License for more details. 00043 00044 // You should have received a copy of the GNU Lesser General Public 00045 // License along with this library; if not, write to the Free Software 00046 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00047 00048 00049 #ifndef _ROS_MSG_TRANSPORTER_HPP_ 00050 #define _ROS_MSG_TRANSPORTER_HPP_ 00051 00052 #include <rtt/types/TypeTransporter.hpp> 00053 #include <rtt/Port.hpp> 00054 #include <rtt/TaskContext.hpp> 00055 #include <rtt/internal/ConnFactory.hpp> 00056 #include <ros/ros.h> 00057 00058 00059 #include "ros_publish_activity.hpp" 00060 00061 namespace ros_integration { 00062 00063 using namespace RTT; 00068 template<typename T> 00069 class RosPubChannelElement: public base::ChannelElement<T>,public RosPublisher 00070 { 00071 char hostname[1024]; 00072 std::string topicname; 00073 ros::NodeHandle ros_node; 00074 ros::Publisher ros_pub; 00076 RosPublishActivity::shared_ptr act; 00077 00078 public: 00079 00090 RosPubChannelElement(base::PortInterface* port,const ConnPolicy& policy) 00091 { 00092 if ( policy.name_id.empty() ){ 00093 std::stringstream namestr; 00094 gethostname(hostname, sizeof(hostname)); 00095 00096 namestr << hostname<<'/' << port->getInterface()->getOwner()->getName() 00097 << '/' << port->getName() << '/'<<this << '/' << getpid(); 00098 policy.name_id = namestr.str(); 00099 } 00100 topicname=policy.name_id; 00101 Logger::In in(topicname); 00102 log(Debug)<<"Creating ROS publisher for port "<<port->getInterface()->getOwner()->getName()<<"."<<port->getName()<<" on topic "<<policy.name_id<<endlog(); 00103 00104 ros_pub = ros_node.advertise<T>(policy.name_id, policy.size ? policy.size : 1, policy.init); // minimum 1 00105 act = RosPublishActivity::Instance(); 00106 act->addPublisher( this ); 00107 } 00108 00109 ~RosPubChannelElement() { 00110 Logger::In in(topicname); 00111 log(Debug)<<"Destroying RosPubChannelElement"<<endlog(); 00112 act->removePublisher( this ); 00113 } 00114 00120 virtual bool inputReady() { 00121 return true; 00122 } 00123 00131 virtual bool data_sample(typename base::ChannelElement<T>::param_t sample) 00132 { 00133 return true; 00134 } 00135 00141 bool signal(){ 00142 //Logger::In in(topicname); 00143 //log(Debug)<<"Requesting publish"<<endlog(); 00144 return act->requestPublish(this); 00145 } 00146 00147 void publish(){ 00148 typename base::ChannelElement<T>::value_t sample; // XXX: real-time ! 00149 // this read should always succeed since signal() means 'data available in a data element'. 00150 typename base::ChannelElement<T>::shared_ptr input = this->getInput(); 00151 while( input && (input->read(sample,false) == NewData) ) 00152 ros_pub.publish(sample); 00153 } 00154 00155 }; 00156 00157 template<typename T> 00158 class RosSubChannelElement: public base::ChannelElement<T> 00159 { 00160 ros::NodeHandle ros_node; 00161 ros::Subscriber ros_sub; 00162 00163 public: 00173 RosSubChannelElement(base::PortInterface* port, const ConnPolicy& policy) 00174 { 00175 log(Debug)<<"Creating ROS subscriber for port "<<port->getInterface()->getOwner()->getName()<<"."<<port->getName()<<" on topic "<<policy.name_id<<endlog(); 00176 ros_sub=ros_node.subscribe(policy.name_id,policy.size,&RosSubChannelElement::newData,this); 00177 this->ref(); 00178 } 00179 00180 ~RosSubChannelElement() { 00181 } 00182 00183 virtual bool inputReady() { 00184 return true; 00185 } 00191 void newData(const T& msg){ 00192 typename base::ChannelElement<T>::shared_ptr output = this->getOutput(); 00193 if (output) 00194 output->write(msg); 00195 } 00196 }; 00197 00198 template <class T> 00199 class RosMsgTransporter : public RTT::types::TypeTransporter{ 00200 virtual base::ChannelElementBase::shared_ptr createStream (base::PortInterface *port, const ConnPolicy &policy, bool is_sender) const{ 00201 base::ChannelElementBase* buf = internal::ConnFactory::buildDataStorage<T>(policy); 00202 base::ChannelElementBase::shared_ptr tmp; 00203 if(is_sender){ 00204 tmp = base::ChannelElementBase::shared_ptr(new RosPubChannelElement<T>(port,policy)); 00205 buf->setOutput(tmp); 00206 return buf; 00207 } 00208 else { 00209 tmp = new RosSubChannelElement<T>(port,policy); 00210 tmp->setOutput(buf); 00211 return tmp; 00212 } 00213 } 00214 }; 00215 } 00216 #endif