We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
rospy.sleep(): request for specific exception if time moved backwards
I kindly request for the TODO of rospy.sleep() in [rospy.timer.py](https://github.com/ros/ros_comm/blob/hydro-devel/clients/rospy/src/rospy/timer.py) to be implemented and use a specific exception if ros time moved backwards.
I had trouble to find the cause of a python node shutting down, when using 'rosbag play -l --clock bagfile'. When the implementation follows the ros tutorials on python the ROSInterruptException is always catched:

``` python
if __name__ == '__main__':
    try:
        talker()
    except rospy.ROSInterruptException: pass
```

And there is no error message telling you, that time moved backwards.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `clients/rospy/src/rospy/timer.py`
Content:
```
1 # Software License Agreement (BSD License)
2 #
3 # Copyright (c) 2010, 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: __init__.py 12069 2010-11-09 20:31:55Z kwc $
34 
35 import threading
36 import time
37 
38 # for Time, Duration
39 import genpy
40 
41 import rospy.core
42 import rospy.rostime
43 
44 # author: tfield (Timers)
45 # author: kwc (Rate, sleep)
46 
47 class Rate(object):
48     """
49     Convenience class for sleeping in a loop at a specified rate
50     """
51     
52     def __init__(self, hz):
53         """
54         Constructor.
55         @param hz: hz rate to determine sleeping
56         @type  hz: int
57         """
58         # #1403
59         self.last_time = rospy.rostime.get_rostime()
60         self.sleep_dur = rospy.rostime.Duration(0, int(1e9/hz))
61 
62     def sleep(self):
63         """
64         Attempt sleep at the specified rate. sleep() takes into
65         account the time elapsed since the last successful
66         sleep().
67         
68         @raise ROSInterruptException: if ROS time is set backwards or if
69         ROS shutdown occurs before sleep completes
70         """
71         curr_time = rospy.rostime.get_rostime()
72         # detect time jumping backwards
73         if self.last_time > curr_time:
74             self.last_time = curr_time
75 
76         # calculate sleep interval
77         elapsed = curr_time - self.last_time
78         sleep(self.sleep_dur - elapsed)
79         self.last_time = self.last_time + self.sleep_dur
80 
81         # detect time jumping forwards, as well as loops that are
82         # inherently too slow
83         if curr_time - self.last_time > self.sleep_dur * 2:
84             self.last_time = curr_time
85 
86 # TODO: may want more specific exceptions for sleep
87 def sleep(duration):
88     """
89     sleep for the specified duration in ROS time. If duration
90     is negative, sleep immediately returns.
91     
92     @param duration: seconds (or rospy.Duration) to sleep
93     @type  duration: float or Duration
94     @raise ROSInterruptException: if ROS time is set backwards or if
95     ROS shutdown occurs before sleep completes
96     """
97     if rospy.rostime.is_wallclock():
98         if isinstance(duration, genpy.Duration):
99             duration = duration.to_sec()
100         if duration < 0:
101             return
102         else:
103             rospy.rostime.wallsleep(duration)
104     else:
105         initial_rostime = rospy.rostime.get_rostime()
106         if not isinstance(duration, genpy.Duration):
107             duration = genpy.Duration.from_sec(duration)
108 
109         rostime_cond = rospy.rostime.get_rostime_cond()
110 
111         # #3123
112         if initial_rostime == genpy.Time(0):
113             # break loop if time is initialized or node is shutdown
114             while initial_rostime == genpy.Time(0) and \
115                       not rospy.core.is_shutdown():
116                 with rostime_cond:
117                     rostime_cond.wait(0.3)
118                 initial_rostime = rospy.rostime.get_rostime()
119 
120         sleep_t = initial_rostime + duration
121 
122         # break loop if sleep_t is reached, time moves backwards, or
123         # node is shutdown
124         while rospy.rostime.get_rostime() < sleep_t and \
125               rospy.rostime.get_rostime() >= initial_rostime and \
126                   not rospy.core.is_shutdown():
127             with rostime_cond:
128                 rostime_cond.wait(0.5)
129 
130         if rospy.rostime.get_rostime() < initial_rostime:
131             raise rospy.exceptions.ROSInterruptException("ROS time moved backwards")
132         if rospy.core.is_shutdown():
133             raise rospy.exceptions.ROSInterruptException("ROS shutdown request")
134 
135 class TimerEvent(object):
136     """
137     Constructor.
138     @param last_expected: in a perfect world, this is when the previous callback should have happened
139     @type  last_expected: rospy.Time
140     @param last_real: when the callback actually happened
141     @type  last_real: rospy.Time
142     @param current_expected: in a perfect world, this is when the current callback should have been called
143     @type  current_expected: rospy.Time
144     @param last_duration: contains the duration of the last callback (end time minus start time) in seconds.
145                           Note that this is always in wall-clock time.
146     @type  last_duration: float
147     """
148     def __init__(self, last_expected, last_real, current_expected, current_real, last_duration):
149         self.last_expected    = last_expected
150         self.last_real        = last_real
151         self.current_expected = current_expected
152         self.current_real     = current_real
153         self.last_duration    = last_duration
154 
155 class Timer(threading.Thread):
156     """
157     Convenience class for calling a callback at a specified rate
158     """
159 
160     def __init__(self, period, callback, oneshot=False):
161         """
162         Constructor.
163         @param period: desired period between callbacks
164         @type  period: rospy.Time
165         @param callback: callback to be called
166         @type  callback: function taking rospy.TimerEvent
167         @param oneshot: if True, fire only once, otherwise fire continuously until shutdown is called [default: False]
168         @type  oneshot: bool
169         """
170         threading.Thread.__init__(self)
171         self._period   = period
172         self._callback = callback
173         self._oneshot  = oneshot
174         self._shutdown = False
175         self.setDaemon(True)
176         self.start()
177 
178     def shutdown(self):
179         """
180         Stop firing callbacks.
181         """
182         self._shutdown = True
183         
184     def run(self):
185         r = Rate(1.0 / self._period.to_sec())
186         current_expected = rospy.rostime.get_rostime() + self._period
187         last_expected, last_real, last_duration = None, None, None
188         while not rospy.core.is_shutdown() and not self._shutdown:
189             r.sleep()
190             if self._shutdown:
191                 break
192             current_real = rospy.rostime.get_rostime()
193             start = time.time()
194             self._callback(TimerEvent(last_expected, last_real, current_expected, current_real, last_duration))
195             if self._oneshot:
196                 break
197             last_duration = time.time() - start
198             last_expected, last_real = current_expected, current_real
199             current_expected += self._period
200
```

Path: `clients/rospy/src/rospy/exceptions.py`
Content:
```
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 """rospy exception types"""
36 
37 class ROSException(Exception): 
38     """
39     Base exception class for ROS clients
40     """
41     pass    
42 
43 class ROSSerializationException(ROSException):
44     """
45     Exception for message serialization errors
46     """    
47     pass
48 
49 class ROSInitException(ROSException):
50     """
51     Exception for errors initializing ROS state
52     """    
53     pass
54 
55 class ROSInterruptException(ROSException, KeyboardInterrupt):
56     """
57     Exception for operations that interrupted, e.g. due to shutdown.
58 
59     This is a subclass of both L{ROSException} and KeyboardInterrupt
60     so that it can be used in logic tht expects either.
61     """    
62     pass
63 
64 class ROSInternalException(Exception):
65     """
66     Base class for exceptions that are internal to the ROS system
67     """    
68     pass
69 
70 class TransportException(ROSInternalException):
71     """
72     Base class for transport-related exceptions
73     """    
74     pass
75 
76 class TransportTerminated(TransportException):
77     """
78     Internal class for representing broken connections
79     """    
80     pass
81 
82 class TransportInitError(TransportException):
83     """
84     Internal exception for representing exceptions that occur
85     establishing transports
86     """
87     pass
88 
89
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/clients/rospy/src/rospy/exceptions.py b/clients/rospy/src/rospy/exceptions.py
--- a/clients/rospy/src/rospy/exceptions.py
+++ b/clients/rospy/src/rospy/exceptions.py
@@ -61,6 +61,15 @@
     """    
     pass
 
+class ROSTimeMovedBackwardsException(ROSInterruptException): 
+    """
+    Exception if time moved backwards
+    """
+    def __init__(self, time):
+        self.time = time
+        """The amount of time in seconds."""
+        super(ROSTimeMovedBackwardsException, self).__init__("ROS time moved backwards")
+
 class ROSInternalException(Exception):
     """
     Base class for exceptions that are internal to the ROS system
diff --git a/clients/rospy/src/rospy/timer.py b/clients/rospy/src/rospy/timer.py
--- a/clients/rospy/src/rospy/timer.py
+++ b/clients/rospy/src/rospy/timer.py
@@ -65,8 +65,10 @@
         account the time elapsed since the last successful
         sleep().
         
-        @raise ROSInterruptException: if ROS time is set backwards or if
-        ROS shutdown occurs before sleep completes
+        @raise ROSInterruptException: if ROS shutdown occurs before
+        sleep completes
+        @raise ROSTimeMovedBackwardsException: if ROS time is set
+        backwards
         """
         curr_time = rospy.rostime.get_rostime()
         # detect time jumping backwards
@@ -83,7 +85,6 @@
         if curr_time - self.last_time > self.sleep_dur * 2:
             self.last_time = curr_time
 
-# TODO: may want more specific exceptions for sleep
 def sleep(duration):
     """
     sleep for the specified duration in ROS time. If duration
@@ -91,8 +92,10 @@
     
     @param duration: seconds (or rospy.Duration) to sleep
     @type  duration: float or Duration
-    @raise ROSInterruptException: if ROS time is set backwards or if
-    ROS shutdown occurs before sleep completes
+    @raise ROSInterruptException: if ROS shutdown occurs before sleep
+    completes
+    @raise ROSTimeMovedBackwardsException: if ROS time is set
+    backwards
     """
     if rospy.rostime.is_wallclock():
         if isinstance(duration, genpy.Duration):
@@ -128,7 +131,9 @@
                 rostime_cond.wait(0.5)
 
         if rospy.rostime.get_rostime() < initial_rostime:
-            raise rospy.exceptions.ROSInterruptException("ROS time moved backwards")
+            time_jump = (initial_rostime - rospy.rostime.get_rostime()).to_sec()
+            rospy.core.logerr("ROS time moved backwards: %ss", time_jump)
+            raise rospy.exceptions.ROSTimeMovedBackwardsException(time_jump)
         if rospy.core.is_shutdown():
             raise rospy.exceptions.ROSInterruptException("ROS shutdown request")

{"golden_diff": "diff --git a/clients/rospy/src/rospy/exceptions.py b/clients/rospy/src/rospy/exceptions.py\n--- a/clients/rospy/src/rospy/exceptions.py\n+++ b/clients/rospy/src/rospy/exceptions.py\n@@ -61,6 +61,15 @@\n     \"\"\"    \n     pass\n \n+class ROSTimeMovedBackwardsException(ROSInterruptException): \n+    \"\"\"\n+    Exception if time moved backwards\n+    \"\"\"\n+    def __init__(self, time):\n+        self.time = time\n+        \"\"\"The amount of time in seconds.\"\"\"\n+        super(ROSTimeMovedBackwardsException, self).__init__(\"ROS time moved backwards\")\n+\n class ROSInternalException(Exception):\n     \"\"\"\n     Base class for exceptions that are internal to the ROS system\ndiff --git a/clients/rospy/src/rospy/timer.py b/clients/rospy/src/rospy/timer.py\n--- a/clients/rospy/src/rospy/timer.py\n+++ b/clients/rospy/src/rospy/timer.py\n@@ -65,8 +65,10 @@\n         account the time elapsed since the last successful\n         sleep().\n         \n-        @raise ROSInterruptException: if ROS time is set backwards or if\n-        ROS shutdown occurs before sleep completes\n+        @raise ROSInterruptException: if ROS shutdown occurs before\n+        sleep completes\n+        @raise ROSTimeMovedBackwardsException: if ROS time is set\n+        backwards\n         \"\"\"\n         curr_time = rospy.rostime.get_rostime()\n         # detect time jumping backwards\n@@ -83,7 +85,6 @@\n         if curr_time - self.last_time > self.sleep_dur * 2:\n             self.last_time = curr_time\n \n-# TODO: may want more specific exceptions for sleep\n def sleep(duration):\n     \"\"\"\n     sleep for the specified duration in ROS time. If duration\n@@ -91,8 +92,10 @@\n     \n     @param duration: seconds (or rospy.Duration) to sleep\n     @type  duration: float or Duration\n-    @raise ROSInterruptException: if ROS time is set backwards or if\n-    ROS shutdown occurs before sleep completes\n+    @raise ROSInterruptException: if ROS shutdown occurs before sleep\n+    completes\n+    @raise ROSTimeMovedBackwardsException: if ROS time is set\n+    backwards\n     \"\"\"\n     if rospy.rostime.is_wallclock():\n         if isinstance(duration, genpy.Duration):\n@@ -128,7 +131,9 @@\n                 rostime_cond.wait(0.5)\n \n         if rospy.rostime.get_rostime() < initial_rostime:\n-            raise rospy.exceptions.ROSInterruptException(\"ROS time moved backwards\")\n+            time_jump = (initial_rostime - rospy.rostime.get_rostime()).to_sec()\n+            rospy.core.logerr(\"ROS time moved backwards: %ss\", time_jump)\n+            raise rospy.exceptions.ROSTimeMovedBackwardsException(time_jump)\n         if rospy.core.is_shutdown():\n             raise rospy.exceptions.ROSInterruptException(\"ROS shutdown request\")\n", "issue": "rospy.sleep(): request for specific exception if time moved backwards\nI kindly request for the TODO of rospy.sleep() in [rospy.timer.py](https://github.com/ros/ros_comm/blob/hydro-devel/clients/rospy/src/rospy/timer.py) to be implemented and use a specific exception if ros time moved backwards.\nI had trouble to find the cause of a python node shutting down, when using 'rosbag play -l --clock bagfile'. When the implementation follows the ros tutorials on python the ROSInterruptException is always catched:\n\n``` python\nif __name__ == '__main__':\n    try:\n        talker()\n    except rospy.ROSInterruptException: pass\n```\n\nAnd there is no error message telling you, that time moved backwards.\n\n", "before_files": [{"content": "# Software License Agreement (BSD License)\n#\n# Copyright (c) 2010, Willow Garage, Inc.\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions\n# are met:\n#\n#  * Redistributions of source code must retain the above copyright\n#    notice, this list of conditions and the following disclaimer.\n#  * Redistributions in binary form must reproduce the above\n#    copyright notice, this list of conditions and the following\n#    disclaimer in the documentation and/or other materials provided\n#    with the distribution.\n#  * Neither the name of Willow Garage, Inc. nor the names of its\n#    contributors may be used to endorse or promote products derived\n#    from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n# POSSIBILITY OF SUCH DAMAGE.\n#\n# Revision $Id: __init__.py 12069 2010-11-09 20:31:55Z kwc $\n\nimport threading\nimport time\n\n# for Time, Duration\nimport genpy\n\nimport rospy.core\nimport rospy.rostime\n\n# author: tfield (Timers)\n# author: kwc (Rate, sleep)\n\nclass Rate(object):\n    \"\"\"\n    Convenience class for sleeping in a loop at a specified rate\n    \"\"\"\n    \n    def __init__(self, hz):\n        \"\"\"\n        Constructor.\n        @param hz: hz rate to determine sleeping\n        @type  hz: int\n        \"\"\"\n        # #1403\n        self.last_time = rospy.rostime.get_rostime()\n        self.sleep_dur = rospy.rostime.Duration(0, int(1e9/hz))\n\n    def sleep(self):\n        \"\"\"\n        Attempt sleep at the specified rate. sleep() takes into\n        account the time elapsed since the last successful\n        sleep().\n        \n        @raise ROSInterruptException: if ROS time is set backwards or if\n        ROS shutdown occurs before sleep completes\n        \"\"\"\n        curr_time = rospy.rostime.get_rostime()\n        # detect time jumping backwards\n        if self.last_time > curr_time:\n            self.last_time = curr_time\n\n        # calculate sleep interval\n        elapsed = curr_time - self.last_time\n        sleep(self.sleep_dur - elapsed)\n        self.last_time = self.last_time + self.sleep_dur\n\n        # detect time jumping forwards, as well as loops that are\n        # inherently too slow\n        if curr_time - self.last_time > self.sleep_dur * 2:\n            self.last_time = curr_time\n\n# TODO: may want more specific exceptions for sleep\ndef sleep(duration):\n    \"\"\"\n    sleep for the specified duration in ROS time. If duration\n    is negative, sleep immediately returns.\n    \n    @param duration: seconds (or rospy.Duration) to sleep\n    @type  duration: float or Duration\n    @raise ROSInterruptException: if ROS time is set backwards or if\n    ROS shutdown occurs before sleep completes\n    \"\"\"\n    if rospy.rostime.is_wallclock():\n        if isinstance(duration, genpy.Duration):\n            duration = duration.to_sec()\n        if duration < 0:\n            return\n        else:\n            rospy.rostime.wallsleep(duration)\n    else:\n        initial_rostime = rospy.rostime.get_rostime()\n        if not isinstance(duration, genpy.Duration):\n            duration = genpy.Duration.from_sec(duration)\n\n        rostime_cond = rospy.rostime.get_rostime_cond()\n\n        # #3123\n        if initial_rostime == genpy.Time(0):\n            # break loop if time is initialized or node is shutdown\n            while initial_rostime == genpy.Time(0) and \\\n                      not rospy.core.is_shutdown():\n                with rostime_cond:\n                    rostime_cond.wait(0.3)\n                initial_rostime = rospy.rostime.get_rostime()\n\n        sleep_t = initial_rostime + duration\n\n        # break loop if sleep_t is reached, time moves backwards, or\n        # node is shutdown\n        while rospy.rostime.get_rostime() < sleep_t and \\\n              rospy.rostime.get_rostime() >= initial_rostime and \\\n                  not rospy.core.is_shutdown():\n            with rostime_cond:\n                rostime_cond.wait(0.5)\n\n        if rospy.rostime.get_rostime() < initial_rostime:\n            raise rospy.exceptions.ROSInterruptException(\"ROS time moved backwards\")\n        if rospy.core.is_shutdown():\n            raise rospy.exceptions.ROSInterruptException(\"ROS shutdown request\")\n\nclass TimerEvent(object):\n    \"\"\"\n    Constructor.\n    @param last_expected: in a perfect world, this is when the previous callback should have happened\n    @type  last_expected: rospy.Time\n    @param last_real: when the callback actually happened\n    @type  last_real: rospy.Time\n    @param current_expected: in a perfect world, this is when the current callback should have been called\n    @type  current_expected: rospy.Time\n    @param last_duration: contains the duration of the last callback (end time minus start time) in seconds.\n                          Note that this is always in wall-clock time.\n    @type  last_duration: float\n    \"\"\"\n    def __init__(self, last_expected, last_real, current_expected, current_real, last_duration):\n        self.last_expected    = last_expected\n        self.last_real        = last_real\n        self.current_expected = current_expected\n        self.current_real     = current_real\n        self.last_duration    = last_duration\n\nclass Timer(threading.Thread):\n    \"\"\"\n    Convenience class for calling a callback at a specified rate\n    \"\"\"\n\n    def __init__(self, period, callback, oneshot=False):\n        \"\"\"\n        Constructor.\n        @param period: desired period between callbacks\n        @type  period: rospy.Time\n        @param callback: callback to be called\n        @type  callback: function taking rospy.TimerEvent\n        @param oneshot: if True, fire only once, otherwise fire continuously until shutdown is called [default: False]\n        @type  oneshot: bool\n        \"\"\"\n        threading.Thread.__init__(self)\n        self._period   = period\n        self._callback = callback\n        self._oneshot  = oneshot\n        self._shutdown = False\n        self.setDaemon(True)\n        self.start()\n\n    def shutdown(self):\n        \"\"\"\n        Stop firing callbacks.\n        \"\"\"\n        self._shutdown = True\n        \n    def run(self):\n        r = Rate(1.0 / self._period.to_sec())\n        current_expected = rospy.rostime.get_rostime() + self._period\n        last_expected, last_real, last_duration = None, None, None\n        while not rospy.core.is_shutdown() and not self._shutdown:\n            r.sleep()\n            if self._shutdown:\n                break\n            current_real = rospy.rostime.get_rostime()\n            start = time.time()\n            self._callback(TimerEvent(last_expected, last_real, current_expected, current_real, last_duration))\n            if self._oneshot:\n                break\n            last_duration = time.time() - start\n            last_expected, last_real = current_expected, current_real\n            current_expected += self._period\n", "path": "clients/rospy/src/rospy/timer.py"}, {"content": "# Software License Agreement (BSD License)\n#\n# Copyright (c) 2008, Willow Garage, Inc.\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions\n# are met:\n#\n#  * Redistributions of source code must retain the above copyright\n#    notice, this list of conditions and the following disclaimer.\n#  * Redistributions in binary form must reproduce the above\n#    copyright notice, this list of conditions and the following\n#    disclaimer in the documentation and/or other materials provided\n#    with the distribution.\n#  * Neither the name of Willow Garage, Inc. nor the names of its\n#    contributors may be used to endorse or promote products derived\n#    from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n# POSSIBILITY OF SUCH DAMAGE.\n#\n# Revision $Id$\n\n\"\"\"rospy exception types\"\"\"\n\nclass ROSException(Exception): \n    \"\"\"\n    Base exception class for ROS clients\n    \"\"\"\n    pass    \n\nclass ROSSerializationException(ROSException):\n    \"\"\"\n    Exception for message serialization errors\n    \"\"\"    \n    pass\n\nclass ROSInitException(ROSException):\n    \"\"\"\n    Exception for errors initializing ROS state\n    \"\"\"    \n    pass\n\nclass ROSInterruptException(ROSException, KeyboardInterrupt):\n    \"\"\"\n    Exception for operations that interrupted, e.g. due to shutdown.\n\n    This is a subclass of both L{ROSException} and KeyboardInterrupt\n    so that it can be used in logic tht expects either.\n    \"\"\"    \n    pass\n\nclass ROSInternalException(Exception):\n    \"\"\"\n    Base class for exceptions that are internal to the ROS system\n    \"\"\"    \n    pass\n\nclass TransportException(ROSInternalException):\n    \"\"\"\n    Base class for transport-related exceptions\n    \"\"\"    \n    pass\n\nclass TransportTerminated(TransportException):\n    \"\"\"\n    Internal class for representing broken connections\n    \"\"\"    \n    pass\n\nclass TransportInitError(TransportException):\n    \"\"\"\n    Internal exception for representing exceptions that occur\n    establishing transports\n    \"\"\"\n    pass\n\n", "path": "clients/rospy/src/rospy/exceptions.py"}], "after_files": [{"content": "# Software License Agreement (BSD License)\n#\n# Copyright (c) 2010, Willow Garage, Inc.\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions\n# are met:\n#\n#  * Redistributions of source code must retain the above copyright\n#    notice, this list of conditions and the following disclaimer.\n#  * Redistributions in binary form must reproduce the above\n#    copyright notice, this list of conditions and the following\n#    disclaimer in the documentation and/or other materials provided\n#    with the distribution.\n#  * Neither the name of Willow Garage, Inc. nor the names of its\n#    contributors may be used to endorse or promote products derived\n#    from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n# POSSIBILITY OF SUCH DAMAGE.\n#\n# Revision $Id: __init__.py 12069 2010-11-09 20:31:55Z kwc $\n\nimport threading\nimport time\n\n# for Time, Duration\nimport genpy\n\nimport rospy.core\nimport rospy.rostime\n\n# author: tfield (Timers)\n# author: kwc (Rate, sleep)\n\nclass Rate(object):\n    \"\"\"\n    Convenience class for sleeping in a loop at a specified rate\n    \"\"\"\n    \n    def __init__(self, hz):\n        \"\"\"\n        Constructor.\n        @param hz: hz rate to determine sleeping\n        @type  hz: int\n        \"\"\"\n        # #1403\n        self.last_time = rospy.rostime.get_rostime()\n        self.sleep_dur = rospy.rostime.Duration(0, int(1e9/hz))\n\n    def sleep(self):\n        \"\"\"\n        Attempt sleep at the specified rate. sleep() takes into\n        account the time elapsed since the last successful\n        sleep().\n        \n        @raise ROSInterruptException: if ROS shutdown occurs before\n        sleep completes\n        @raise ROSTimeMovedBackwardsException: if ROS time is set\n        backwards\n        \"\"\"\n        curr_time = rospy.rostime.get_rostime()\n        # detect time jumping backwards\n        if self.last_time > curr_time:\n            self.last_time = curr_time\n\n        # calculate sleep interval\n        elapsed = curr_time - self.last_time\n        sleep(self.sleep_dur - elapsed)\n        self.last_time = self.last_time + self.sleep_dur\n\n        # detect time jumping forwards, as well as loops that are\n        # inherently too slow\n        if curr_time - self.last_time > self.sleep_dur * 2:\n            self.last_time = curr_time\n\ndef sleep(duration):\n    \"\"\"\n    sleep for the specified duration in ROS time. If duration\n    is negative, sleep immediately returns.\n    \n    @param duration: seconds (or rospy.Duration) to sleep\n    @type  duration: float or Duration\n    @raise ROSInterruptException: if ROS shutdown occurs before sleep\n    completes\n    @raise ROSTimeMovedBackwardsException: if ROS time is set\n    backwards\n    \"\"\"\n    if rospy.rostime.is_wallclock():\n        if isinstance(duration, genpy.Duration):\n            duration = duration.to_sec()\n        if duration < 0:\n            return\n        else:\n            rospy.rostime.wallsleep(duration)\n    else:\n        initial_rostime = rospy.rostime.get_rostime()\n        if not isinstance(duration, genpy.Duration):\n            duration = genpy.Duration.from_sec(duration)\n\n        rostime_cond = rospy.rostime.get_rostime_cond()\n\n        # #3123\n        if initial_rostime == genpy.Time(0):\n            # break loop if time is initialized or node is shutdown\n            while initial_rostime == genpy.Time(0) and \\\n                      not rospy.core.is_shutdown():\n                with rostime_cond:\n                    rostime_cond.wait(0.3)\n                initial_rostime = rospy.rostime.get_rostime()\n\n        sleep_t = initial_rostime + duration\n\n        # break loop if sleep_t is reached, time moves backwards, or\n        # node is shutdown\n        while rospy.rostime.get_rostime() < sleep_t and \\\n              rospy.rostime.get_rostime() >= initial_rostime and \\\n                  not rospy.core.is_shutdown():\n            with rostime_cond:\n                rostime_cond.wait(0.5)\n\n        if rospy.rostime.get_rostime() < initial_rostime:\n            time_jump = (initial_rostime - rospy.rostime.get_rostime()).to_sec()\n            rospy.core.logerr(\"ROS time moved backwards: %ss\", time_jump)\n            raise rospy.exceptions.ROSTimeMovedBackwardsException(time_jump)\n        if rospy.core.is_shutdown():\n            raise rospy.exceptions.ROSInterruptException(\"ROS shutdown request\")\n\nclass TimerEvent(object):\n    \"\"\"\n    Constructor.\n    @param last_expected: in a perfect world, this is when the previous callback should have happened\n    @type  last_expected: rospy.Time\n    @param last_real: when the callback actually happened\n    @type  last_real: rospy.Time\n    @param current_expected: in a perfect world, this is when the current callback should have been called\n    @type  current_expected: rospy.Time\n    @param last_duration: contains the duration of the last callback (end time minus start time) in seconds.\n                          Note that this is always in wall-clock time.\n    @type  last_duration: float\n    \"\"\"\n    def __init__(self, last_expected, last_real, current_expected, current_real, last_duration):\n        self.last_expected    = last_expected\n        self.last_real        = last_real\n        self.current_expected = current_expected\n        self.current_real     = current_real\n        self.last_duration    = last_duration\n\nclass Timer(threading.Thread):\n    \"\"\"\n    Convenience class for calling a callback at a specified rate\n    \"\"\"\n\n    def __init__(self, period, callback, oneshot=False):\n        \"\"\"\n        Constructor.\n        @param period: desired period between callbacks\n        @type  period: rospy.Time\n        @param callback: callback to be called\n        @type  callback: function taking rospy.TimerEvent\n        @param oneshot: if True, fire only once, otherwise fire continuously until shutdown is called [default: False]\n        @type  oneshot: bool\n        \"\"\"\n        threading.Thread.__init__(self)\n        self._period   = period\n        self._callback = callback\n        self._oneshot  = oneshot\n        self._shutdown = False\n        self.setDaemon(True)\n        self.start()\n\n    def shutdown(self):\n        \"\"\"\n        Stop firing callbacks.\n        \"\"\"\n        self._shutdown = True\n        \n    def run(self):\n        r = Rate(1.0 / self._period.to_sec())\n        current_expected = rospy.rostime.get_rostime() + self._period\n        last_expected, last_real, last_duration = None, None, None\n        while not rospy.core.is_shutdown() and not self._shutdown:\n            r.sleep()\n            if self._shutdown:\n                break\n            current_real = rospy.rostime.get_rostime()\n            start = time.time()\n            self._callback(TimerEvent(last_expected, last_real, current_expected, current_real, last_duration))\n            if self._oneshot:\n                break\n            last_duration = time.time() - start\n            last_expected, last_real = current_expected, current_real\n            current_expected += self._period\n", "path": "clients/rospy/src/rospy/timer.py"}, {"content": "# Software License Agreement (BSD License)\n#\n# Copyright (c) 2008, Willow Garage, Inc.\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions\n# are met:\n#\n#  * Redistributions of source code must retain the above copyright\n#    notice, this list of conditions and the following disclaimer.\n#  * Redistributions in binary form must reproduce the above\n#    copyright notice, this list of conditions and the following\n#    disclaimer in the documentation and/or other materials provided\n#    with the distribution.\n#  * Neither the name of Willow Garage, Inc. nor the names of its\n#    contributors may be used to endorse or promote products derived\n#    from this software without specific prior written permission.\n#\n# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n# \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\n# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\n# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\n# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\n# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n# POSSIBILITY OF SUCH DAMAGE.\n#\n# Revision $Id$\n\n\"\"\"rospy exception types\"\"\"\n\nclass ROSException(Exception): \n    \"\"\"\n    Base exception class for ROS clients\n    \"\"\"\n    pass    \n\nclass ROSSerializationException(ROSException):\n    \"\"\"\n    Exception for message serialization errors\n    \"\"\"    \n    pass\n\nclass ROSInitException(ROSException):\n    \"\"\"\n    Exception for errors initializing ROS state\n    \"\"\"    \n    pass\n\nclass ROSInterruptException(ROSException, KeyboardInterrupt):\n    \"\"\"\n    Exception for operations that interrupted, e.g. due to shutdown.\n\n    This is a subclass of both L{ROSException} and KeyboardInterrupt\n    so that it can be used in logic tht expects either.\n    \"\"\"    \n    pass\n\nclass ROSTimeMovedBackwardsException(ROSInterruptException): \n    \"\"\"\n    Exception if time moved backwards\n    \"\"\"\n    def __init__(self, time):\n        self.time = time\n        \"\"\"The amount of time in seconds.\"\"\"\n        super(ROSTimeMovedBackwardsException, self).__init__(\"ROS time moved backwards\")\n\nclass ROSInternalException(Exception):\n    \"\"\"\n    Base class for exceptions that are internal to the ROS system\n    \"\"\"    \n    pass\n\nclass TransportException(ROSInternalException):\n    \"\"\"\n    Base class for transport-related exceptions\n    \"\"\"    \n    pass\n\nclass TransportTerminated(TransportException):\n    \"\"\"\n    Internal class for representing broken connections\n    \"\"\"    \n    pass\n\nclass TransportInitError(TransportException):\n    \"\"\"\n    Internal exception for representing exceptions that occur\n    establishing transports\n    \"\"\"\n    pass\n\n", "path": "clients/rospy/src/rospy/exceptions.py"}]}