Time and event in MORSE

This page presents the inner workings 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 Blender’s Game Engine

Here is some pseudo-code that describes the behaviour of Blender’s Game Engine (for Blender < 2.78 at least):

# 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 graphics 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 can support it) 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 calls to default_action to match the desired frequency, as specified in the builder script (using morse.builder.abstractcomponent.AbstractComponent.frequency()). Internally, The execution frequency of the sensor, actuator, or 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. This is controllable using the morse.builder.environment.Environment()’s time_auto_tune flag. The default settings are:

  • best effort
  • base_frequency is selected according to the fastest component specified in the builder script
  • v-sync is disabled

Accessing time

In the simulator itself, you can access the simulated time via morse.core.blenderapi.persistantstorage().time.time. This returns the simulated time as the number of seconds (as a float) since Epoch, as done by time.time(). More precisely, at startup, the simulation is initialized with time.time() and then progresses depending on the selected strategy. The precision depends of the underlying 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 as the time as seen by the current robot. To do that, you must call the method morse.core.robot.Robot.gettime(). This allows different modifiers to be added for different robots, triggering all the interesting temporal issues you must address in multi-robot situations. The Clock exposes the time, as seen by a specific robot.

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