Package rospy :: Module rostime

Source Code for Module rospy.rostime

  1  # Software License Agreement (BSD License) 
  2  # 
  3  # Copyright (c) 2008, Willow Garage, Inc. 
  4  # All rights reserved. 
  5  # 
  6  # Redistribution and use in source and binary forms, with or without 
  7  # modification, are permitted provided that the following conditions 
  8  # are met: 
  9  # 
 10  #  * Redistributions of source code must retain the above copyright 
 11  #    notice, this list of conditions and the following disclaimer. 
 12  #  * Redistributions in binary form must reproduce the above 
 13  #    copyright notice, this list of conditions and the following 
 14  #    disclaimer in the documentation and/or other materials provided 
 15  #    with the distribution. 
 16  #  * Neither the name of Willow Garage, Inc. nor the names of its 
 17  #    contributors may be used to endorse or promote products derived 
 18  #    from this software without specific prior written permission. 
 19  # 
 20  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 21  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 22  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 23  # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 24  # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 25  # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 26  # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 27  # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 28  # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 29  # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 30  # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 31  # POSSIBILITY OF SUCH DAMAGE. 
 32  # 
 33  # Revision $Id$ 
 34   
 35  """ 
 36  ROS time and duration representations, as well as internal routines 
 37  for managing wallclock versus a simulated clock.  The important data 
 38  classes are L{Time} and L{Duration}, which represent the ROS 'time' 
 39  and 'duration' primitives, respectively. 
 40  """ 
 41   
 42  import sys 
 43  import threading 
 44  import time 
 45  import traceback 
 46   
 47  import rospy.exceptions 
 48   
 49  import genpy 
 50   
 51  ## /time support. This hooks into the rospy Time representation and 
 52  ## allows it to be overriden with data from the /time topic. 
 53   
 54  _rostime_initialized = False 
 55  _rostime_current = None 
 56  _rostime_cond = threading.Condition() 
