VelocityDispatcher.cpp
Go to the documentation of this file.
00001 
00029 #include <iostream>
00030 #include <boost/thread.hpp>
00031 #include <boost/foreach.hpp>
00032 
00033 #include <ros/ros.h>
00034 #include <geometry_msgs/Twist.h>
00035 #include <std_msgs/Int32.h>
00036 
00037 using namespace std;
00038 using namespace ros;
00039 
00040 #define foreach BOOST_FOREACH
00041 
00042 /*************************************************************************************************
00043 *** Parameters
00044 **************************************************************************************************/
00045 
00046 volatile bool _enableOutput;
00047 
00048 int _currentInput;
00049 int _currentOutput;
00050 
00051 vector<Subscriber> _inputs;
00052 vector<Publisher>  _outputs;
00053 
00054 Subscriber _setInputSubscriber;
00055 Subscriber _setOutputSubscriber;
00056 
00057 Publisher _currentInputPublisher;
00058 Publisher _currentOutputPublisher;
00059 
00060 boost::thread* _velocityPublishThread;
00061 Timer _statusPublishTimer;
00062 
00063 geometry_msgs::Twist _currentVelocity;
00064 
00065 /*************************************************************************************************
00066 *** Callbacks
00067 **************************************************************************************************/
00068 
00069 void onSetInputMessage(const std_msgs::Int32::ConstPtr inputIdMessage) {
00070         if (inputIdMessage->data >= 1 && inputIdMessage->data <= _inputs.size()) {
00071                 _currentInput = inputIdMessage->data - 1;
00072                 ROS_INFO("Current input changed to '#%i' ['%s']", inputIdMessage->data, _inputs[_currentInput].getTopic().c_str());
00073         }
00074 }
00075 
00076 void onSetOutputMessage(const std_msgs::Int32::ConstPtr outputIdMessage) {
00077         if (outputIdMessage->data >= 1 && outputIdMessage->data <= _outputs.size()) {
00078                 _currentOutput = outputIdMessage->data - 1;
00079                 _enableOutput = true;
00080                 ROS_INFO("Current output changed to '#%i' ['%s']", outputIdMessage->data, _outputs[_currentOutput].getTopic().c_str());
00081         }
00082 
00083         if (outputIdMessage->data == 0) {
00084                 _enableOutput = false;
00085                 ROS_INFO("Current output changed to NONE [Disabled]");
00086         }
00087 }
00088 
00089 void onInputVelocityMessage(const geometry_msgs::Twist::ConstPtr velocityMessage, int inputId) {
00090         if (inputId == _currentInput + 1)
00091                 _currentVelocity = *velocityMessage;
00092 }
00093 
00094 /*************************************************************************************************
00095 *** Functions
00096 **************************************************************************************************/
00097 
00098 void publishStatus(TimerEvent timerEvent) {
00099         std_msgs::Int32 intMessage;
00100 
00101         intMessage.data = _currentInput + 1;
00102         _currentInputPublisher.publish(intMessage);
00103 
00104         intMessage.data = _currentOutput + 1;
00105         _currentOutputPublisher.publish(intMessage);
00106 }
00107 
00108 void publishVelocity() {
00109         while (ros::ok()) {
00110 
00111                 if (_enableOutput)
00112                         _outputs[_currentOutput].publish(_currentVelocity);
00113 
00114                 boost::this_thread::sleep(boost::posix_time::milliseconds(1000.0 / 20.0));
00115         }
00116 }
00117 
00118 void createSubscribersAndPublishers(NodeHandle& node, map<string, string>& inputs, vector<string>& outputs) {
00122         int inputId = 1;
00123         ROS_INFO("[Preparing inputs]");
00124         pair<string, string> input;
00125         foreach (input, inputs) {
00126                 ROS_INFO(" - Setting up input topic #%i: %s", inputId, input.second.c_str());
00127 
00128                 _inputs.push_back(node.subscribe<geometry_msgs::Twist>
00129                         (input.second, 100, boost::bind(onInputVelocityMessage, _1, inputId++)));
00130         }
00131 
00135         int outputId = 1;
00136         ROS_INFO("[Preparing outputs]");
00137         foreach (string output, outputs) {
00138                 ROS_INFO(" - Setting up output topic #%i: %s", outputId++, output.c_str());
00139 
00140                 _outputs.push_back(node.advertise<geometry_msgs::Twist>(output, 1, false));
00141         }
00142 
00146         _setInputSubscriber = node.subscribe("/velocity_dispatcher/set_input", 1, onSetInputMessage);
00147         _setOutputSubscriber = node.subscribe("/velocity_dispatcher/set_output", 1, onSetOutputMessage);
00148 
00152         _currentInputPublisher = node.advertise<std_msgs::Int32>("/velocity_dispatcher/current_input", 1, true);
00153         _currentOutputPublisher = node.advertise<std_msgs::Int32>("/velocity_dispatcher/current_output", 1, true);
00154 
00158         _statusPublishTimer = node.createTimer(Duration(1), boost::bind(publishStatus, _1));
00159         _velocityPublishThread = new boost::thread(publishVelocity);
00160 }
00161 
00162 bool setupInputOutput(NodeHandle& node) {
00163 
00164         map<string, string> inputTopics;
00165         vector<string> outputTopics;
00166 
00167         if (node.hasParam("/mr_teleoperator/input_topics"))
00168                 node.getParam("/mr_teleoperator/input_topics", inputTopics);
00169         else {
00170                 ROS_ERROR("No input topics provided");
00171                 return false;
00172         }
00173 
00174         if (node.hasParam("/mr_teleoperator/output_topics"))
00175                 node.getParam("/mr_teleoperator/output_topics", outputTopics);
00176         else {
00177                 ROS_ERROR("No output topics provided");
00178                 return false;
00179         }
00180 
00181         _enableOutput   = true;
00182         _currentInput   = 0;
00183         _currentOutput  = 0;
00184 
00185         createSubscribersAndPublishers(node, inputTopics, outputTopics);
00186 
00187         return true;
00188 
00189 }
00190 
00191 /*************************************************************************************************
00192 *** THIS IS MAAAAAAAAAAAAAAAAAAAAAAAIN!!!
00193 **************************************************************************************************/
00194 
00195 int main(int argc, char **argv) {
00196         init(argc, argv, "velocity_dispatcher");
00197 
00198         NodeHandle node;
00199 
00200         if (!setupInputOutput(node))
00201                 return 1;
00202 
00203         spin();
00204         return 0;
00205 }
00206 
00207 


mr_tools
Author(s): Igor Makhtes
autogenerated on Fri Aug 28 2015 11:35:35