ROSiFace.h
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 #ifndef ROSIFACE_H
00027 #define ROSIFACE_H
00028
00029 #include "includeROS.h"
00030 #include <sstream>
00031 #include <typeinfo>
00032 #include "MIPMatrix.h"
00033 #include <LogTrace.h>
00034 #include <deque>
00035
00036
00037
00038 #include <boost/bind.hpp>
00039
00040
00044
00048
00049 using namespace MipBaselib;
00050
00051 namespace MipBaselib{
00053
00054
00058 enum ROSiFaceOpeningModes{
00060 ROSIFACE_R,
00062 ROSIFACE_W,
00064 ROSIFACE_RW
00065 };
00066
00067
00068 class ROSiFaceBoss{
00069 public:
00074 virtual bool updateMessage()=0;
00075
00076
00077
00078 };
00079
00085 template <class msg_type, typename msg_type_ptr>
00086 class ROSiFace: public ROSiFaceBoss{
00087 public:
00088
00099 ROSiFace(const string& topicName, ros::NodeHandle *_node, ROSiFaceOpeningModes op, int queue=1, int bufferDim=1);
00100
00103 ~ROSiFace();
00104
00110 bool sendMessage(const msg_type& message);
00111
00116 bool updateMessage();
00117
00123 bool getMessage(msg_type &msg);
00124
00129 void getMsgList(deque<msg_type> &listMsg);
00130
00131 private:
00132
00133
00135 string _topicName;
00137 ROSiFaceOpeningModes _openingMode;
00139 int _queueLength;
00140
00141
00143 ros::Publisher* _talkerA;
00145 ros::Subscriber* _subscriberA;
00146
00148 int storedMsgSize;
00149
00151 msg_type _lastMessage;
00153 deque<msg_type> _storedMessages;
00154
00156 bool _busy;
00157
00159
00160 void chatterCallback(const msg_type_ptr& msg);
00161 };
00162
00163
00164
00165 template <class msg_type, typename msg_type_ptr> ROSiFace<msg_type, msg_type_ptr>::ROSiFace(const string& topicName, ros::NodeHandle *_node, ROSiFaceOpeningModes op, int queue,int bufferDim)
00166 {
00167 _topicName = topicName;
00168 _openingMode = op;
00169 _queueLength = queue;
00170
00171 if (op == ROSIFACE_W || op == ROSIFACE_RW){
00172 cout << "ROSiFace: open a Publisher on the topic " << _topicName << endl;
00173 this->_talkerA = new ros::Publisher;
00174 *this->_talkerA = _node->advertise<msg_type>(_topicName, _queueLength);
00175 }
00176 if (op == ROSIFACE_R || op == ROSIFACE_RW){
00177 storedMsgSize = bufferDim;
00178
00179 cout << "ROSiFace: open a Subscriber on the topic " << _topicName << endl;
00180 this->_subscriberA = new ros::Subscriber;
00181 ros::SubscribeOptions so = ros::SubscribeOptions::create<msg_type>(_topicName, _queueLength, boost::bind(&ROSiFace::chatterCallback, this, _1), ros::VoidPtr(), NULL);
00182 *this->_subscriberA = _node->subscribe(so);
00183 }
00184 _busy = false;
00185 }
00186
00187
00188
00189 template <class msg_type, typename msg_type_ptr> ROSiFace<msg_type, msg_type_ptr>::ROSiFace::~ROSiFace() {
00190 if (_openingMode == ROSIFACE_W || _openingMode == ROSIFACE_RW){
00191 cout << "RosTalker:: Destruct a publisher" << endl;
00192 delete this->_talkerA;
00193 }
00194 if (_openingMode == ROSIFACE_R || _openingMode == ROSIFACE_RW){
00195 cout << "RosTalker:: Destruct a subscriber" << endl;
00196 delete this->_subscriberA;
00197 }
00198 }
00199
00200
00201
00202
00203 template <class msg_type, typename msg_type_ptr> bool ROSiFace<msg_type, msg_type_ptr>::ROSiFace::sendMessage(const msg_type& message) {
00204 if (_openingMode == ROSIFACE_R){
00205 LogTrace::fatal("tentative of writing a read-only ROSiFace.");
00206 return false;
00207 }
00208 if(ros::ok()) {
00209 this->_talkerA->publish(message);
00210 return true;
00211 }
00212 else {
00213 cout<< "WARNING! RosTalker::sendRosMsg() ros::ok() is FALSE" << endl;
00214 return false;
00215 }
00216 }
00217
00218
00219 template <class msg_type, typename msg_type_ptr> bool ROSiFace<msg_type, msg_type_ptr>::ROSiFace::updateMessage() {
00220 if (_openingMode == ROSIFACE_W){
00221 LogTrace::fatal("tentative of reading a write-only ROSiFace.");
00222 return false;
00223 }
00224 if(ros::ok()) {
00225 ros::spinOnce();
00226 return true;
00227 }
00228 else {
00229 cout<< "WARNING! RosTalker::sendRosMsg() ros::ok() is FALSE" << endl;
00230 return false;
00231 }
00232 }
00233
00234 template <class msg_type, typename msg_type_ptr> bool ROSiFace<msg_type, msg_type_ptr>::ROSiFace::getMessage(msg_type& msg){
00235 if (_openingMode == ROSIFACE_W){
00236 LogTrace::fatal("tentative of reading a write-only ROSiFace.");
00237 return false;
00238 }
00239 if(ros::ok()) {
00240 msg = _lastMessage;
00241 return true;
00242 }else
00243 return false;
00244 }
00245
00246 template <class msg_type, typename msg_type_ptr> void ROSiFace<msg_type, msg_type_ptr>::ROSiFace::getMsgList(deque< msg_type >& listMsg){
00247 listMsg.clear();
00248 while(_busy){usleep(100);}
00249 _busy = true;
00250 listMsg = _storedMessages;
00251 _busy = false;
00252 }
00253
00254
00255 template <class msg_type, typename msg_type_ptr> void ROSiFace<msg_type, msg_type_ptr>::ROSiFace::chatterCallback(const msg_type_ptr& msg) {
00256 _lastMessage = *msg;
00257 while(_busy){usleep(100);}
00258 _busy = true;
00259 int listBufferSize = _storedMessages.size();
00260 if(listBufferSize<storedMsgSize){
00261 _storedMessages.push_back(*msg);
00262 }else{
00263 _storedMessages.pop_front();
00264 _storedMessages.push_back(*msg);
00265 }
00266 _busy = false;
00267 }
00268
00269
00270
00271
00272
00273
00274 }
00275 #endif // ROSIFACE_H
00276