Time and event in MORSE

This page presents the inner working of time in MORSE. If you are not yet familiar with time issues and you simply want to configure the time-related settings of your simulation, you should start here.

Understand time handling in the Blender’s Game Engine

A pseudo-code describing the behaviour of the Blender’s Game Engine (for Blender < 2.78 at least) is the following:

# main loop
while not_quit:
    # logic / physics loop
    for i in 0..n:
        execute_logic
            ...
            synchronise_with_external_clock # optionally
            ...
            ...
        execute_physics
    end

    execute_graphics # v-sync occurs here if enabled

The loop is centered around the graphic update. By default in Blender, v-sync is enabled, so the main loop is caped by the frequency of your screen (often 60 Hz). It is possible to disable v-sync (this lets MORSE reach higher frequencies, assuming your hardware permits) using morse.builder.environment.Environment.use_vsync(). Though, as shown in the pseudo-code, it is possible to run the logic / physics at higher frequency. This behaviour can be configured using the builder API using the method morse.builder.environment.Environment.simulator_frequency(). For instance, env.simulator_frequency(20) means that the main loop will run at 20Hz (if your hardware is powerful enough). The base_frequency is the frequency of the main loop by second. It will be adjusted automatically if you try to accelerate or slow-down the time (see below). The logic_step_max and physics_step_max are used to compute the maximum possible n in the previous loop.

While the simulation is running, during the execute_logic step, components actually invoke their default_action method via the Blender logic bricks. At this point the component will perform its task and update its internal data.

To run a component at a lower frequency, Morse will skip call to default_action to match desired frequency, as specified in the builder script (using morse.builder.abstractcomponent.AbstractComponent.frequency()). Internally, The execution frequency of the sensor | actuator | robot can be retrieved using the property morse.core.object.Object.frequency().

Default settings

Since Morse 1.4, Morse tries to compute the best settings for your simulation. It is controllable by the flag time_auto_tune from morse.builder.environment.Environment(). The default settings are the following:

  • Best Effort
  • base_frequency is selected according to the faster component specified in the builder script
  • v-sync is disabled

Accessing time

In the simulator itself, you can access to the simulated time via morse.core.blenderapi.persistantstorage().time.time. It returns the simulated time as the number of seconds (in float) since Epoch, as done by time.time(). More precisely, at startup, the simulated is initialized with time.time() and then progress depending of the selected strategy. The precision depends of the underlaying implementation of time.time() and the speed of simulation. If you run a simulation at 60 Hz, the simulator clock will be updated about every 15 ms.

Moreover, in a lot of situations, you do not want to access the simulated time directly, but at the time as seen by the current robot. To do that, you must call the method morse.core.robot.Robot.gettime(). It allows different modifiers to be added for different robots, triggering all the nice temporal issues you must address in multi-robot situations. The Clock exposes the time, as seen by a specific robot.

Last, a set of services in morse.services.time_services allows to retrieve the simulated time and various statistics about it.