SimPy: Real-time simulations
Posted on
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.