topics.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 #
00003 # Copyright 2015 Airbus
00004 # Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
00005 #
00006 # Licensed under the Apache License, Version 2.0 (the "License");
00007 # you may not use this file except in compliance with the License.
00008 # You may obtain a copy of the License at
00009 #
00010 #   http://www.apache.org/licenses/LICENSE-2.0
00011 #
00012 # Unless required by applicable law or agreed to in writing, software
00013 # distributed under the License is distributed on an "AS IS" BASIS,
00014 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 # See the License for the specific language governing permissions and
00016 # limitations under the License.
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,                   # Main thread (QObject)
00031                  name,                     # Topic name
00032                  data_class,               # Data class ROS message
00033                  cb_slot      = None,      # Callback Qt slot triggered by ROS message 
00034                  timeout_slot = None,      # Timeout Qt slot triggered when unreceived message on time
00035                  timeout      = None,      # Timeout duration
00036                  auto_start   = True,      # Auto start connection
00037                  max_rate     = None):     # Limitation frequency to emit SIGNAL to call cb_slot
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 # Minimum time duration between 2 call
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     


airbus_pyqt_extend
Author(s): Martin Matignon
autogenerated on Thu Jun 6 2019 17:59:16