@@ -74,6 +74,8 @@ def __init__(self, realtime=True, display=True):
74
74
self .realtime = realtime
75
75
self .display = display
76
76
77
+ self .recording = False
78
+
77
79
if self .display and sw is None :
78
80
_import_swift ()
79
81
@@ -96,11 +98,11 @@ def launch(self):
96
98
sw .start_servers (self .outq , self .inq )
97
99
self .last_time = time .time ()
98
100
99
- def step (self , dt = 50 ):
101
+ def step (self , dt = 0.05 ):
100
102
"""
101
103
Update the graphical scene
102
104
103
- :param dt: time step in milliseconds , defaults to 50
105
+ :param dt: time step in seconds , defaults to 0.05
104
106
:type dt: int, optional
105
107
106
108
``env.step(args)`` triggers an update of the 3D scene in the Swift
@@ -133,11 +135,11 @@ def step(self, dt=50):
133
135
134
136
# If realtime is set, delay progress if we are running too quickly
135
137
if self .realtime :
136
- time_taken = (time .time () - self .last_time ) * 1000
138
+ time_taken = (time .time () - self .last_time )
137
139
diff = dt - time_taken
138
140
139
141
if diff > 0 :
140
- time .sleep (diff / 1000 )
142
+ time .sleep (diff )
141
143
142
144
self .last_time = time .time ()
143
145
@@ -251,6 +253,46 @@ def remove(self):
251
253
252
254
super ().remove ()
253
255
256
+ def start_recording (self , file_name , framerate ):
257
+ """
258
+ Start recording the canvas in the Swift simulator
259
+
260
+ :param file_name: The file name for which the video will be saved as
261
+ :type file_name: string
262
+ :param framerate: The framerate of the video - to be timed correctly,
263
+ this should equalt 1 / dt where dt is the time supplied to the
264
+ step function
265
+ :type framerate: float
266
+
267
+ ``env.start_recording(file_name)`` starts recording the simulation
268
+ scene and will save it as file_name once
269
+ ``env.start_recording(file_name)`` is called
270
+ """
271
+
272
+ if not self .recording :
273
+ self ._send_socket ('start_recording' , [framerate , file_name ])
274
+ self .recording = True
275
+ else :
276
+ raise ValueError (
277
+ "You are already recording, you can only record one video"
278
+ " at a time" )
279
+
280
+ def stop_recording (self ):
281
+ """
282
+ Start recording the canvas in the Swift simulator. This is optional
283
+ as the video will be automatically saved when the python script exits
284
+
285
+ ``env.stop_recording()`` stops the recording of the simulation, can
286
+ only be called after ``env.start_recording(file_name)``
287
+ """
288
+
289
+ if self .recording :
290
+ self ._send_socket ('stop_recording' )
291
+ else :
292
+ raise ValueError (
293
+ "You must call swift.start_recording(file_name) before trying"
294
+ " to stop the recording" )
295
+
254
296
def _step_robots (self , dt ):
255
297
256
298
for robot in self .robots :
@@ -261,7 +303,7 @@ def _step_robots(self, dt):
261
303
if robot .control_type == 'v' :
262
304
263
305
for i in range (robot .n ):
264
- robot .q [i ] += robot .qd [i ] * (dt / 1000 )
306
+ robot .q [i ] += robot .qd [i ] * (dt )
265
307
266
308
if np .any (robot .qlim [:, i ] != 0 ) and \
267
309
not np .any (np .isnan (robot .qlim [:, i ])):
@@ -285,8 +327,8 @@ def _step_shapes(self, dt):
285
327
t = T .t
286
328
r = T .rpy ('rad' )
287
329
288
- t += shape .v [:3 ] * (dt / 1000 )
289
- r += shape .v [3 :] * (dt / 1000 )
330
+ t += shape .v [:3 ] * (dt )
331
+ r += shape .v [3 :] * (dt )
290
332
291
333
shape .base = sm .SE3 (t ) * sm .SE3 .RPY (r )
292
334
@@ -298,7 +340,7 @@ def _draw_all(self):
298
340
for i in range (len (self .shapes )):
299
341
self ._send_socket ('shape_poses' , [i , self .shapes [i ].fk_dict ()])
300
342
301
- def _send_socket (self , code , data ):
343
+ def _send_socket (self , code , data = None ):
302
344
msg = [code , data ]
303
345
304
346
self .outq .put (msg )
0 commit comments