protobuf2ros_stream.cc
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2017 Roboception GmbH
00003  * All rights reserved
00004  *
00005  * Author: Christian Emmerich
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted provided that the following conditions are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright notice,
00011  * this list of conditions and the following disclaimer.
00012  *
00013  * 2. Redistributions in binary form must reproduce the above copyright notice,
00014  * this list of conditions and the following disclaimer in the documentation
00015  * and/or other materials provided with the distribution.
00016  *
00017  * 3. Neither the name of the copyright holder nor the names of its contributors
00018  * may be used to endorse or promote products derived from this software without
00019  * specific prior written permission.
00020  *
00021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00031  * POSSIBILITY OF SUCH DAMAGE.
00032  */
00033 
00034 #include "protobuf2ros_stream.h"
00035 
00036 #include "publishers/protobuf2ros_publisher.h"
00037 #include "publishers/protobuf2ros_conversions.h"
00038 
00039 #include <ros/ros.h>
00040 #include <tf/transform_broadcaster.h>
00041 
00042 #include <rc_dynamics_api/unexpected_receive_timeout.h>
00043 
00044 
00045 using namespace std;
00046 
00047 namespace rc
00048 {
00049 
00050 namespace rcd = dynamics;
00051 
00052 
00053 bool Protobuf2RosStream::startReceivingAndPublishingAsRos()
00054 {
00055   unsigned int timeoutMillis = 500;
00056   string pbMsgType = _rcdyn->getPbMsgTypeOfStream(_stream);
00057 
00058   Protobuf2RosPublisher rosPublisher(_nh, _stream, pbMsgType, _tfPrefix);
00059 
00060   unsigned int cntNoListener = 0;
00061   bool failed = false;
00062 
00063   while (!_stop && !failed)
00064   {
00065 
00066     // start streaming only if someone is listening
00067 
00068     if (!rosPublisher.used())
00069     {
00070       // ros getNumSubscribers usually takes a while to register the subscribers
00071       if (++cntNoListener > 200)
00072       {
00073         _requested = false;
00074       }
00075       usleep(1000 * 10);
00076       continue;
00077     }
00078     cntNoListener = 0;
00079     _requested = true;
00080     _success = false;
00081     ROS_INFO_STREAM("rc_visard_driver: Enabled rc-dynamics stream: " << _stream);
00082 
00083     // initialize data stream to this host
00084 
00085     rcd::DataReceiver::Ptr receiver;
00086     try
00087     {
00088       receiver = _rcdyn->createReceiverForStream(_stream);
00089     }
00090     catch (rcd::UnexpectedReceiveTimeout& e) {
00091       stringstream msg;
00092       msg << "Could not initialize rc-dynamics stream: " << _stream << ":" << endl << e.what();
00093       ROS_WARN_STREAM_THROTTLE(5, msg.str());
00094       continue;
00095     }
00096     catch (exception &e)
00097     {
00098       ROS_ERROR_STREAM(std::string("Could not initialize rc-dynamics stream: ")
00099                        + _stream + ": " + e.what());
00100       failed = true;
00101       break;
00102     }
00103     receiver->setTimeout(timeoutMillis);
00104     ROS_INFO_STREAM("rc_visard_driver: rc-dynamics stream ready: " << _stream);
00105 
00106     // main loop for listening, receiving and republishing data to ROS
00107 
00108     shared_ptr<::google::protobuf::Message> pbMsg;
00109     while (!_stop && rosPublisher.used())
00110     {
00111 
00112       // try receive msg; blocking call (timeout)
00113       try
00114       {
00115         pbMsg = receiver->receive(pbMsgType);
00116         _success = true;
00117       }
00118       catch (std::exception &e)
00119       {
00120         ROS_ERROR_STREAM("Caught exception during receiving "
00121                                  << _stream << ": " << e.what());
00122         failed = true;
00123         break; // stop receiving loop
00124       }
00125 
00126       // timeout happened; if its only small let's put a warning and increasing recv timeout
00127       if (!pbMsg)
00128       {
00129         ROS_ERROR_STREAM("Did not receive any "
00130                                  << _stream << " message within the last "
00131                                  << timeoutMillis << " ms. "
00132                                  << "Either rc_visard stopped streaming or is turned off, "
00133                                  << "or you seem to have serious network/connection problems!");
00134         failed = true;
00135         break; // stop receiving loop
00136       }
00137 
00138       ROS_DEBUG_STREAM_THROTTLE(1, "Received protobuf message: "
00139               << pbMsg->DebugString());
00140 
00141       // convert to ROS message and publish
00142       rosPublisher.publish(pbMsg);
00143     }
00144 
00145     ROS_INFO_STREAM("rc_visard_driver: Disabled rc-dynamics stream: " << _stream);
00146   }
00147 
00148   // return info about stream being stopped externally or failed internally
00149   return !failed;
00150 }
00151 
00152 
00153 bool PoseStream::startReceivingAndPublishingAsRos()
00154 {
00155   unsigned int timeoutMillis = 500;
00156 
00157   ros::Publisher pub = _nh.advertise<geometry_msgs::PoseStamped>(_stream, 1000);
00158   tf::TransformBroadcaster tf_pub;
00159 
00160   unsigned int cntNoListener = 0;
00161   bool failed = false;
00162 
00163   while (!_stop && !failed)
00164   {
00165     bool someoneListens = _tfEnabled || pub.getNumSubscribers() > 0;
00166 
00167     // start streaming only if someone is listening
00168 
00169     if (!someoneListens)
00170     {
00171       // ros getNumSubscribers usually takes a while to register the subscribers
00172       if (++cntNoListener > 200)
00173       {
00174         _requested = false;
00175       }
00176       usleep(1000 * 10);
00177       continue;
00178     }
00179     cntNoListener = 0;
00180     _requested = true;
00181     _success = false;
00182     ROS_INFO_STREAM("rc_visard_driver: Enabled rc-dynamics stream: " << _stream);
00183 
00184     // initialize data stream to this host
00185 
00186     rcd::DataReceiver::Ptr receiver;
00187     try
00188     {
00189       receiver = _rcdyn->createReceiverForStream(_stream);
00190     }
00191     catch (rcd::UnexpectedReceiveTimeout& e) {
00192       stringstream msg;
00193       msg << "Could not initialize rc-dynamics stream: " << _stream << ":" << endl << e.what();
00194       ROS_WARN_STREAM_THROTTLE(5, msg.str());
00195       continue;
00196     }
00197     catch (exception &e)
00198     {
00199       ROS_ERROR_STREAM(std::string("Could not initialize rc-dynamics stream: ")
00200                        + _stream + ": " + e.what());
00201       failed = true;
00202       break;
00203     }
00204     receiver->setTimeout(timeoutMillis);
00205     ROS_INFO_STREAM("rc_visard_driver: rc-dynamics stream ready: " << _stream);
00206 
00207     // main loop for listening, receiving and republishing data to ROS
00208 
00209     shared_ptr <roboception::msgs::Frame> protoFrame;
00210     while (!_stop && someoneListens)
00211     {
00212 
00213       // try receive msg; blocking call (timeout)
00214       try
00215       {
00216         protoFrame = receiver->receive<roboception::msgs::Frame>();
00217         _success = true;
00218       }
00219       catch (std::exception &e)
00220       {
00221         ROS_ERROR_STREAM("Caught exception during receiving "
00222                                  << _stream << ": " << e.what());
00223         failed = true;
00224         break; // stop receiving loop
00225       }
00226 
00227       // timeout happened; if its only small let's put a warning and increasing recv timeout
00228       if (!protoFrame)
00229       {
00230         ROS_ERROR_STREAM("Did not receive any "
00231                                  << _stream << " message within the last "
00232                                  << timeoutMillis << " ms. "
00233                                  << "Either rc_visard stopped streaming or is turned off, "
00234                                  << "or you seem to have serious network/connection problems!");
00235         failed = true;
00236         break; // stop receiving loop
00237       }
00238 
00239       ROS_DEBUG_STREAM_THROTTLE(1, "Received protoFrame: "
00240               << protoFrame->DebugString());
00241 
00242 
00243       // overwrite frame name/ids
00244       protoFrame->set_parent(_tfPrefix+protoFrame->parent());
00245       protoFrame->set_name(_tfPrefix+protoFrame->name());
00246 
00247       auto rosPose = toRosPoseStamped(protoFrame);
00248       pub.publish(rosPose);
00249 
00250       // convert to tf and publish
00251       if (_tfEnabled)
00252       {
00253         tf::StampedTransform transform = toRosTfStampedTransform(protoFrame);
00254         tf_pub.sendTransform(transform);
00255       }
00256 
00257       // check if still someone is listening
00258       someoneListens = _tfEnabled || pub.getNumSubscribers() > 0;
00259     }
00260 
00261     ROS_INFO_STREAM("rc_visard_driver: Disabled rc-dynamics stream: " << _stream);
00262   }
00263 
00264   // return info about stream being stopped externally or failed internally
00265   return !failed;
00266 }
00267 
00268 
00269 
00270 }


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:06