57 58 # subclass genpy to provide abstraction layer 59 -class Duration(genpy.Duration):
60 """ 61 Duration represents the ROS 'duration' primitive type, which 62 consists of two integers: seconds and nanoseconds. The Duration 63 class allows you to add and subtract Duration instances, including 64 adding and subtracting from L{Time} instances. 65 66 Usage:: 67 five_seconds = Duration(5) 68 five_nanoseconds = Duration(0, 5) 69 70 print 'Fields are', five_seconds.secs, five_seconds.nsecs 71 72 # Duration arithmetic 73 ten_seconds = five_seconds + five_seconds 74 five_secs_ago = rospy.Time.now() - five_seconds # Time minus Duration is a Time 75 76 true_val = ten_second > five_seconds 77 """ 78 __slots__ = [] 79
80 - def __init__(self, secs=0, nsecs=0):
81 """ 82 Create new Duration instance. secs and nsecs are integers and 83 correspond to the ROS 'duration' primitive type. 84 85 @param secs: seconds 86 @type secs: int 87 @param nsecs: nanoseconds 88 @type nsecs: int 89 """ 90 super(Duration, self).__init__(secs, nsecs)
91
92 - def __repr__(self):
93 return 'rospy.Duration[%d]' % self.to_nsec()
94
95 -class Time(genpy.Time):
96 """ 97 Time represents the ROS 'time' primitive type, which consists of two 98 integers: seconds since epoch and nanoseconds since seconds. Time 99 instances are mutable. 100 101 The L{Time.now()} factory method can initialize Time to the 102 current ROS time and L{from_sec()} can be used to create a 103 Time instance from the Python's time.time() float seconds 104 representation. 105 106 The Time class allows you to subtract Time instances to compute 107 Durations, as well as add Durations to Time to create new Time 108 instances. 109 110 Usage:: 111 now = rospy.Time.now() 112 zero_time = rospy.Time() 113 114 print 'Fields are', now.secs, now.nsecs 115 116 # Time arithmetic 117 five_secs_ago = now - rospy.Duration(5) # Time minus Duration is a Time 118 five_seconds = now - five_secs_ago # Time minus Time is a Duration 119 true_val = now > five_secs_ago 120 121 # NOTE: in general, you will want to avoid using time.time() in ROS code 122 import time 123 py_time = rospy.Time.from_sec(time.time()) 124 """ 125 __slots__ = [] 126
127 - def __init__(self, secs=0, nsecs=0):
128 """ 129 Constructor: secs and nsecs are integers and correspond to the 130 ROS 'time' primitive type. You may prefer to use the static 131 L{from_sec()} and L{now()} factory methods instead. 132 133 @param secs: seconds since epoch 134 @type secs: int 135 @param nsecs: nanoseconds since seconds (since epoch) 136 @type nsecs: int 137 """ 138 super(Time, self).__init__(secs, nsecs)
139
140 - def __repr__(self):
141 return 'rospy.Time[%d]' % self.to_nsec()
142 143 @staticmethod
144 - def now():
145 """ 146 Create new L{Time} instance representing current time. This 147 can either be wall-clock time or a simulated clock. It is 148 strongly recommended that you use the now() factory to create 149 current time representations instead of reading wall-clock 150 time and create Time instances from it. 151 152 @return: L{Time} instance for current time 153 @rtype: L{Time} 154 """ 155 return get_rostime()
156 157 # have to reproduce super class implementation to return correct typing 158
159 - def from_seconds(float_secs):
160 """ 161 Use Time.from_sec() instead. Retained for backwards compatibility. 162 163 @param float_secs: time value in time.time() format 164 @type float_secs: float 165 @return: Time instance for specified time 166 @rtype: L{Time} 167 """ 168 return Time.from_sec(float_secs)
169 170 from_seconds = staticmethod(from_seconds) 171
172 - def from_sec(float_secs):
173 """ 174 Create new Time instance from a float seconds representation 175 (e.g. time.time()). 176 177 @param float_secs: time value in time.time() format 178 @type float_secs: float 179 @return: Time instance for specified time 180 @rtype: L{Time} 181 """ 182 secs = int(float_secs) 183 nsecs = int((float_secs - secs) * 1000000000) 184 return Time(secs, nsecs)
185 186 from_sec = staticmethod(from_sec)
187
188 -def _set_rostime(t):
189 """Callback to update ROS time from a ROS Topic""" 190 if isinstance(t, genpy.Time): 191 t = Time(t.secs, t.nsecs) 192 elif not isinstance(t, Time): 193 raise ValueError("must be Time instance: %s"%t.__class__) 194 global _rostime_current 195 _rostime_current = t 196 try: 197 _rostime_cond.acquire() 198 _rostime_cond.notifyAll() 199 finally: 200 _rostime_cond.release()
201
202 -def get_rostime():
203 """ 204 Get the current time as a L{Time} object 205 @return: current time as a L{rospy.Time} object 206 @rtype: L{Time} 207 """ 208 if not _rostime_initialized: 209 raise rospy.exceptions.ROSInitException("time is not initialized. Have you called init_node()?") 210 if _rostime_current is not None: 211 # initialize with sim time 212 return _rostime_current 213 else: 214 # initialize with wallclock 215 float_secs = time.time() 216 secs = int(float_secs) 217 nsecs = int((float_secs - secs) * 1000000000) 218 return Time(secs, nsecs)
219
220 -def get_time():
221 """ 222 Get the current time as float secs (time.time() format) 223 @return: time in secs (time.time() format) 224 @rtype: float 225 """ 226 return Time.now().to_sec()
227
228 -def set_rostime_initialized(val):
229 """ 230 Internal use. 231 Mark rostime as initialized. This flag enables other routines to 232 throw exceptions if rostime is being used before the underlying 233 system is initialized. 234 @param val: value for initialization state 235 @type val: bool 236 """ 237 global _rostime_initialized 238 _rostime_initialized = val
239
240 -def is_rostime_initialized():
241 """ 242 Internal use. 243 @return: True if rostime has been initialized 244 @rtype: bool 245 """ 246 return _rostime_initialized
247
248 -def get_rostime_cond():
249 """ 250 internal API for helper routines that need to wait on time updates 251 @return: rostime conditional var 252 @rtype: threading.Cond 253 """ 254 return _rostime_cond
255
256 -def is_wallclock():
257 """ 258 Internal use for ROS-time routines. 259 @return: True if ROS is currently using wallclock time 260 @rtype: bool 261 """ 262 return _rostime_current == None
263
264 -def switch_to_wallclock():
265 """ 266 Internal use. 267 Switch ROS to wallclock time. This is mainly for testing purposes. 268 """ 269 global _rostime_current 270 _rostime_current = None 271 try: 272 _rostime_cond.acquire() 273 _rostime_cond.notifyAll() 274 finally: 275 _rostime_cond.release()
276
277 -def wallsleep(duration):
278 """ 279 Internal use. 280 Windows interrupts time.sleep with an IOError exception 281 when a signal is caught. Even when the signal is handled 282 by a callback, it will then proceed to throw IOError when 283 the handling has completed. 284 285 Refer to https://code.ros.org/trac/ros/ticket/3421. 286 287 So we create a platform dependant wrapper to handle this 288 here. 289 """ 290 if sys.platform in ['win32']: # cygwin seems to be ok 291 try: 292 time.sleep(duration) 293 except IOError: 294 pass 295 else: 296 time.sleep(duration)
297