File: real-time-simulations.rst

package info (click to toggle)
python-simpy3 3.0.11-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,080 kB
  • sloc: python: 2,885; makefile: 138
file content (90 lines) | stat: -rw-r--r-- 3,111 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
.. _realtime:

=====================
Real-time simulations
=====================

Sometimes, you might not want to perform a simulation as fast as possible but
synchronous to 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 :class:`~simpy.core.Environment` with
a :class:`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:

.. code-block:: python

   >>> 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:

.. code-block:: python

   >>> 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``:

.. code-block:: python

   >>> 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!