This is another guide to SimPy simulations. SimPy ususally runs simulations as fast as possible, but sometimes, you might want your simulation to run synchronized with the wall-clock time. This kind of simulation is also called real-time simulation.
Real-time simulations may be necessary
- if you have hardware-in-the-loop,
- if there is human interaction with your simulation, or
- if you want to analyze the real-time behavior of an algorithm.
To convert a simulation into a real-time simulation, you only need to replace SimPy’s default Environment with a simpy.rt.RealtimeEnvironment. Apart from the initial_time argument, there are two additional parameters: factor and strict: RealtimeEnvironment(initial_time=0, factor=1.0, strict=True).
The factor defines how much real time passes with each step of simulation time. By default, this is one second. If you set factor=0.1, a unit of simulation time will only take a tenth of a second; if you set factor=60, it will take a minute.
Here is a simple example for converting a normal simulation to a real-time simulation with a duration of one tenth of a second per simulation time unit:
>>> import time >>> import simpy >>> >>> def example(env): ... start = time.perf_counter() ... yield env.timeout(1) ... end = time.perf_counter() ... print('Duration of one simulation time unit: %.2fs' % (end - start)) >>> >>> env = simpy.Environment() >>> proc = env.process(example(env)) >>> env.run(until=proc) Duration of one simulation time unit: 0.00s >>> >>> import simpy.rt >>> env = simpy.rt.RealtimeEnvironment(factor=0.1) >>> proc = env.process(example(env)) >>> env.run(until=proc) Duration of one simulation time unit: 0.10s
If the strict parameter is set to True (the default), the step() and run() methods will raise a RuntimeError if the computation within a simulation time step take more time than the real-time factor allows. In the following example, a process will perform a task that takes 0.02 seconds within a real-time environment with a time factor of 0.01 seconds:
>>> import time >>> import simpy.rt >>> >>> def slow_proc(env): ... time.sleep(0.02) # Heavy computation :-) ... yield env.timeout(1) >>> >>> env = simpy.rt.RealtimeEnvironment(factor=0.01) >>> proc = env.process(slow_proc(env)) >>> try: ... env.run(until=proc) ... print('Everything alright') ... except RuntimeError: ... print('Simulation is too slow') Simulation is too slow
To suppress the error, simply set strict=False:
>>> env = simpy.rt.RealtimeEnvironment(factor=0.01, strict=False) >>> proc = env.process(slow_proc(env)) >>> try: ... env.run(until=proc) ... print('Everything alright') ... except RuntimeError: ... print('Simulation is too slow') Everything alright
That’s it. Real-time simulations are that simple with SimPy! This guide is now also part of the official SimPy documentation.