simple_publisher_plugin.h
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 * 
00004 *  Copyright (c) 2009, Willow Garage, Inc.
00005 *  All rights reserved.
00006 * 
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 * 
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the Willow Garage nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 * 
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
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     // First call the internal callback (for sending setup headers, etc.)
00205     internal_cb(ros_ssp);
00206     
00207     // Construct a function object for publishing sensor_msgs::Image through the
00208     // subclass-implemented publish() using the ros::SingleSubscriberPublisher to send
00209     // messages of the transport-specific type.
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     // Bind PubT::publish(const Message&) as PublishFn
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 } //namespace image_transport
00239 
00240 #endif


image_transport
Author(s): Patrick Mihelich
autogenerated on Mon Oct 6 2014 00:42:37