@@ -10,22 +10,66 @@ is run and in cooperation with the controller code (such as the code controlling
10
10
your robot). As a result, using ` time.time ` to know how long your robot has been
11
11
running for or ` time.sleep ` to wait for some duration may be unreliable.
12
12
13
- Instead the simulated ` Robot ` API provides some alternatives which you are
14
- encouraged to use instead.
13
+ ## Approaches
14
+
15
+ ### Existing projects: the ` Robot ` class
16
+
17
+ <!-- We should drop this after SR2020 and move `ManualTimestepRobot` to being the default. -->
18
+
19
+ For existing projects the default ` Robot ` class will automatically advance the
20
+ simulator all the time. This can make programming your robot slightly easier as
21
+ you don't need to worry about the progress of time and (just like a real robot)
22
+ you can assume that time passing will just happen.
23
+
24
+ However this has a drawback -- because the simulator advances time in small
25
+ chunks (rather than the smooth progression we're used to in reality) it can mean
26
+ that your robots actions sometimes run for slightly more or less time than you
27
+ expect. While the time difference will be small (a few tens of milliseconds), it
28
+ is likely to impact attempts at more precise movement more than larger actions
29
+ due to their shorter time.
30
+
31
+ This may mean for example that turning by a small angle to line up with a token
32
+ will sometimes work and sometimes point the robot in not quite the right
33
+ direction.
34
+
35
+ If your robot code is impacted by these unpredictability issues we recommend
36
+ that you change over to using the ` ManualTimestepRobot ` class instead. For
37
+ guidance on doing this, see the [ upgrade guide] ( #upgrading ) below.
38
+
39
+ This class is maintained for compatibility with earlier releases of the
40
+ simulator, though its use is discouraged (especially for new projects).
41
+
42
+ ### New projects: the ` ManualTimestepRobot ` class {#manual-timestep-robot}
43
+
44
+ For new projects, or existing projects that want to be sure of getting precise
45
+ robot behaviour, the recommended approach is to use the ` ManualTimestepRobot `
46
+ class.
47
+
48
+ This approach relies upon your code advancing the simulation explicitly by
49
+ calling its ` sleep ` method (documented below) in order for the simulation to
50
+ actually run. This should not be an issue for most robot code however as you
51
+ will likely be doing this anyway in order to wait for things to happen.
52
+
53
+ <div class =" info " >
54
+ If you find that the simulator freezes then this indicates that your code is
55
+ busy doing something without giving the simulator a chance to run.
56
+
57
+ This usually indicates that you have a loop somewhere which is expecting time
58
+ to advance on its own and which should be modified to call <code >R.sleep</code >
59
+ occasionally (even a very small value will allow the simulator to progress).
60
+ </div >
15
61
16
62
## Sleeping
17
63
18
64
If you want to wait for something to happen within the simulation, and you can
19
65
be reasonably confident that it will take a given amount of time, you can use
20
- ` Robot. sleep` method to pause your code for a given duration.
66
+ ` sleep ` method on your robot to pause your code for a given duration.
21
67
22
68
Internally this uses the simulation's own clock and so is suitable for use in
23
69
place of ` time.sleep ` . Note that, just as with ` time.sleep ` , while your code is
24
70
sleeping your robot will continue any actions it was doing.
25
71
26
72
``` python
27
- R = Robot()
28
-
29
73
# Blink the output
30
74
R.ruggeduinos[0 ].digital_write(A_PIN , 1 )
31
75
R.sleep(1.5 ) # Sleep for a second and a half of simulation time
@@ -35,16 +79,14 @@ R.ruggeduinos[0].digital_write(A_PIN, 0)
35
79
## Getting the current time
36
80
37
81
If you need to measure the time since some previous moment within the simulator,
38
- ` Robot. time` can be used in place of ` time.time ` to get a number (in seconds)
39
- which increases in line with simulation time.
82
+ your robot has a ` time ` method which can be used in place of ` time.time ` to get
83
+ a number (in seconds) that increases in line with simulation time.
40
84
41
85
Time zero as returned by this method is the point at which the simulation began,
42
86
however you should not rely on that being a useful reference point as it may not
43
87
be the moment at which the _ match_ began.
44
88
45
89
``` python
46
- R = Robot()
47
-
48
90
then = R.time()
49
91
50
92
# .. do some other things ..
@@ -53,3 +95,71 @@ now = R.time()
53
95
54
96
duration = now - then
55
97
```
98
+
99
+ ## Changing from ` Robot ` to ` ManualTimestepRobot ` {#upgrading}
100
+
101
+ The changes needed to move from using ` Robot ` to ` ManualTimestepRobot ` are
102
+ fairly small since both classes have the same interface. This means that
103
+ anywhere in the docs a <code >Robot</code > is used, you can also use a
104
+ <code >ManualTimestepRobot</code >.
105
+
106
+ 1 . Anywhere that your code mentions ` Robot ` , change it to ` ManualTimestepRobot ` ,
107
+ for example:
108
+
109
+ ``` python
110
+ from sr.robot import Robot # change this
111
+
112
+ R = Robot() # change this
113
+
114
+ R.motors[0 ].m1.power = 20 # this stays the same
115
+ ```
116
+
117
+ should be changed to:
118
+
119
+ ``` python
120
+ from sr.robot import ManualTimestepRobot
121
+
122
+ R = ManualTimestepRobot()
123
+
124
+ R.motors[0 ].m1.power = 20
125
+ ```
126
+
127
+ 2 . Remove any usages of either `time.time` or `time.sleep` and replace them with
128
+ the equivalent robot methods (documented above). For example:
129
+
130
+ ``` python
131
+ import time # remove this everywhere
132
+
133
+ start = time.time()
134
+ time.sleep(1.2 )
135
+ print (" I slept for {} seconds" .format(time.time() - start))
136
+ ```
137
+
138
+ should be changed to:
139
+
140
+ ``` python
141
+ start = R.time()
142
+ R.sleep(1.2 )
143
+ print (" I slept for {} seconds" .format(R.time() - start))
144
+ ```
145
+
146
+ 3 . Check for any places where you have code which expect that `R.time()` will
147
+ increase on its own and ensure that they sleep for at least a very small
148
+ amount of time on each iteration. For example:
149
+
150
+ ``` python
151
+ end = R.time() + 5
152
+ while R.time() < end:
153
+ if has_touched_something(R):
154
+ break
155
+ ```
156
+
157
+ should be changed to:
158
+
159
+ ``` python
160
+ end = R.time() + 5
161
+ while R.time() < end:
162
+ R.sleep(0.01 ) # note addition of this line
163
+ if has_touched_something(R):
164
+ break
165
+ ```
0 commit comments