@@ -74,6 +74,8 @@ def __init__(self, realtime=True, display=True):
7474 self .realtime = realtime
7575 self .display = display
7676
77+ self .recording = False
78+
7779 if self .display and sw is None :
7880 _import_swift ()
7981
@@ -96,11 +98,11 @@ def launch(self):
9698 sw .start_servers (self .outq , self .inq )
9799 self .last_time = time .time ()
98100
99- def step (self , dt = 50 ):
101+ def step (self , dt = 0.05 ):
100102 """
101103 Update the graphical scene
102104
103- :param dt: time step in milliseconds , defaults to 50
105+ :param dt: time step in seconds , defaults to 0.05
104106 :type dt: int, optional
105107
106108 ``env.step(args)`` triggers an update of the 3D scene in the Swift
@@ -133,11 +135,11 @@ def step(self, dt=50):
133135
134136 # If realtime is set, delay progress if we are running too quickly
135137 if self .realtime :
136- time_taken = (time .time () - self .last_time ) * 1000
138+ time_taken = (time .time () - self .last_time )
137139 diff = dt - time_taken
138140
139141 if diff > 0 :
140- time .sleep (diff / 1000 )
142+ time .sleep (diff )
141143
142144 self .last_time = time .time ()
143145
@@ -251,6 +253,46 @@ def remove(self):
251253
252254 super ().remove ()
253255
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+
254296 def _step_robots (self , dt ):
255297
256298 for robot in self .robots :
@@ -261,7 +303,7 @@ def _step_robots(self, dt):
261303 if robot .control_type == 'v' :
262304
263305 for i in range (robot .n ):
264- robot .q [i ] += robot .qd [i ] * (dt / 1000 )
306+ robot .q [i ] += robot .qd [i ] * (dt )
265307
266308 if np .any (robot .qlim [:, i ] != 0 ) and \
267309 not np .any (np .isnan (robot .qlim [:, i ])):
@@ -285,8 +327,8 @@ def _step_shapes(self, dt):
285327 t = T .t
286328 r = T .rpy ('rad' )
287329
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 )
290332
291333 shape .base = sm .SE3 (t ) * sm .SE3 .RPY (r )
292334
@@ -298,7 +340,7 @@ def _draw_all(self):
298340 for i in range (len (self .shapes )):
299341 self ._send_socket ('shape_poses' , [i , self .shapes [i ].fk_dict ()])
300342
301- def _send_socket (self , code , data ):
343+ def _send_socket (self , code , data = None ):
302344 msg = [code , data ]
303345
304346 self .outq .put (msg )
0 commit comments