publisher.cpp
Go to the documentation of this file.
00001 //=================================================================================================
00002 // Copyright (c) 2012, Johannes Meyer, TU Darmstadt
00003 // All rights reserved.
00004 
00005 // Redistribution and use in source and binary forms, with or without
00006 // modification, are permitted provided that the following conditions are met:
00007 //     * Redistributions of source code must retain the above copyright
00008 //       notice, this list of conditions and the following disclaimer.
00009 //     * Redistributions in binary form must reproduce the above copyright
00010 //       notice, this list of conditions and the following disclaimer in the
00011 //       documentation and/or other materials provided with the distribution.
00012 //     * Neither the name of the Flight Systems and Automatic Control group,
00013 //       TU Darmstadt, nor the names of its contributors may be used to
00014 //       endorse or promote products derived from this software without
00015 //       specific prior written permission.
00016 
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00018 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00019 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00020 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
00021 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 //=================================================================================================
00028 
00029 #include <rosmatlab/publisher.h>
00030 #include <rosmatlab/exception.h>
00031 #include <rosmatlab/options.h>
00032 #include <rosmatlab/conversion.h>
00033 
00034 #include <introspection/message.h>
00035 
00036 #include <ros/topic_manager.h>
00037 
00038 namespace rosmatlab {
00039 
00040 template <> const char *Object<Publisher>::class_name_ = "ros.Publisher";
00041 
00042 Publisher::Publisher()
00043   : Object<Publisher>(this)
00044 {
00045 }
00046 
00047 Publisher::Publisher(int nrhs, const mxArray *prhs[])
00048   : Object<Publisher>(this)
00049 {
00050   if (nrhs > 0) advertise(nrhs, prhs);
00051 }
00052 
00053 Publisher::~Publisher() {
00054   shutdown();
00055 }
00056 
00057 bool Publisher::advertise(int nrhs, const mxArray *prhs[])
00058 {
00059   if (nrhs < 2) {
00060     throw Exception("Publisher: advertise needs at least two arguments");
00061   }
00062 
00063   options_ = ros::AdvertiseOptions();
00064   for(int i = 0; i < nrhs; i++) {
00065     switch(i) {
00066       case 0:
00067         if (!Options::isString(prhs[i])) throw Exception("Publisher: need a topic as 1st argument");
00068         options_.topic = Options::getString(prhs[i]);
00069         break;
00070 
00071       case 1:
00072         if (!Options::isString(prhs[i])) throw Exception("Publisher: need a datatype as 2nd argument");
00073         options_.datatype = Options::getString(prhs[i]);
00074         break;
00075 
00076       case 2:
00077         if (!Options::isDoubleScalar(prhs[i])) throw Exception("Publisher: need a queue size as 3rd argument (optional)");
00078         options_.queue_size = Options::getDoubleScalar(prhs[i]);
00079         break;
00080 
00081       case 3:
00082         if (!Options::isLogicalScalar(prhs[i]) && !Options::isDoubleScalar(prhs[i])) throw Exception("Publisher: need logical latch as 4th argument (optional)");
00083         options_.latch = Options::getLogicalScalar(prhs[i]);
00084         break;
00085 
00086       default:
00087         throw Exception("Publisher: too many arguments");
00088     }
00089   }
00090 
00091   introspection_ = cpp_introspection::messageByDataType(options_.datatype);
00092   if (!introspection_) throw Exception("Publisher: unknown datatype '" + options_.datatype + "'");
00093   options_.md5sum = introspection_->getMD5Sum();
00094   options_.message_definition = introspection_->getDefinition();
00095   options_.has_header = introspection_->hasHeader();
00096 
00097   *this = node_handle_.advertise(options_);
00098   return *this;
00099 }
00100 
00101 static ros::SerializedMessage serialize(const cpp_introspection::MessagePtr& message)
00102 {
00103 //  mexPrintf("Serializer called for a message of type %s...\n", message->getDataType());
00104   return message->serialize();
00105 }
00106 
00107 
00108 void Publisher::publish(int nrhs, const mxArray *prhs[])
00109 {
00110   if (nrhs < 1) throw Exception("Publisher: publish needs at least one argument");
00111   if (!introspection_) throw Exception("Publisher: unknown message type");
00112 
00113   std::size_t length = mxGetNumberOfElements(prhs[0]);
00114   MessagePtr message;
00115   ros::SerializedMessage m;
00116   m.type_info = &(introspection_->getTypeId());
00117   Conversion conversion(introspection_);
00118 
00119   for(std::size_t i = 0; i < length; ++i) {
00120     message = Conversion(introspection_).fromMatlab(prhs[0], i);
00121     if (!message) throw Exception("Publisher: failed to parse message of type " + options_.datatype);
00122     m.message = message->getConstInstance();
00123 //    mexPrintf("Publishing on topic %s...\n", ros::Publisher::getTopic().c_str());
00124     ros::TopicManager::instance()->publish(ros::Publisher::getTopic(), boost::bind(&serialize, message), m);
00125   }
00126 
00127 }
00128 
00129 mxArray *Publisher::getTopic() const
00130 {
00131   return mxCreateString(ros::Publisher::getTopic().c_str());
00132 }
00133 
00134 mxArray *Publisher::getNumSubscribers() const
00135 {
00136   return mxCreateDoubleScalar(ros::Publisher::getNumSubscribers());
00137 }
00138 
00139 mxArray *Publisher::isLatched() const
00140 {
00141   throw Exception("ros::Publisher::isLatched is currently not implemented in roscpp (see https://github.com/ros/ros_comm/pull/1)");
00142 //  return mxCreateLogicalScalar(ros::Publisher::isLatched());
00143   return mxCreateLogicalScalar(false);
00144 }
00145 
00146 } // namespace rosmatlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


rosmatlab
Author(s): Johannes Meyer
autogenerated on Tue Jan 8 2013 17:31:00