Go to the documentation of this file.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
00030
00031
00032
00033
00034
00035 #ifndef IMAGE_TRANSPORT_SIMPLE_PUBLISHER_PLUGIN_H
00036 #define IMAGE_TRANSPORT_SIMPLE_PUBLISHER_PLUGIN_H
00037
00038 #include "image_transport/publisher_plugin.h"
00039 #include <boost/scoped_ptr.hpp>
00040
00041 namespace image_transport {
00042
00060 template <class M>
00061 class SimplePublisherPlugin : public PublisherPlugin
00062 {
00063 public:
00064 virtual ~SimplePublisherPlugin() {}
00065
00066 virtual uint32_t getNumSubscribers() const
00067 {
00068 if (simple_impl_) return simple_impl_->pub_.getNumSubscribers();
00069 return 0;
00070 }
00071
00072 virtual std::string getTopic() const
00073 {
00074 if (simple_impl_) return simple_impl_->pub_.getTopic();
00075 return std::string();
00076 }
00077
00078 virtual void publish(const sensor_msgs::Image& message) const
00079 {
00080 if (!simple_impl_ || !simple_impl_->pub_) {
00081 ROS_ASSERT_MSG(false, "Call to publish() on an invalid image_transport::SimplePublisherPlugin");
00082 return;
00083 }
00084
00085 publish(message, bindInternalPublisher(simple_impl_->pub_));
00086 }
00087
00088 virtual void shutdown()
00089 {
00090 if (simple_impl_) simple_impl_->pub_.shutdown();
00091 }
00092
00093 protected:
00094 virtual void advertiseImpl(ros::NodeHandle& nh, const std::string& base_topic, uint32_t queue_size,
00095 const SubscriberStatusCallback& user_connect_cb,
00096 const SubscriberStatusCallback& user_disconnect_cb,
00097 const ros::VoidPtr& tracked_object, bool latch)
00098 {
00099 std::string transport_topic = getTopicToAdvertise(base_topic);
00100 ros::NodeHandle param_nh(transport_topic);
00101 simple_impl_.reset(new SimplePublisherPluginImpl(param_nh));
00102 simple_impl_->pub_ = nh.advertise<M>(transport_topic, queue_size,
00103 bindCB(user_connect_cb, &SimplePublisherPlugin::connectCallback),
00104 bindCB(user_disconnect_cb, &SimplePublisherPlugin::disconnectCallback),
00105 tracked_object, latch);
00106 }
00107
00109 typedef boost::function<void(const M&)> PublishFn;
00110
00119 virtual void publish(const sensor_msgs::Image& message, const PublishFn& publish_fn) const = 0;
00120
00126 virtual std::string getTopicToAdvertise(const std::string& base_topic) const
00127 {
00128 return base_topic + "/" + getTransportName();
00129 }
00130
00136 virtual void connectCallback(const ros::SingleSubscriberPublisher& pub) {}
00137
00143 virtual void disconnectCallback(const ros::SingleSubscriberPublisher& pub) {}
00144
00148 const ros::NodeHandle& nh() const
00149 {
00150 return simple_impl_->param_nh_;
00151 }
00152
00159 const ros::Publisher& getPublisher() const
00160 {
00161 ROS_ASSERT(simple_impl_);
00162 return simple_impl_->pub_;
00163 }
00164
00165 private:
00166 struct SimplePublisherPluginImpl
00167 {
00168 SimplePublisherPluginImpl(const ros::NodeHandle& nh)
00169 : param_nh_(nh)
00170 {
00171 }
00172
00173 const ros::NodeHandle param_nh_;
00174 ros::Publisher pub_;
00175 };
00176
00177 boost::scoped_ptr<SimplePublisherPluginImpl> simple_impl_;
00178
00179 typedef void (SimplePublisherPlugin::*SubscriberStatusMemFn)(const ros::SingleSubscriberPublisher& pub);
00180
00185 ros::SubscriberStatusCallback bindCB(const SubscriberStatusCallback& user_cb,
00186 SubscriberStatusMemFn internal_cb_fn)
00187 {
00188 ros::SubscriberStatusCallback internal_cb = boost::bind(internal_cb_fn, this, _1);
00189 if (user_cb)
00190 return boost::bind(&SimplePublisherPlugin::subscriberCB, this, _1, user_cb, internal_cb);
00191 else
00192 return internal_cb;
00193 }
00194
00200 void subscriberCB(const ros::SingleSubscriberPublisher& ros_ssp,
00201 const SubscriberStatusCallback& user_cb,
00202 const ros::SubscriberStatusCallback& internal_cb)
00203 {
00204
00205 internal_cb(ros_ssp);
00206
00207
00208
00209
00210 typedef void (SimplePublisherPlugin::*PublishMemFn)(const sensor_msgs::Image&, const PublishFn&) const;
00211 PublishMemFn pub_mem_fn = &SimplePublisherPlugin::publish;
00212 ImagePublishFn image_publish_fn = boost::bind(pub_mem_fn, this, _1, bindInternalPublisher(ros_ssp));
00213
00214 SingleSubscriberPublisher ssp(ros_ssp.getSubscriberName(), getTopic(),
00215 boost::bind(&SimplePublisherPlugin::getNumSubscribers, this),
00216 image_publish_fn);
00217 user_cb(ssp);
00218 }
00219
00220 typedef boost::function<void(const sensor_msgs::Image&)> ImagePublishFn;
00221
00228 template <class PubT>
00229 PublishFn bindInternalPublisher(const PubT& pub) const
00230 {
00231
00232 typedef void (PubT::*InternalPublishMemFn)(const M&) const;
00233 InternalPublishMemFn internal_pub_mem_fn = &PubT::publish;
00234 return boost::bind(internal_pub_mem_fn, &pub, _1);
00235 }
00236 };
00237
00238 }
00239
00240 #endif