rutils.py
Go to the documentation of this file.
00001 #
00002 # Copyright (c) 2009, Georgia Tech Research Corporation
00003 # All rights reserved.
00004 #
00005 # Redistribution and use in source and binary forms, with or without
00006 # modification, are permitted provided that the following conditions are met:
00007 #     * Redistributions of source code must retain the above copyright
00008 #       notice, this list of conditions and the following disclaimer.
00009 #     * Redistributions in binary form must reproduce the above copyright
00010 #       notice, this list of conditions and the following disclaimer in the
00011 #       documentation and/or other materials provided with the distribution.
00012 #     * Neither the name of the Georgia Tech Research Corporation nor the
00013 #       names of its contributors may be used to endorse or promote products
00014 #       derived from this software without specific prior written permission.
00015 #
00016 # THIS SOFTWARE IS PROVIDED BY GEORGIA TECH RESEARCH CORPORATION ''AS IS'' AND
00017 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00018 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019 # DISCLAIMED. IN NO EVENT SHALL GEORGIA TECH BE LIABLE FOR ANY DIRECT, INDIRECT,
00020 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00021 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
00022 # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00023 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
00024 # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
00025 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 #
00027 
00028 #  \author Hai Nguyen (Healthcare Robotics Lab, Georgia Tech.)
00029 
00030 import roslib; roslib.load_manifest('hrl_lib')
00031 import rospy
00032 #import rosrecord
00033 import std_srvs.srv as srv
00034 from hrl_msgs.msg import FloatArray
00035 #import tf
00036 #import tf.msg
00037 from rospy.impl.tcpros import DEFAULT_BUFF_SIZE
00038 
00039 import time
00040 import numpy as np
00041 import geometry_msgs.msg as gm
00042 import sensor_msgs.msg as sm
00043 import threading
00044 
00045 ##
00046 # Converts any ros message class into a dictionary
00047 # (currently used to make PoseStamped messages picklable)
00048 # @param msg
00049 # @return a nested dict with rospy.Time turned into normal unix time float
00050 def ros_to_dict(msg):
00051     d = {}
00052     for f in msg.__slots__:
00053         val = eval('msg.%s' % f)
00054         methods = dir(val)
00055         if 'to_time' in methods:
00056             val = eval('val.to_time()')
00057         elif '__slots__' in methods:
00058             val = ros_to_dict(val)
00059         d[f] = val
00060     return d
00061 
00062 ###
00063 ## Converts a list of pr2_msgs/PressureState into a matrix
00064 ##
00065 ## @return left mat, right mat, array
00066 #def pressure_state_to_mat(contact_msgs):
00067 #    times = np.array([c.header.stamp.to_time() for c in contact_msgs])
00068 #    left, right = zip(*[[list(c.l_finger_tip), list(c.r_finger_tip)] for c in contact_msgs])
00069 #    
00070 #    left = np.matrix(left).T
00071 #    right = np.matrix(right).T
00072 #    return left, right, times
00073 
00074 def np_to_pointcloud(points_mat, frame):
00075     pc = sm.PointCloud()
00076     pc.header.stamp = rospy.get_rostime()
00077     pc.header.frame_id = frame
00078     for i in range(points_mat.shape[1]):
00079         p32 = gm.Point32()
00080         p32.x = points_mat[0,i]
00081         p32.y = points_mat[1,i]
00082         p32.z = points_mat[2,i]
00083         pc.points.append(p32)
00084     return pc
00085 
00086 def np_to_colored_pointcloud(points_mat, intensity, frame):
00087     pc = np_to_pointcloud(points_mat, frame)
00088     pc.channels.append(sm.ChannelFloat32())
00089     pc.channels[0].name = 'intensity'
00090     pc.channels[0].values = intensity.A1.tolist()
00091     return pc
00092 
00093 ##
00094 # @param points_mat 2xn
00095 # @param intensities 3xn
00096 # @param frame
00097 def np_to_rgb_pointcloud(points_mat, intensities, frame):
00098     pc = np_to_pointcloud(points_mat, frame)
00099     pc.channels.append(sm.ChannelFloat32())
00100     pc.channels[0].name = 'r'
00101     pc.channels[0].values = intensities[2,:].A1.tolist()
00102 
00103     pc.channels.append(sm.ChannelFloat32())
00104     pc.channels[1].name = 'g'
00105     pc.channels[1].values = intensities[1,:].A1.tolist()
00106 
00107     pc.channels.append(sm.ChannelFloat32())
00108     pc.channels[2].name = 'b'
00109     pc.channels[2].values = intensities[0,:].A1.tolist()
00110     return pc
00111 
00112 def pointcloud_to_np(pc):
00113     plist = []
00114     for p in pc.points:
00115         plist.append([p.x, p.y, p.z])
00116     return np.matrix(plist).T
00117 
00118 #class LaserScanner:
00119 #    def __init__(self, service):
00120 #        srv_name = '/%s/single_sweep_cloud' % service
00121 #        self.sp = rospy.ServiceProxy(srv_name, snp.BuildCloudAngle)
00122 #
00123 #    def scan_np(self, start, end, duration):
00124 #        resp = self.sp(start, end, duration)
00125 #        return pointcloud_to_np(resp.cloud)
00126 #
00127 #    def scan(self, start, end, duration):
00128 #        resp = self.sp(start, end, duration)
00129 #        return resp.cloud
00130 
00131 ##
00132 # Iterator function for simplified filtered bag reading. Works with large bags/messages.
00133 #
00134 # @param file_name bag file name
00135 # @param topics list of topics that you care about (leave blank to get everything)
00136 # @return list of (topic_name, message, rostime) 
00137 def bag_iter(file_name, topics=[]):
00138     f = open(file_name)
00139     tdict = {}
00140     for t in topics:
00141         tdict[t] = True
00142 
00143     for r in rosrecord.logplayer(f):
00144         if tdict.has_key(r[0]):
00145             yield r
00146 
00147     f.close()
00148 
00149 ##
00150 # Select topics from a given bag.  Use this only if you're dealing with small
00151 # messages as not everything will fit into RAM.
00152 #
00153 # @param file_name bag file name
00154 # @param topics list of topics that you care about (leave blank to get everything)
00155 # @return dict with each entry containing a list of [(topic_name, message, rostime), (...), ...]
00156 def bag_sel_(file_name, topics=[]):
00157     print 'deprecated'
00158     d = {}
00159     for topic, msg, t in bag_iter(file_name, topics):
00160         if not d.has_key(topic):
00161             d[topic] = []
00162         d[topic].append((topic, msg, t.to_time()))
00163     return d
00164 
00165 def bag_sel(file_name, topics=[]):
00166     d = {}
00167     for topic, msg, t in bag_iter(file_name, topics):
00168         if not d.has_key(topic):
00169             d[topic] = {'topic':[], 'msg':[], 't':[]}
00170         d[topic]['topic'].append(topic)
00171         d[topic]['msg'].append(msg)
00172         d[topic]['t'].append(t.to_time())
00173         #d[topic].append((topic, msg, t.to_time()))
00174     return d
00175 
00176 ##
00177 # Used on ROS server (service provider) side to conveniently declare
00178 # a function that returns nothing as a service.
00179 #
00180 # ex.  obj = YourObject()
00181 #      rospy.Service('your_service', YourSrv, 
00182 #                    wrap(obj.some_function, 
00183 #                         # What that function should be given as input from the request
00184 #                         ['request_data_field_name1',  'request_data_field_name2'],
00185 #                         # Class to use when construction ROS response
00186 #                         response=SomeClass
00187 #                         ))
00188 def wrap(f, inputs=[], response=srv.EmptyResponse, verbose=False):
00189     def _f(request):
00190         arguments = [eval('request.' + arg) for arg in inputs]
00191         if verbose:
00192             print 'Function', f, 'called with args:', arguments
00193         try:
00194             returns = f(*arguments)
00195             if returns == None:
00196                 return response()
00197             else:
00198                 return response(*returns)
00199         except Exception, e:
00200             print e
00201     return _f
00202 
00203 def ignore_return(f):
00204     def _f(*args):
00205         f(*args)
00206     return _f
00207 
00208 class UnresponsiveServerError(Exception):
00209     def __init__(self, value):
00210         self.value = value
00211     def __str__(self):
00212         return repr(self.value)
00213 
00214 ##
00215 # Listens over ros network
00216 class FloatArrayListener:
00217     ##
00218     # Constructor
00219     #
00220     # @param node_name name of node if current process has not initialized ROS
00221     # @param listen_channel name of channel to listen to
00222     # @param frequency frequency this node should expect to get messages, 
00223     #        this value is used for determinining when messages are stale
00224     def __init__(self, node_name, listen_channel, frequency):
00225         try:
00226             print node_name, ': inited node.'
00227             rospy.init_node(node_name, anonymous=True)
00228         except rospy.ROSException, e:
00229             #print e
00230             pass
00231 
00232         self.reading             = None
00233         self.last_message_number = None
00234         self.last_msg_time       = None
00235         self.last_call_back      = None
00236 
00237         self.delay_tolerance     = 300.0 / 1000.0 #Because of Nagel's
00238         self.delay_time          = None
00239         self.time_out            = 1.2 #Because of Nagel's algorithm!!! FIX THIS WITH NEW ROS!
00240         self.count = 0
00241 
00242         self.error = False
00243 
00244         def callback(msg):
00245             msg_time      = msg.header.stamp.to_time()
00246             msg_number    = msg.header.seq
00247             self.reading  = np.matrix(msg.data, 'f').T, msg_number
00248 
00249             #Check for delayed messages
00250             if self.last_msg_time == None:
00251                 self.last_msg_time = msg_time
00252 
00253             time_diff = msg_time - self.last_msg_time
00254             if time_diff > self.delay_tolerance:
00255                 self.delay_time = msg_time - self.last_msg_time 
00256             #print 1000*time_diff
00257             self.last_msg_time  = msg_time
00258 
00259             ctime = time.time()
00260             #if self.last_call_back != None:
00261             #    print 1000.0*(ctime - self.last_call_back)
00262             #self.last_call_back = time.time()
00263             #if self.last_call_back != None:
00264             #    print 'last called back at %.2f ms ago, %d'% (1000*(ctime-self.last_call_back), self.count)
00265             self.last_call_back = ctime
00266             self.count = self.count + 1
00267 
00268         rospy.Subscriber(listen_channel, FloatArray, callback)
00269         self.node_name = node_name
00270         print node_name,': subscribed to', listen_channel
00271 
00272     def _check_timeout(self):
00273         if self.last_call_back != None:
00274             #ctime = time.time()
00275             time_diff = time.time() - self.last_call_back
00276             if time_diff > self.delay_tolerance:
00277                 print self.node_name, ': have not heard back from publisher in', 1000*time_diff, 'ms'
00278                 time.sleep(5/1000.0)
00279             
00280             if time_diff > 1.0:
00281                 self.error = True
00282 
00283             if time_diff > self.time_out:
00284                 #print 'raising hell!', ctime, self.last_call_back
00285                 #if self.times > 0:
00286                     #print 'Times', self.times
00287                 print "FloatArrayListener: Server have not responded for %.2f ms" % (1000 * time_diff)
00288                 #exit()
00289                 #raise UnresponsiveServerError("Server have not responded for %.2f ms" % (1000 * time_diff))
00290                 #else:
00291                 #    self.times = self.times + 1
00292 
00293 
00294     def read(self, fresh=True):
00295         if not fresh and self.reading == None:
00296             return None
00297         else:
00298             t = time.time()
00299             while self.reading  == None:
00300                 time.sleep(1.0)
00301                 print self.node_name, ': no readings for %.2f s' % (time.time() - t)
00302 
00303         reading = self.reading 
00304         if fresh:
00305             while reading[1] == self.last_message_number:
00306                 #self._check_timeout()
00307                 time.sleep(1/1000.0)
00308                 if self.delay_time != None:
00309                     delay_time = self.delay_time
00310                     self.delay_time = None #prevent multiple Exceptions from being thrown
00311                     print 'WARNING: delayed by', delay_time * 1000.0
00312                 reading = self.reading 
00313         else:
00314             self._check_timeout()
00315 
00316         self.last_message_number = reading[1]
00317         return reading[0]
00318 
00319 ##
00320 # Takes a normal ROS callback channel and gives it an on demand query style
00321 # interface.
00322 class GenericListener:
00323     ##
00324     # Message has to have a header
00325     # @param node_name name of node (if haven't been inited)
00326     # @param message_type type of message to listen for
00327     # @param listen_channel ROS channel to listen
00328     # @param frequency the frequency to expect messages (used to print warning statements to console)
00329     # @param message_extractor function to preprocess the message into a desired format
00330     # @param queue_size ROS subscriber queue (None = infinite)
00331     def __init__(self, node_name, message_type, listen_channel,
00332                  frequency, message_extractor=None, queue_size=None):
00333         try:
00334             print node_name, ': inited node.'
00335             rospy.init_node(node_name, anonymous=True)
00336         except rospy.ROSException, e:
00337             pass
00338         self.last_msg_returned   = None   #Last message returned to callers from this class
00339         self.last_call_back      = None   #Local time of last received message
00340         self.delay_tolerance     = 1/frequency #in seconds
00341         self.reading             = {'message':None, 'msg_id':-1}
00342         self.curid               = 0
00343         self.message_extractor = message_extractor
00344 
00345         def callback(*msg):
00346             #If this is a tuple (using message filter)
00347             if 'header' in dir(msg):
00348                 if msg.__class__ == ().__class__:
00349                     msg_number = msg[0].header.seq
00350                 else:
00351                     msg_number = msg.header.seq
00352             else:
00353                 msg_number = self.curid
00354                 self.curid += 1
00355 
00356             #*msg makes everything a tuple.  If length is one, msg = (msg, )
00357             if len(msg) == 1:
00358                 msg = msg[0]
00359             
00360             self.reading  = {'message':msg, 'msg_id':msg_number}
00361 
00362             #Check for delayed messages
00363             self.last_call_back = time.time() #record when we have been called back last
00364 
00365         if message_type.__class__ == [].__class__:
00366             import message_filters
00367             subscribers = [message_filters.Subscriber(channel, mtype) for channel, mtype in zip(listen_channel, message_type)]
00368             queue_size = 10
00369             ts = message_filters.TimeSynchronizer(subscribers, queue_size)
00370             ts.registerCallback(callback)
00371         else:
00372             rospy.Subscriber(listen_channel, message_type, callback,
00373                              queue_size = queue_size)
00374 
00375         self.node_name = node_name
00376         #print node_name,': subscribed to', listen_channel
00377         rospy.loginfo('%s: subscribed to %s' % (node_name, listen_channel))
00378 
00379     def _check_for_delivery_hiccups(self):
00380         #If have received a message in the past
00381         if self.last_call_back != None:
00382             #Calculate how it has been
00383             time_diff = time.time() - self.last_call_back
00384             #If it has been longer than expected hz, complain
00385             if time_diff > self.delay_tolerance:
00386                 print self.node_name, ': have not heard back from publisher in', time_diff, 's'
00387 
00388     def _wait_for_first_read(self, quiet=False):
00389         if not quiet:
00390             rospy.loginfo('%s: waiting for reading ...' % self.node_name)
00391         while self.reading['message'] == None and not rospy.is_shutdown():
00392             time.sleep(0.1)
00393             #if not quiet:
00394             #    print self.node_name, ': waiting for reading ...'
00395 
00396     ## 
00397     # Supported use cases
00398     # rfid   - want to get a reading, can be stale, no duplication allowed (allow None),        query speed important
00399     # hokuyo - want to get a reading, can be stale, no duplication allowed (don't want a None), willing to wait for new data (default)
00400     # ft     - want to get a reading, can be stale, duplication allowed    (don't want a None), query speed important
00401     # NOT ALLOWED                                   duplication allowed,                        willing to wait for new data
00402     def read(self, allow_duplication=False, willing_to_wait=True, warn=False, quiet=True):
00403         if allow_duplication:
00404             if willing_to_wait:
00405                 raise RuntimeError('Invalid settings for read.')
00406             else: 
00407                 # ft - want to get a reading, can be stale, duplication allowed (but don't want a None), query speed important
00408                 #self._wait_for_first_read(quiet)
00409                 reading                = self.reading
00410                 self.last_msg_returned = reading['msg_id']
00411                 if self.message_extractor is not None:
00412                     return self.message_extractor(reading['message'])
00413                 else:
00414                     return reading['message']
00415         else:
00416             if willing_to_wait:
00417                 # hokuyo - want to get a reading, can be stale, no duplication allowed (don't want a None), willing to wait for new data (default)
00418                 self._wait_for_first_read(quiet)
00419                 while self.reading['msg_id'] == self.last_msg_returned and not rospy.is_shutdown():
00420                     if warn:
00421                         self._check_for_delivery_hiccups()
00422                     time.sleep(1/1000.0)
00423                 reading = self.reading
00424                 self.last_msg_returned = reading['msg_id']
00425                 if self.message_extractor is not None:
00426                     return self.message_extractor(reading['message'])
00427                 else:
00428                     return reading['message']
00429             else:
00430                 # rfid   - want to get a reading, can be stale, no duplication allowed (allow None),        query speed important
00431                 if self.last_msg_returned == self.reading['msg_id']:
00432                     return None
00433                 else:
00434                     reading = self.reading
00435                     self.last_msg_returned = reading['msg_id']
00436                     if self.message_extractor is not None:
00437                         return self.message_extractor(reading['message'])
00438                     else:
00439                         return reading['message']
00440 
00441 ##
00442 #Class for registering as a subscriber to a specified topic, where
00443 #the messages are of a given type. Only calls the callback at a
00444 #prescribed rate.
00445 class RateListener():
00446     #Constructor.
00447     
00448     # Wraps the Subscriber class to only call the callback at
00449     # no quicker than the specified rate.
00450 
00451     #@param rate: time in seconds for subscriber to call callback
00452     #@type rate: float
00453     #@param name: graph resource name of topic, e.g. 'laser'.
00454     #@type  name: str
00455     #@param data_class: data type class to use for messages,
00456     #  e.g. std_msgs.msg.String
00457     #@type  data_class: L{Message} class
00458     #@param callback: function to call ( fn(data)) when data is
00459     #  received. If callback_args is set, the function must accept
00460     #  the callback_args as a second argument, i.e. fn(data,
00461     #  callback_args).  NOTE: Additional callbacks can be added using
00462     #  add_callback().
00463     #@type  callback: str
00464     #@param callback_args: additional arguments to pass to the
00465     #  callback. This is useful when you wish to reuse the same
00466     #  callback for multiple subscriptions.
00467     #@type  callback_args: any
00468     #@param queue_size: maximum number of messages to receive at
00469     #  a time. This will generally be 1 or None (infinite,
00470     #  default). buff_size should be increased if this parameter
00471     #  is set as incoming data still needs to sit in the incoming
00472     #  buffer before being discarded. Setting queue_size
00473     #  buff_size to a non-default value affects all subscribers to
00474     #  this topic in this process.
00475     #@type  queue_size: int
00476     #@param buff_size: incoming message buffer size in bytes. If
00477     #  queue_size is set, this should be set to a number greater
00478     #  than the queue_size times the average message size. Setting
00479     #  buff_size to a non-default value affects all subscribers to
00480     #  this topic in this process.
00481     #@type  buff_size: int
00482     #@param tcp_nodelay: if True, request TCP_NODELAY from
00483     #  publisher.  Use of this option is not generally recommended
00484     #  in most cases as it is better to rely on timestamps in
00485     #  message data. Setting tcp_nodelay to True enables TCP_NODELAY
00486     #  for all subscribers in the same python process.
00487     #@type  tcp_nodelay: bool
00488     #@raise ROSException: if parameters are invalid
00489     def __init__(self, rate, name, data_class, callback=None, callback_args=None,
00490                  queue_size=None, buff_size=DEFAULT_BUFF_SIZE, tcp_nodelay=False):
00491         self.rate = rate
00492         self.callback = callback
00493         self.lasttime = 0.0
00494         self.sub = rospy.Subscriber(name, data_class, self._process_msg, callback_args,
00495                               queue_size, buff_size, tcp_nodelay)
00496     
00497     def _process_msg(self, data, callback_args=None):
00498         delay = rospy.Time.now().to_sec() - self.lasttime
00499         if delay >= self.rate or self.lasttime == 0.0:
00500             if callback_args == None:
00501                 self.callback(data)
00502             else:
00503                 self.callback(data, callback_args)
00504             self.lasttime = rospy.Time.now().to_sec()
00505 
00506     def unregister(self):
00507         self.sub.unregister()
00508 
00509     def get_num_connections():
00510         return self.sub.get_num_connections()
00511 
00512 
00513 class RateCaller():
00514 
00515     def __init__(self, func, rate, args=None):
00516         self.func = func
00517         self.rate = rate
00518         self.args = args
00519         self.thread = None
00520         self.is_running = False
00521         self.beg_time = None
00522 
00523     def run(self):
00524         if not self.is_running:
00525             self.beg_time = time.time()
00526             self.num_time = 0
00527             self.thread = threading.Timer(self.rate, self._run)
00528             self.is_running = True
00529             self.thread.start()
00530 
00531     def _run(self):
00532         if self.is_running:
00533             if self.args is None:
00534                 self.func()
00535             else:
00536                 self.func(*self.args)
00537             self.num_time += 1
00538 
00539             diff_time = time.time() - self.beg_time
00540             timer_len = self.rate * (self.num_time + 1) - diff_time
00541             if timer_len <= 0.:
00542                 timer_len = 0.
00543             self.thread = threading.Timer(timer_len, self._run)
00544             self.thread.start()
00545 
00546     def stop(self):
00547         if self.thread is not None and self.is_running:
00548             self.thread.cancel()
00549             self.is_running = False
00550 
00551 #class TransformBroadcaster:
00552 #
00553 #    def __init__(self):
00554 #        self.pub_tf = rospy.Publisher("/tf", tf.msg.tfMessage)
00555 #
00556 #    ## send transform as a tfmessage.
00557 #    # @param tf_stamped - object of class TransformStamped (rosmsg show TransformStamped)
00558 #    def send_transform(self,tf_stamped):
00559 #        tfm = tf.msg.tfMessage([tf_stamped])
00560 #        self.pub_tf.publish(tfm)
00561 
00562 ##
00563 # Calls the service with the given name and given parameters and returns
00564 # the output of the service.
00565 # @param service_name the full name of the service to be called
00566 # @param params the list of parameters to be passed into the service
00567 # @filename name of a pickle object to be created if not None
00568 def call_save_service(service_name, service_def, params, filename=None):
00569     srv = rospy.ServiceProxy(service_name, service_def)
00570     try:
00571         resp = srv(*params)
00572         if not filename is None:
00573             save_pickle(resp, filename)
00574         srv.close()
00575         return resp
00576     except rospy.ServiceException, e:
00577         print "Service error"
00578     srv.close()
00579     return None
00580 
00581 
00582 
00583 
00584 
00585 
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 
00609 
00610 
00611 
00612 
00613 
00614 
00615 
00616 
00617 
00618 
00619 
00620 
00621 
00622 
00623 
00624 
00625 
00626 
00627 
00628 
00629 
00630 
00631 
00632 
00633 
00634 
00635 
00636 
00637 #class ROSPoll:
00638 #    def __init__(self, topic, type):
00639 #        self.data       = None
00640 #        self.t          = time.time()
00641 #        self.old        = self.t
00642 #        self.subscriber = rospy.TopicSub(topic, type, self.callback)
00643 #
00644 #    def callback(self, data):
00645 #        self.data = data
00646 #        self.t    = time.time()
00647 #
00648 #    ##
00649 #    # Returns only fresh data!
00650 #    def read(self):
00651 #        t = time.time()
00652 #        while self.old == self.t:
00653 #            time.sleep(.1)
00654 #            if (time.time() - t) > 3.0:
00655 #                print 'ROSPoll: failed to read. Did you do a rospy.init_node(name)?'
00656 #                return None
00657 #        self.old = self.t
00658 #        return self.data
00659 #
00660 ##
00661 # Sample Code
00662 #if __name__ == '__main__':
00663 #    from pkg import *
00664 #    from urg_driver.msg import urg as UrgMessage
00665 #    rospy.init_node('test') #Important before doing anything ROS related!
00666 #
00667 #    poller = ROSPoll('urg', UrgMessage)
00668 #    msg    = poller.read()
00669 #    print msg.__class__
00670 
00671 
00672     #def _check_freshness(self, current_time):
00673     #    if self.last_received_time != None:
00674     #        time_diff = current_time - self.last_received_time
00675     #        #print '%.2f' %( time_diff * 1000.0)
00676     #        if time_diff > self.stale_tolerance:
00677     #            self.throw_exception = time_diff
00678     #def _stale_alert(self):
00679     #    if self.throw_exception != None:
00680     #        self.throw_exception = None
00681     #        raise RuntimeError('Have not heard from publisher for %.2f ms' % (1000.0 * self.throw_exception))
00682 
00683 ###
00684 ## Wrapper helper function
00685 #def empty(f):
00686 #    def _f(request):
00687 #        print 'Request', request, ' for function', f, 'received.'
00688 #        try:
00689 #            f()
00690 #        except Exception, e:
00691 #            print e
00692 #        return srv.EmptyResponse()
00693 #    return _f
00694 
00695     #def read(self, fresh=True, no_wait, warn=True):
00696     #    #if reading
00697     #    reading = self.reading 
00698     #    if reading != None:
00699     #        if fresh:
00700     #            #While the current message is equal the the last message we returned caller
00701     #            while reading['msg_id'] == self.last_msg_returned:
00702     #                if warn:
00703     #                    self._check_for_delivery_hiccups()
00704     #                reading = self.reading 
00705     #                time.sleep(1/1000.0)
00706     #            self.last_msg_returned = reading['msg_id']
00707     #            return reading['message']
00708 
00709     #        elif allow_duplicates:
00710     #            self.last_msg_returned = reading['msg_id']
00711     #            return reading['message']
00712 
00713     #        else:
00714     #            #not fresh & don't allow duplicates
00715     #            if reading['msg_id'] == self.last_msg_returned:
00716     #                return None
00717     #            else:
00718     #                self.last_msg_returned = reading['msg_id']
00719     #                return reading['message']
00720     #    else:
00721     #        fresh and allow_duplicates
00722     #        fresh and not allow_duplicates
00723     #        not fresh and not allow_duplicates
00724     #        not fresh and allow_duplicates
00725 
00726 
00727 
00728 
00729 
00730    #     #Is this the first time we have been called?
00731    #     if not fresh and self.reading == None:
00732    #         return None
00733    #     else:
00734    #         while self.reading  == None:
00735    #             time.sleep(.3)
00736    #             print self.node_name, ': waiting for reading ...'
00737 
00738    #     reading = self.reading 
00739    #     if fresh:
00740    #         #While the current message is equal the the last message we returned caller
00741    #         while reading[1] == self.last_msg_returned:
00742    #             if warn:
00743    #                 self._check_for_delivery_hiccups()
00744    #             #if self.delay_time != None:
00745    #             #    delay_time = self.delay_time
00746    #             #    self.delay_time = None #prevent multiple Exceptions from being thrown
00747    #             #    if warn:
00748    #             #        print 'WARNING: delayed by', delay_time * 1000.0
00749    #             reading = self.reading 
00750    #             time.sleep(1/1000.0)
00751    #     else:
00752    #         self._check_timeout()
00753 
00754    #     self.last_msg_returned = reading[1]
00755    #     return reading[0]


hrl_lib
Author(s): Cressel Anderson, Travis Deyle, Advait Jain, Hai Nguyen, Advisor: Prof. Charlie Kemp, Lab: Healthcare Robotics Lab at Georgia Tech
autogenerated on Wed Nov 27 2013 11:34:06