ROSiFace.h

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------------
00002 //
00003 // $Id$
00004 //
00005 // Copyright 2008, 2009, 2010, 2011, 2012  Antonio Franchi and Paolo Stegagno    
00006 //
00007 // This file is part of MIP.
00008 //
00009 // MIP is free software: you can redistribute it and/or modify
00010 // it under the terms of the GNU General Public License as published by
00011 // the Free Software Foundation, either version 3 of the License, or
00012 // (at your option) any later version.
00013 //
00014 // MIP is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with MIP. If not, see <http://www.gnu.org/licenses/>.
00021 //
00022 // Contact info: antonio.franchi@tuebingen.mpg.de stegagno@diag.uniroma1.it
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     return false;
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    // properties of this topic
00135    string _topicName;
00137    ROSiFaceOpeningModes _openingMode;
00139    int _queueLength;
00140    
00141    // topic variables
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 

Generated on Mon Feb 20 07:01:07 2017 for MIP by  doxygen 1.5.6