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 import rospy
00020 import os
00021 from python_qt_binding.QtGui import *
00022 from python_qt_binding.QtCore import *
00023 
00024 class QAgiSubscriber(QObject):
00025     
00026     CALLBACK_SIGN = 'callbackTriggered'
00027     TIMEOUT_SIGN  = 'timeoutTriggered'
00028     
00029     def __init__(self,
00030                  parent,                   
00031                  name,                     
00032                  data_class,               
00033                  cb_slot      = None,      
00034                  timeout_slot = None,      
00035                  timeout      = None,      
00036                  auto_start   = True,      
00037                  max_rate     = None):     
00038         
00039         QObject.__init__(self)
00040         
00041         self._parent        = parent
00042         self._sub           = None
00043         self._topic_name    = name
00044         self._data_class    = data_class
00045         self._cb_slot       = cb_slot
00046         self._timeout       = timeout
00047         self._timeout_slot  = timeout_slot
00048         self._timeout_t     = None
00049         
00050         self._last_call_time    = rospy.get_rostime()
00051         self._min_time_dur_b2c  = None 
00052         
00053         if isinstance(max_rate, rospy.Rate):
00054             self._min_time_dur_b2c = max_rate.sleep_dur
00055             self._cb_ptr = self._inhibited_callback
00056         elif isinstance(max_rate, int):
00057             self._min_time_dur_b2c = rospy.Rate(max_rate).sleep_dur
00058             self._cb_ptr = self._inhibited_callback
00059         else:
00060             self._cb_ptr = self._callback
00061         
00062         self._parent.connect(self, SIGNAL(self.CALLBACK_SIGN), self._cb_slot)
00063         
00064         if self._timeout_slot:
00065             self._parent.connect(self, SIGNAL(self.TIMEOUT_SIGN), self._timeout_slot)
00066             
00067         if auto_start:
00068             self.start()
00069             
00070     def remaining(self):
00071         elapsed = rospy.get_rostime() - self._last_call_time
00072         return elapsed
00073     
00074     def _inhibited_callback(self, msg):
00075         """Callback with max rate limitation
00076         Check time between two call and inhibit signal if diff time is too small
00077         If (T-1 - T) < Tmax_rate -> inhibit slot
00078         else call slot
00079         """
00080         
00081         if self.remaining() >= self._min_time_dur_b2c:
00082             self._callback(msg)
00083     
00084     def _callback(self, msg):
00085         """Callback without max rate inhibition"""
00086         self.emit(SIGNAL(self.CALLBACK_SIGN), msg)
00087         self._last_call_time = rospy.get_rostime()
00088         
00089     def _slot_check_timeout(self):
00090         
00091         if self.remaining() > self._timeout:
00092             self.emit(SIGNAL(self.TIMEOUT_SIGN))
00093     
00094     def setTimeout(self, timeout):
00095         self._timeout = timeout
00096         
00097     def start(self):
00098         
00099         self._sub = rospy.Subscriber(self._topic_name,
00100                                      self._data_class,
00101                                      self._cb_ptr)
00102         
00103         if self._timeout:
00104             self._timeout_t = QTimer(self)
00105             self.connect(self._timeout_t, SIGNAL("timeout()"), self._slot_check_timeout)
00106             self._timeout_t.start(self._timeout.to_nsec()*(1e-6)/3)
00107             
00108         self._last_call_time = rospy.get_rostime()
00109         
00110     subscribe = start
00111     
00112     def shutdown(self):
00113         
00114         if self._timeout is not None:
00115             self._timeout_t.stop()
00116         if self._sub is not None:
00117             self._sub.unregister()
00118             self._sub = None
00119         
00120     unregister = shutdown
00121     stop = shutdown
00122