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.