Simulation environment¶
Processes¶
Simulations schedule calls to a number of “processes” into an infinite loop,
which represents the control loop of the robot. A process is a simple wrapper
around an on_tick()
function, which is called at each iteration of the
simulation loop.
-
class
pymanoid.proc.
Process
¶ Processes implement the
on_tick
method called by the simulation.-
on_tick
(sim)¶ Main function called by the simulation at each control cycle.
- Parameters
sim (Simulation) – Current simulation instance.
-
pause
()¶ Stop calling the process at new clock ticks.
-
resume
()¶ Resume calling the process at new clock ticks.
-
Simulation¶
The simulation object is both a global environment and a serial process
scheduler. As an environment, it is passed as argument when calling the
on_tick()
functions of child processes, and also contains a number of
fields, such as dt
(simulation time step) or gravity
(gravity vector in
the world frame).
-
class
pymanoid.sim.
Simulation
(dt, env_path=None, env_xml=None)¶ Simulation objects are the entry point of pymanoid scripts (similar to OpenRAVE environments, which they wrap).
- Parameters
dt (real) – Time interval between two ticks in simulation time.
env_path (string, optional) – Load environment from XML/DAE file.
env_xml (string, optional) – Load environment from XML string.
-
dt
¶ Simulation timestep, that is, time interval between two ticks in simulation time. The default value of 30 [ms] is chosen so that stock simulations run real-time on modern computers. Lower simulation steps make forward integration more precise, but will result in loss of real-timeness at some point (a simulation runs real-time when the computer spends less than
dt
to carry out all computations at every tick, so that it takes N seconds of real time to simulate N seconds of simulation time).- Type
scalar, optional
-
property
camera_transform
¶ Camera transform in the world frame.
-
load_mesh
(path)¶ Load a pymanoid.Body from a DAE or VRML model.
- Parameters
path (string) – Path to DAE or VRML model.
-
log_comp_time
(label, ctime)¶ Log computation time for a given process.
- Parameters
label (string) – Label of the operation.
ctime (scalar) – Computation time in [s].
-
move_camera_to
(T, duration=0.0, dt=0.03)¶ Continuously move the camera frame to a target transform.
- Parameters
T ((4, 4) array) – Target transform.
duration (scalar, optional) – Motion duration.
dt (scalar, optional) – Time step between intermeditate camera transforms.
-
record
(fname=None)¶ Record simulation video.
- Parameters
fname (string, optional) – Video file name.
-
run_thread
()¶ Run simulation thread.
-
schedule
(process, paused=False, log_comp_times=False)¶ Add a process to the schedule list.
- Parameters
process (pymanoid.Process) – Process that will be called at every simulation tick.
paused (bool, optional) – If True, the process will be initially paused.
Note
The order in which processes are scheduled does matter.
-
schedule_extra
(process)¶ Schedule a Process not counted in the computation time budget.
-
set_background
(color=None)¶ Set viewer background color.
- Parameters
color (string, RGB tuple or None) – Background color.
-
set_camera_back
(x=None, y=None, z=None)¶ Align camera axis with the x-axis of the world frame.
- Parameters
x (scalar or None) – Camera translation along x-axis of the world frame.
y (scalar or None) – Camera translation along y-axis of the world frame.
z (scalar or None) – Camera translation along z-axis of the world frame.
-
set_camera_bottom
(x=None, y=None, z=None)¶ Align camera axis with the z-axis of the world frame.
- Parameters
x (scalar or None) – Camera translation along x-axis of the world frame.
y (scalar or None) – Camera translation along y-axis of the world frame.
z (scalar or None) – Camera translation along z-axis of the world frame.
-
set_camera_front
(x=None, y=None, z=None)¶ Align camera axis opposite to the x-axis of the world frame.
- Parameters
x (scalar or None) – Camera translation along x-axis of the world frame.
y (scalar or None) – Camera translation along y-axis of the world frame.
z (scalar or None) – Camera translation along z-axis of the world frame.
-
set_camera_left
(x=None, y=None, z=None)¶ Align camera axis opposite to the y-axis of the world frame.
- Parameters
x (scalar or None) – Camera translation along x-axis of the world frame.
y (scalar or None) – Camera translation along y-axis of the world frame.
z (scalar or None) – Camera translation along z-axis of the world frame.
-
set_camera_right
(x=None, y=None, z=None)¶ Align camera axis with the y-axis of the world frame.
- Parameters
x (scalar or None) – Camera translation along x-axis of the world frame.
y (scalar or None) – Camera translation along y-axis of the world frame.
z (scalar or None) – Camera translation along z-axis of the world frame.
-
set_camera_top
(x=None, y=None, z=None)¶ Align camera axis opposite to the z-axis of the world frame.
- Parameters
x (scalar or None) – Camera translation along x-axis of the world frame.
y (scalar or None) – Camera translation along y-axis of the world frame.
z (scalar or None) – Camera translation along z-axis of the world frame.
-
set_camera_transform
(T)¶ Set camera transform.
- Parameters
T ((4, 4) array) – Target transform.
Notes
See also
pymanoid.sim.Simulation.move_camera_to()
.
-
set_viewer
(plugin='qtcoin')¶ Open OpenRAVE viewer.
- Parameters
plugin (string, optional) – Viewer plugin name (‘qtcoin’ or ‘qtosg’), defaults to ‘qtcoin’.
-
start
()¶ Start simulation thread.
-
step
(n=1)¶ Perform a given number of simulation steps (default is one).
- Parameters
n (int, optional) – Number of simulation steps.
-
unschedule
(process)¶ Remove a process to the schedule list.
- Parameters
process (pymanoid.Process) – Process that will be called at every simulation tick.
Camera recording¶
To record a video of your simulation, schedule a camera recorder as follows:
sim = pymanoid.Simulation(dt=0.03)
camera_recorder = pymanoid.CameraRecorder(sim, fname="my_video.mp4")
sim.schedule_extra(camera_recorder)
Upon scheduling the camera recorder, the following message will appear in your Python shell:
Please click on the OpenRAVE window.
The mouse pointer changes to a cross. While it is like this, click on the OpenRAVE window (so that the recorder knows which window to record from). Then, start or step your simulation as usual.
When your simulation is over, run the video conversion script created in the current directory:
./make_pymanoid_video.sh
After completion, the file my_video.mp4
is created in the current
directory.
-
class
pymanoid.proc.
CameraRecorder
(sim, fname=None, tmp_folder='pymanoid_rec')¶ Video recording process.
When created, this process will ask the user to click on the OpenRAVE GUI to get its window ID. Then, it will save a screenshot in the camera folder at each tick of the simulation (don’t expect real-time recording…). When your simulation is over, go to the camera folder and run the script called
make_video.sh
.- Parameters
sim (Simulation) – Simulation instance.
fname (string, optional) – Video file name.
tmp_folder (string, optional) – Temporary folder where screenshots will be recorded.
Note
Creating videos requires the following dependencies (here listed for Ubuntu 14.04):
sudo apt-get install x11-utils imagemagick libav-tools
.Note
Don’t expect the simulation to run real-time while recording.
Note
The GUI window should stay visible on your screen for the whole duration of the recording. Also, don’t resize it, otherwise video conversion will fail later on.
-
on_tick
(sim)¶ Main function called by the simulation at each control cycle.
- Parameters
sim (Simulation) – Current simulation instance.
-
wait_for
(wait_time)¶ Pause the video by repeating the last frame for a certain duration.
- Parameters
wait_time (scalar) – Duration in [s].
Making a new process¶
Imagine we want to record knee angles while the robot moves in the horizontal walking example. We can create a new process class:
class KneeAngleRecorder(pymanoid.Process):
def __init__(self):
"""
Initialize process. Don't forget to call parent constructor.
"""
super(KneeAngleRecorder, self).__init__()
self.left_knee_angles = []
self.right_knee_angles = []
self.times = []
def on_tick(self, sim):
"""
Update function run at every simulation tick.
Parameters
----------
sim : Simulation
Instance of the current simulation.
"""
self.left_knee_angles.append(robot.q[robot.left_knee])
self.right_knee_angles.append(robot.q[robot.right_knee])
self.times.append(sim.time)
To execute it, we instantiate a process of this class and add it to the
simulation right before the call to start_walking()
:
recorder = KneeAngleRecorder()
sim.schedule_extra(recorder)
start_walking() # comment this out to start walking manually
We can plot the data recorded in this process at any time by:
import pylab
pylab.ion()
pylab.plot(recorder.times, recorder.left_knee_angles)
pylab.plot(recorder.times, recorder.right_knee_angles)
Note that we scheduled the recorder as an extra process, using
sim.schedule_extra
rather than sim.schedule
, so that it does not get
counted in the computation time budget of the control loop.