forked from modelica/ModelicaStandardLibrary
-
Notifications
You must be signed in to change notification settings - Fork 1
/
StateGraph.mo
2815 lines (2567 loc) · 122 KB
/
StateGraph.mo
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
within Modelica;
package StateGraph
"Library of hierarchical state machine components to model discrete event and reactive systems"
extends Modelica.Icons.Package;
import Modelica.Units.SI;
package UsersGuide "User's Guide of StateGraph Library"
extends Modelica.Icons.Information;
class OverView "Overview of library"
extends Modelica.Icons.Information;
annotation (Documentation(info="<html>
<p>
In this section, an overview of the most important features
of this library is given.
</p>
<h4>Steps and Transitions</h4>
<p>
A <strong>StateGraph</strong> is an enhanced finite state machine.
It is based on the JGrafchart method and
takes advantage of Modelica features for
the \"action\" language. JGrafchart is a further development of
Grafcet to include elements of StateCharts that are not present
in Grafcet/Sequential Function Charts. Therefore, the StateGraph
library has a similar modeling power as StateCharts but avoids
some deficiencies of StateCharts.
</p>
<p>
The basic elements of StateGraphs are <strong>steps</strong> and <strong>transitions</strong>:
</p>
<div>
<img src=\"modelica://Modelica/Resources/Images/StateGraph/UsersGuide/StepAndTransition1.png\">
</div>
<p>
<strong>Steps</strong> represent the possible states a StateGraph can have.
If a step is active the Boolean variable <strong>active</strong> of
the step is <strong>true</strong>. If it is deactivated,
<strong>active</strong> = <strong>false</strong>. At the initial time, all \"usual\"
steps are deactivated. The <strong>InitialStep</strong> objects are steps
that are activated at the initial time. They are characterized
by a double box (see figure above).
</p>
<p>
<strong>Transitions</strong> are used to change the state of a StateGraph.
When the step connected to the input of a transition is active,
the step connected to the output of this transition is deactivated
and the transition condition becomes true, then the
transition fires. This means that the step connected to the input to the
transition is deactivated and the step connected to the output
of the transition is activated.
</p>
<p>
The transition <strong>condition</strong> is defined via the parameter menu
of the transition object. Clicking on object \"transition1\" in
the above figure, results in the following menu:
</p>
<div>
<img src=\"modelica://Modelica/Resources/Images/StateGraph/UsersGuide/StepAndTransition2.png\">
</div>
<p>
In the input field \"<strong>condition</strong>\", any type of time varying
Boolean expression can be given (in Modelica notation, this is
a modification of the time varying variable <strong>condition</strong>).
Whenever this condition is true, the transition can fire.
Additionally, it is possible to activate a timer, via
<strong>enableTimer</strong> (see menu above) and provide a
<strong>waitTime</strong>. In this case the firing of the transition
is delayed according to the provided waitTime. The transition
condition and the waitTime are displayed in the transition icon.
</p>
<p>
In the above example, the simulation starts at <strong>initialStep</strong>.
After 1 second, <strong>transition1</strong> fires and <strong>step1</strong> becomes
active. After another second <strong>transition2</strong> fires and
<strong>initialStep</strong> becomes again active. After a further
second <strong>step1</strong> becomes again active, and so on.
</p>
<p>
In JGrafcharts, Grafcet and Sequential Function Charts, the
network of steps and transitions is drawn from top to bottom.
In StateGraphs, no particular direction is defined, since
steps and transitions are blocks with input and output connectors
that can be arbitrarily placed and connected. Usually, it is
most practical to define the network from left to right,
as in the example above, since then it is easy to read the
labels on the icons.
</p>
<h4>Conditions and Actions</h4>
<p>
With the block <strong>TransitionWithSignal</strong>, the firing condition
can be provided as Boolean input signal, instead as entry in the
menu of the transition. An example is given in the next
figure:
</p>
<div>
<img src=\"modelica://Modelica/Resources/Images/StateGraph/UsersGuide/StepAndTransition3.png\">
</div>
<p>
Component \"step\" is an instance of \"StepWithSignal\" that is
a usual step where the active flag is available as Boolean
output signal. To this output, component \"Timer\" from
library \"Modelica.Blocks.Logical\" is connected. It measures the
time from the time instant where the Boolean input (i.e., the
active flag of the step) became true up to the current
time instant. The timer is connected to a comparison
component. The output is true, once the timer reaches
1 second. This signal is used as condition input of the
transition. As a result, \"transition2\" fires, once step
\"step\" has been active for 1 second.
Of course, any other
Modelica block with a Boolean output signal can be
connected to the condition input of such a transition block
as well.
</p>
<p>
Conditions of a transition can either be computed by
a network of logical blocks from the Logical library as
in the figure above, or via the \"SetBoolean\" component
any type of logical expression can be defined in textual
form, as shown in the next figure:
</p>
<div>
<img src=\"modelica://Modelica/Resources/Images/StateGraph/UsersGuide/StepAndTransition4.png\">
</div>
<p>
With the block \"<strong>SetBoolean</strong>\", a time varying expression
can be provided as modification to the output signal <strong>y</strong>
(see block with icon text \"timer.y > 1\" in the figure above).
The output signal can be in turn connected to the condition
input of a TransitionWithSignal block.
</p>
<p>
The \"<strong>SetBoolean</strong>\" block can also be used to
compute a Boolean signal depending on the active step.
In the figure above, the output of the block with the
icon text \"step.active\" is
true, when \"step\" is active, otherwise it is false
(note, the icon text of \"SetBoolean\" displays the modification
of the output signal \"y\").
This signal can then be used to compute desired <strong>actions</strong>
in the physical systems model. For example, if a <strong>valve</strong>
shall be open, when the StateGraph is in \"step1\" or
in \"step4\", a \"SetBoolean\" block may be connected to the
valve model using the following condition:
</p>
<blockquote><pre>
valve = step1.active <strong>or</strong> step2.active
</pre></blockquote>
<p>
Via the Modelica operators <strong>edge</strong>(..) and <strong>change</strong>(..),
conditions depending on rising and falling edges of
Boolean expressions can be used when needed.
</p>
<p>
In JGrafcharts, Grafcet, Sequential Function Charts and StateCharts,
<strong>actions</strong> are formulated <strong>within a step</strong>. Such actions are
distinguished as <strong>entry</strong>, <strong>normal</strong>, <strong>exit</strong> and
<strong>abort</strong> actions. For example, a valve might be opened by
an entry action of a step and might be closed by an exit
action of the same step. In StateGraphs, this is (fortunately)
<strong>not possible</strong>
due to Modelica's \"single assignment rule\" that requires that every
variable is defined by exactly one equation. Instead, the
approach explained above is used. For example, via the
\"SetBoolean\" component, the valve variable is set to true
when the StateGraph is in particular steps.
</p>
<p>
This feature of a StateGraph is <strong>very useful</strong>, since it allows
a Modelica translator to <strong>guarantee</strong> that a given StateGraph
has always <strong>deterministic</strong> behaviour without conflicts.
In the other methodologies this is much more cumbersome. For example,
if two steps are executed in parallel and both step actions
modify the same variable, the result is either non-deterministic
or non-obvious rules have to be defined which action
takes priority. In a StateGraph, such a situation is detected by
the translator resulting in an error, since there are two equations
to compute one variable. Additional benefits of the StateGraph
approach are:
</p>
<ul>
<li> A JGrafchart or a StateChart need to potentially access
variables in a step that are defined in
higher hierarchical levels of a model. Therefore, mostly <strong>global
variables</strong> are used in the whole network, even if the
network is structured hierarchically. In StateGraphs this
is not necessary, since the physical systems outside
of a StateGraph might access the step or transition state
via a hierarchical name. This means that <strong>no global variables</strong>
are needed, because the local variables in the StateGraph
are accessed from local variables outside of the StateGraph.
</li>
<li> It is simpler for a user to understand the information that
is provided in the non-graphical definition, since every
variable is defined at exactly one place. In the other
methodologies, the setting and re-setting of the same
variable is cluttered within the whole network.
</li>
</ul>
<p>
To emphasize this important difference between these methodologies,
consider the case that a state machine has the following
hierarchy:
</p>
<blockquote><pre>
stateMachine.superstate1.superstate2.step1
</pre></blockquote>
<p>
Within \"step1\" a StateChart would, e.g., access variable
\"stateMachine.openValve\", say as \"entry action: openValve = true\".
This typical usage has the severe drawback that it is not possible
to use the hierarchical state \"superstate1\" as component in another
context, because \"step1\" references a particular name outside of this
component.
</p>
<p>
In a StateGraph, there would be typically a \"SetBoolean\" component
in the \"stateMachine\" component stating:
</p>
<blockquote><pre>
openValve = superstate1.superstate2.step1.active;
</pre></blockquote>
<p>
As a result, the \"superstate1\" component can be used in
another context, because it does not depend on the environment
where it is used.
</p>
<h4>Execution Model</h4>
<p>
The execution model of a StateGraph follows from its
Modelica implementation: Given the states of all steps, i.e.,
whether a step is active or not active, the equations of all
steps, transitions, transition conditions, actions etc. are
sorted resulting in an execution sequence to compute
essentially the new values of the steps. If conflicts occur,
e.g., if there are more equations as variables, of if there
are algebraic loops between Boolean variables, an exception
is raised. Once all equations have been processed, the
<strong>active</strong> variables of all steps are updated to the newly
calculated values. Afterwards, the equations are again
evaluated. The iteration stops, once no step changes
its state anymore, i.e., once no transition fires anymore.
Then, simulation continuous until a new event is triggered,
(when a relation changes its value).
</p>
<p>
With the Modelica \"sample(..)\" operator, a StateGraph might also
be executed within a discrete controller that is called
at regular time instants. Furthermore, clocked state machines
are directly supported by the Modelica language itself, see <a href=\"https://specification.modelica.org/v3.4/Ch17.html\">Section 17 (State Machines) of the Modelica 3.4 specification</a>.
</p>
<h4>Parallel and Alternative Execution</h4>
<p>
Parallel activities can be defined by
component <strong>Parallel</strong> and alternative activities
can be defined by component <strong>Alternative</strong>.
An example for both components is given in the next figure.
</p>
<div>
<img src=\"modelica://Modelica/Resources/Images/StateGraph/UsersGuide/Parallel1.png\">
</div>
<p>
Here, the branch from \"step2\" to \"step5\" is executed in parallel
to \"step1\". A transition connected to the output of a parallel
branch component can only fire if the final steps
in all parallel branches are active simultaneously.
The figure above is a screen-shot from the animation of the
StateGraph: Whenever a step is active or a transition can fire,
the corresponding component is marked in <strong>green</strong> color.
</p>
<p>
The three branches within \"step2\" to \"step5\" are
executed alternatively, depending which transition condition
of \"transition3\", \"transition4\", \"transition4a\" fires first.
Since all three transitions fire after 1 second, they are all
candidates for the active branch. If two or more transitions
would fire at the same time instant, a priority selection
is made: The alternative and parallel components have a
vector of connectors. Every branch has to be connected to
exactly one entry of the connector vector. The entry with
the lowest number has the highest priority.
</p>
<p>
Parallel, Alternative and Step components have vectors of
connectors. The dimensions of these vectors are set in the
corresponding parameter menu. E.g. in a \"Parallel\" component:
</p>
<div>
<img src=\"modelica://Modelica/Resources/Images/StateGraph/UsersGuide/Parallel2.png\">
</div>
<p>
Currently in Dymola the following menu pops up, when a branch
is connected to a vector of components in order to define
the vector index to which the component shall be connected:
</p>
<div>
<img src=\"modelica://Modelica/Resources/Images/StateGraph/UsersGuide/Parallel3.png\">
</div>
<h4>CompositeSteps, Suspend and Resume Port</h4>
<p>
A StateGraph can be hierarchically structured by using a <strong>CompositeStep</strong>.
This is a component that inherits from <strong>PartialCompositeStep</strong>.
An example is given in the next figure (from Examples.ControlledTanks):
</p>
<div>
<img src=\"modelica://Modelica/Resources/Images/StateGraph/UsersGuide/CompositeStep1.png\">
</div>
<p>
The CompositeStep component contains a local StateGraph that is
entered by one or more input transitions and that is left
by one or more output transitions. Also, other needed signals
may enter a CompositeStep. The CompositeStep has similar properties
as a \"usual\" step: The CompositeStep is <strong>active</strong> once at least
one step within the CompositeStep is active. Variable <strong>active</strong>
defines the state of the CompositeStep.
</p>
<p>
Additionally, a CompositeStep has a <strong>suspend</strong> port. Whenever the
transition connected to this port fires, the CompositeStep is left
at once. When leaving the CompositeStep via the suspend port, the internal
state of the CompositeStep is saved, i.e., the active flags of all
steps within the CompositeStep. The CompositeStep might be entered via
its <strong>resume</strong> port. In this case the internal state from the
suspend transition is reconstructed and the CompositeStep continues
the execution that it had before the suspend transition fired
(this corresponds to the history ports of StateCharts or JGrafcharts).
</p>
<p>
A CompositeStep may contain other CompositeSteps. At every level,
a CompositeStep and all of its content can be left via its suspend ports
(actually, there
is a vector of suspend connectors, i.e., a CompositeStep might
be aborted due to different transitions).
</p>
</html>"));
end OverView;
class FirstExample "A first example"
extends Modelica.Icons.Information;
annotation (Documentation(info="<html>
<p>
A first example will be given here (not yet done).
</p>
</html>"));
end FirstExample;
class ApplicationExample "An application example"
extends Modelica.Icons.Information;
annotation (Documentation(info="<html>
<p>
In this section a more realistic, still simple, application example
is given, to demonstrate various features of the StateGraph library.
This example shows the control of a two tank system from the master thesis
of Isolde Dressler
(<a href=\"modelica://Modelica.StateGraph.UsersGuide.Literature\">see literature</a>).
</p>
<p>
In the following figure the top level of the model is shown.
This model is available as StateGraph.Examples.ControlledTanks.
</p>
<div>
<img src=\"modelica://Modelica/Resources/Images/StateGraph/UsersGuide/ControlledTanks1.png\">
</div>
<p>
In the right part of the figure, two tanks are shown. At the top part,
a large fluid source is present from which fluid can be filled in
<strong>tank1</strong> when <strong>valve1</strong> is open. Tank1 can be emptied via
<strong>valve2</strong> that is located in the bottom of tank2 and
fills a second <strong>tank2</strong> which in turn is emptied via
<strong>valve3</strong>. The actual levels of the tanks are measured
and are provided as signals <strong>level1</strong> and <strong>level2</strong>
to the <strong>tankController</strong>.
</p>
<p>
The <strong>tankController</strong> is controlled by three buttons,
<strong>start</strong>, <strong>stop</strong> and <strong>shut</strong> (for shutdown)
that are mutually exclusive. This means that whenever one button is
pressed (i.e., its state is <strong>true</strong>) then the other two
buttons are not pressed (i.e., their states are <strong>false</strong>).
When button <strong>start</strong> is pressed, the \"normal\" operation
to fill and to empty the two tanks is processed:
</p>
<ol>
<li> Valve 1 is opened and tank 1 is filled.</li>
<li> When tank 1 reaches its fill level limit,
valve 1 is closed.</li>
<li> After a waiting time, valve 2 is
opened and the fluid flows from tank 1 into tank 2.</li>
<li> When tank 1 is empty, valve 2 is closed.</li>
<li> After a waiting time, valve 3 is opened and
the fluid flows out of tank 2.</li>
<li> When tank 2 is empty, valve 3 is closed.</li>
</ol>
<p>
The above \"normal\" process can be influenced by the following
buttons:
</p>
<ul>
<li> Button <strong>start</strong> starts the above process.
When this button is pressed after a \"stop\" or
\"shut\" operation, the process operation continues.
</li>
<li> Button <strong>stop</strong> stops the above process by
closing all valves. Then, the controller waits for
further input (either \"start\" or \"shut\" operation).</li>
<li> Button <strong>shut</strong> is used to shutdown the process,
by emptying at once both tanks. When this is achieved,
the process goes back to its start configuration.
Clicking on \"start\", restarts the process.</li>
</ul>
<p>
The implementation of the <strong>tankController</strong> is shown in
the next figure:
</p>
<div>
<img src=\"modelica://Modelica/Resources/Images/StateGraph/UsersGuide/ControlledTanks2.png\">
</div>
<p>
When the \"<strong>start</strong>\" button is pressed, the stateGraph is
within the CompositeStep \"<strong>makeProduct</strong>\". During normal
operation this CompositeStep is only left, once tank2 is empty.
Afterwards, the CompositeStep is at once re-entered.
</p>
<p>
When the \"<strong>stop</strong>\" button is pressed, the \"makeProduct\"
CompositeStep is at once terminated via the \"<strong>suspend</strong>\" port
and the stateGraph waits in step \"<strong>s2</strong>\" for further
commands. When the \"<strong>start</strong>\" button is pressed, the CompositeStep
is re-entered via its <strong>resume</strong> port and the \"normal\"
operation continues at the state where it was aborted by the
suspend transition. If the \"<strong>shut</strong>\" button is pressed,
the stateGraph waits in the \"<strong>emptyTanks</strong>\" step, until
both tanks are empty and then waits at the initial step
\"<strong>s1</strong>\" for further input.
</p>
<p>
The opening and closing of valves is <strong>not</strong> directly
defined in the stateGraph. Instead via the \"<strong>setValveX</strong>\"
components, the Boolean state of the valves are computed.
For example, the output y of \"setValve2\" is computed as:
</p>
<blockquote><pre>
y = makeProduct.fillTank2.active or emptyTanks.active
</pre></blockquote>
<p>
i.e., valve2 is open, when step \"makeProduct.fillTank2 or when
step \"emptyTanks\" is active. Otherwise, valve2 is closed.
</p>
</html>"));
end ApplicationExample;
class ComparisonWithStateGraph2 "Comparison with StateGraph2"
extends Modelica.Icons.Information;
annotation (Documentation(info="<html>
<p>
An evolved, but non-standard conforming Modelica library, called \"Modelica_StateGraph2\", is available from <a href=\"https://github.com/HansOlsson/Modelica_StateGraph2\">https://github.com/HansOlsson/Modelica_StateGraph2</a>.
Find below a comparison with respect to Modelica.StateGraph.
A third option, especially for modeling of discrete controllers, are the clocked state machines, which
are available as built-in Modelica language elements, see <a href=\"https://specification.modelica.org/v3.4/Ch17.html\">Section 17 (State Machines) of the Modelica 3.4 specification</a>.
</p>
<p>
The Modelica_StateGraph2 library (called <u>StateGraph2</u> below)
is based on the experience with the current
Modelica.StateGraph library (called <u>StateGraph1</u> below) and is
a significantly further development of StateGraph1. Furthermore, it is heavily
based on the article (Malmheden et. al. 2008), see Literature below,
but uses a different implementation
technique as described in this article. The StateGraph2
library has the following improvements with respect to the StateGraph1
library:
</p>
<ul>
<li> <strong>3 Basic Components (Step, Transition, Parallel)</strong><br>
All multiple versions of a component are
combined in only one version (e.g., one step and not 4 step components).
This is easier to understand and more convenient to use.
The \"Parallel\" component is both used as \"composite step\" (so only one branch),
as well as \"parallel step\" (so several execution branches).<br> </li>
<li> <strong>Safer state machines</strong><br>
It is no longer possible to construct a wrong state machine in the sense that properties
of the graph are violated (e.g., two initial steps, or branching wrongly out of a parallel
component). Contrary to StateGraph2, in StateGraph1 such wrong graphs do not lead to an
error but to unexpected simulation results. Still, other desirable properties
of a state machine, such as \"no deadlock\" or \"lifeliness\" or \"every step reachable\",
are not (yet) guaranteed with the current StateGraph2.<br> </li>
<li> <strong>Composite, autonomous, synchronized, preempted subgraphs</strong><br>
Composite steps and parallel steps are described in a much better and more powerful
way as in StateGraph1: Either by component \"Parallel\" or
by inheriting from \"PartialParallel\". The first alternative has the advantage that it
is simple to use (not necessary to construct a new class and instantiating this class, and
easy variable access since no new hierarchy is constructed), the second alternative
has the advantage that it introduces a Modelica hierarchy (useful for large subgraphs).
In both cases, various options are possible, such as
<ol>
<li> autonomous subgraphs (branches are executed in parallel autonomously),</li>
<li> synchronized subgraphs (branches are executed in parallel and are synchronized
before leaving the subgraph via the outPort),</li>
<li> subgraphs with preemption and exception (a parallel step can be interrupted via
the suspend ports and can continue execution via the resume ports).</li>
</ol>
This is achieved by enabling/disabling the different ports.<br> </li>
<li> <strong>No infinite looping</strong>:<br>
As in StateGraph1, there are two types of transitions: immediate transitions (during event
iteration all immediate transitions fire until no transition condition is true anymore) and
delayed transitions (a transition fires only after a delay). Contrary to StateGraph1,
in StateGraph2 every loop must have at least one delayed transition. If this is not the case
a translation error occurs which states that the model contains an algebraic loop
between Booleans with the name \"checkOneDelayedTransitionPerLoop\".<br>
This property guarantees that an event
iteration over a StateGraph2 converges after a
finite number of iterations, provided the modeller does not introduce an unsafe construct
in the actions associated with a StateGraph2 (e.g., \"i = pre(i) + 1\" in the equation section
outside of a when-clause will give an event iteration that never stops).<br>
It is possible to switch off this feature, by setting parameter
\"loopCheck = <strong>false</strong>\" in one transition of a loop, instead of using a \"delayed transition\"
at this place (in cases where immediate transitions are
important and the transition conditions are in a form that they cannot fire at the
same time instant).</li>
</ul>
<h4> Literature </h4>
<p>
The Modelica_StateGraph2 library is described in detail in
(Otter et. al. 2009, see below) and is additionally
based on the following references:
</p>
<dl>
<dt>André, C. (2003):</dt>
<dd><a href=\"http://www.i3s.unice.fr/~map/WEBSPORTS/Documents/2003a2005/SSMsemantics.pdf\">
Semantics of S.S.M (Safe State Machine)</a>.
I3S Laboratory, UMR 6070 University of Nice-Sophia Antipolis / CNRS.<br> </dd>
<dt>Årzén K.-E. (2004):</dt>
<dd> <strong>JGrafchart User Manual. Version 1.5</strong>.
Department of Automatic Control, Lund Institute of Technology,
Lund, Sweden, Feb. 13, 2004.<br> </dd>
<dt>Dressler I. (2004):</dt>
<dd> <a href=\"http://lup.lub.lu.se/student-papers/record/8848017/file/8859434.pdf\">
Code Generation From JGrafchart to Modelica</a>.
Master thesis, supervisor: Karl-Erik Årzén,
Department of Automatic Control, Lund Institute of Technology,
Lund, Sweden, March 30, 2004.<br> </dd>
<dt>Elmqvist H., Mattsson S.E., Otter M. (2001):</dt>
<dd> <strong>Object-Oriented and Hybrid Modeling in Modelica</strong>.
Journal Europeen des systemes automatises (JESA),
Volume 35 - n. 1, 2001.<br> </dd>
<dt>Harel, D. (1987):</dt>
<dd> <a href=\"http://www.inf.ed.ac.uk/teaching/courses/seoc1/2005_2006/resources/statecharts.pdf\">
A Visual Formalism for Complex Systems</a>.
Science of Computer Programming 8, 231-274. Department of Applied Mathematics,
The Weizmann Institute of Science, Rehovot, Israel.<br> </dd>
<dt>Malmheden M. (2007):</dt>
<dd> <a href=\"http://lup.lub.lu.se/student-papers/record/8847773/file/8859375.pdf\">
ModeGraph - A Mode-Automata-Based Modelica Library for Embedded Control</a>.
Master thesis, Department of Automatic Control, Lund University, Sweden.<br>
</dd>
<dt>Malmheden M., Elmqvist H., Mattsson S.E., Henrisson D., Otter M. (2008):</dt>
<dd> <a href=\"https://www.modelica.org/events/conference2008/sessions/session3a3.pdf\">
ModeGraph - A Modelica Library for Embedded Control based on Mode-Automata</a>.
Modelica'2008 Conference, March 3-4, 2008.<br>
</dd>
<dt>Maraninchi F., Rémond, Y. (2002):</dt>
<dd> <a href=\"http://dx.doi.org/10.1016/S0167-6423(02)00093-X\">Mode-Automata:
A New Domain-Specific Construct for the Development of Safe Critical Systems</a>.<br>
</dd>
<dt>Mosterman P., Otter M., Elmqvist H. (1998):</dt>
<dd><a href=\"https://www.modelica.org/papers/scsc98fp.pdf\">
Modeling Petri Nets as Local Constraint Equations for
Hybrid Systems using Modelica</a>.
SCSC'98, Reno, Nevada, USA,
Society for Computer Simulation International, pp. 314-319, 1998.<br>
</dd>
<dt>Otter M., Malmheden M., Elmqvist H., Mattsson S.E., Johnsson C. (2009):</dt>
<dd> <a href=\"https://ep.liu.se/ecp/043/041/ecp09430108.pdf\">
A New Formalism for Modeling of Reactive and Hybrid Systems</a>.
Modelica'2009 Conference, Como, Italy, Sept. 20-22, 2009.
</dd>
</dl>
</html>"));
end ComparisonWithStateGraph2;
class ReleaseNotes "Release notes"
extends Modelica.Icons.ReleaseNotes;
annotation (Documentation(info="<html>
<h4>Version 0.87, 2004-06-23</h4>
<ul>
<li> Included in Modelica standard library 2.0 Beta 1 with the new block connectors.
Changed all the references to the block connectors and the Logical library
correspondingly.</li>
</ul>
<h4>Version 0.86, 2004-06-20</h4>
<ul>
<li> New components \"Alternative\" and \"Parallel\" for alternative and
parallel execution paths.</li>
<li> A step has now a vector of input and output connectors in order
that multiple connections to and from a step are possible</li>
<li> Removed components \"AlternativeSplit\", \"AlternativeJoin\",
\"ParallelSplit\" and \"ParallelJoin\" since the newly introduced
components (\"Alternative\", \"Parallel\", vector connectors of steps)
have the same modeling power but are safer and more convenient.</li>
<li> Removed the timer in a step (attach instead Logical.Timer to
the \"active\" port of a \"StepWithSignal\" component). Note, that in
most cases it is more convenient and more efficient to use the
built-in timer of a transition.</li>
<li> Component \"StepInitial\" renamed to \"InitialStep\".</li>
<li> New component \"Timer\" within sublibrary Logical.</li>
<li> Updated and improved documentation of the library.</li>
</ul>
<h4>Version 0.85, 2004-06-17</h4>
<ul>
<li> Renamed \"MacroStep\" to \"CompositeStep\" and the ports of the MacroStep
from \"abort\" to \"suspend\" and \"history\" to \"resume\".</li>
<li> Nested \"CompositeStep\" components are supported, based on the
experimental feature of nested inner/outer components
introduced by Dymola. This means that CompositeSteps can
be suspended and resumed at every level.</li>
<li> New example \"Examples.ShowExceptions\" to demonstrate the new
feature of nested CompositeSteps.</li>
<li> New package \"Logical\". It contains all components of
ModelicaAdditions.Blocks.Logical, but with new block connectors
and nicer icons. Additionally, logical blocks are also added.</li>
<li> Improved icons for several components of the StateGraph library.</li>
</ul>
<h4>Version 0.83, 2004-05-21</h4>
<ul>
<li> The \"abort\" and \"history\" connectors are no longer visible in the
diagram layer of a CompositeStep since it is not allowed to connect
to them in a CompositeStep.</li>
<li> Made the diagram/icon size of a CompositeStep smaller (from 200/-200 to
150/-150).</li>
<li> Improved icons for \"SetBoolean/SetInteger/SetReal\" components.</li>
<li> Renamed \"ParameterReal\" to \"SetRealParameter\".</li>
</ul>
<h4>Version 0.82, 2004-05-18</h4>
<p>
Implemented a first version that is provided to other people.
</p>
</html>"));
end ReleaseNotes;
class Literature "Literature"
extends Modelica.Icons.References;
annotation (Documentation(info="<html>
<p>
The StateGraph library is based on the following references:
</p>
<dl>
<dt>Årzén K.-E. (2004):</dt>
<dd> <strong>JGrafchart User Manual. Version 1.5</strong>.
Department of Automatic Control, Lund Institute of Technology,
Lund, Sweden, Feb. 13<br> </dd>
<dt>Dressler I. (2004):</dt>
<dd> <strong>Code Generation From JGrafchart to Modelica</strong>.
Master thesis, supervisor: Karl-Erik Årzén,
Department of Automatic Control, Lund Institute of Technology,
Lund, Sweden, March 30<br> </dd>
<dt>Elmqvist H., Mattsson S.E., Otter M. (2001):</dt>
<dd> <strong>Object-Oriented and Hybrid Modeling in Modelica</strong>.
Journal Europeen des systemes automatises (JESA),
Volume 35 - n. 1.<br> </dd>
<dt>Mosterman P., Otter M., Elmqvist H. (1998):</dt>
<dd> <strong>Modeling Petri Nets as Local Constraint Equations for
Hybrid Systems using Modelica</strong>.
SCSC'98, Reno, Nevada, USA,
Society for Computer Simulation International, pp. 314-319.
</dd>
</dl>
</html>"));
end Literature;
class Contact "Contact"
extends Modelica.Icons.Contact;
annotation (Documentation(info="<html>
<h4>Main author</h4>
<p>
<a href=\"http://www.robotic.dlr.de/Martin.Otter/\"><strong>Martin Otter</strong></a><br>
Deutsches Zentrum für Luft- und Raumfahrt (DLR)<br>
Institut für Systemdynamik und Regelungstechnik (SR)<br>
Münchener Straße 20<br>
D-82234 Weßling<br>
Germany<br>
email: <a href=\"mailto:Martin.Otter@dlr.de\">Martin.Otter@dlr.de</a>
</p>
<h4>Acknowledgements</h4>
<ul>
<li> The development of this library was strongly motivated by the
master thesis of Isolde Dressler
(<a href=\"modelica://Modelica.StateGraph.UsersGuide.Literature\">see literature</a>),
in which
a compiler from JGrafchart to Modelica was designed and
implemented. This project was supervised by Karl-Erik Årzén
from Department of Automatic Control, Lund Institut of
Technology, Lund, Sweden.</li>
<li> This library profits also from the experience gained
in the focused research program (Schwerpunktprogramm)
\"Continuous-Discrete Dynamic Systems\" (KONDISK), sponsored by the
Deutsche Forschungsgemeinschaft under grants OT174/1-2 and EN152/22-2.
This support is most gratefully acknowledged.
</li>
<li> The implementation of the basic components of this library by describing
finite state machines with equations is based on
(Elmqvist, Mattsson and Otter, 2001),
which in turn uses ideas from (Mosterman, Otter and Elmqvist, 1998),
see <a href=\"modelica://Modelica.StateGraph.UsersGuide.Literature\">literature</a></li>
</ul>
</html>"));
end Contact;
annotation (DocumentationClass=true, Documentation(info="<html>
<p>
Library <strong>StateGraph</strong> is a <strong>free</strong> Modelica package providing
components to model <strong>discrete event</strong> and <strong>reactive</strong>
systems in a convenient
way. This package contains the <strong>User's Guide</strong> for
the library and has the following content:
</p>
<ol>
<li><a href=\"modelica://Modelica.StateGraph.UsersGuide.OverView\">Overview of library</a>
gives an overview of the library.</li>
<li> <a href=\"modelica://Modelica.StateGraph.UsersGuide.FirstExample\">A first example</a>
demonstrates at hand of a first example how to use this library.</li>
<li> <a href=\"modelica://Modelica.StateGraph.UsersGuide.ApplicationExample\">An
application example</a> demonstrates varies features at hand of the
control of a two tank system.</li>
<li> <a href=\"modelica://Modelica.StateGraph.UsersGuide.ComparisonWithStateGraph2\">Comparison
with StateGraph2</a> compares Modelica.StateGraph with the much improved version
Modelica_StateGraph2.</li>
<li><a href=\"modelica://Modelica.StateGraph.UsersGuide.ReleaseNotes\">Release Notes</a>
summarizes the differences between different versions of this library.</li>
<li><a href=\"modelica://Modelica.StateGraph.UsersGuide.Literature\">Literature</a>
provides references that have been used to design and implement this
library.</li>
<li><a href=\"modelica://Modelica.StateGraph.UsersGuide.Contact\">Contact</a>
provides information about the authors of the library as well as
acknowledgments.</li>
</ol>
</html>"));
end UsersGuide;
package Examples
"Examples to demonstrate the usage of the components of the StateGraph library"
extends Modelica.Icons.ExamplesPackage;
model FirstExample "A first simple StateGraph example"
extends Modelica.Icons.Example;
InitialStep initialStep(nIn=1, nOut=1) annotation (Placement(transformation(extent={{-48,0},
{-28,20}})));
Transition transition1(enableTimer=true, waitTime=1)
annotation (Placement(transformation(extent={{-20,0},{0,20}})));
Step step(nIn=1, nOut=1) annotation (Placement(transformation(extent={{10,0},{30,20}})));
Transition transition2(enableTimer=true, waitTime=1)
annotation (Placement(transformation(extent={{40,0},{60,20}})));
inner StateGraphRoot stateGraphRoot
annotation (Placement(transformation(extent={{-80,60},{-60,80}})));
equation
connect(initialStep.outPort[1], transition1.inPort)
annotation (Line(points={{-27.5,10},{-14,10}}));
connect(transition1.outPort, step.inPort[1])
annotation (Line(points={{-8.5,10},{9,10}}));
connect(step.outPort[1], transition2.inPort)
annotation (Line(points={{30.5,10},{46,10}}));
connect(transition2.outPort, initialStep.inPort[1]) annotation (Line(points=
{{51.5,10},{70,10},{70,32},{-62,32},{-62,10},{-49,10}}));
annotation (experiment(StopTime=5.5));
end FirstExample;
model FirstExample_Variant2
"A variant of the first simple StateGraph example"
extends Modelica.Icons.Example;
InitialStep initialStep(nIn=1, nOut=1) annotation (Placement(transformation(extent={{-70,0},{-50,20}})));
Transition transition1(enableTimer=true, waitTime=1)
annotation (Placement(transformation(extent={{-42,0},{-22,20}})));
StepWithSignal step(nIn=1, nOut=1)
annotation (Placement(transformation(extent={{-14,0},{6,20}})));
TransitionWithSignal transition2
annotation (Placement(transformation(extent={{52,0},{72,20}})));
Modelica.Blocks.Logical.Timer timer annotation (Placement(transformation(
extent={{6,-40},{26,-20}})));
Modelica.Blocks.Logical.GreaterEqualThreshold greaterEqual(threshold=1)
annotation (Placement(transformation(extent={{36,-40},{56,-20}})));
inner StateGraphRoot stateGraphRoot
annotation (Placement(transformation(extent={{-80,60},{-60,80}})));
equation
connect(initialStep.outPort[1], transition1.inPort)
annotation (Line(points={{-49.5,10},{-36,10}}));
connect(transition1.outPort, step.inPort[1])
annotation (Line(points={{-30.5,10},{-15,10}}));
connect(step.active, timer.u) annotation (Line(points={{-4,-1},{-4,-30},{4,
-30}}, color={255,0,255}));
connect(step.outPort[1], transition2.inPort)
annotation (Line(points={{6.5,10},{58,10}}));
connect(timer.y, greaterEqual.u)
annotation (Line(points={{27,-30},{34,-30}}, color={0,0,255}));
connect(greaterEqual.y, transition2.condition) annotation (Line(points={{57,
-30},{62,-30},{62,-2}}, color={255,0,255}));
connect(transition2.outPort, initialStep.inPort[1]) annotation (Line(points=
{{63.5,10},{82,10},{82,32},{-80,32},{-80,10},{-71,10}}));
annotation (experiment(StopTime=5.5));
end FirstExample_Variant2;
model FirstExample_Variant3
"A variant of the first simple StateGraph example"
extends Modelica.Icons.Example;
InitialStep initialStep(nIn=1, nOut=1) annotation (Placement(transformation(extent={{-70,0},{-50,20}})));
Transition transition1(enableTimer=true, waitTime=1)
annotation (Placement(transformation(extent={{-42,0},{-22,20}})));
StepWithSignal step(nIn=1, nOut=1)
annotation (Placement(transformation(extent={{-14,0},{6,20}})));
TransitionWithSignal transition2
annotation (Placement(transformation(extent={{56,0},{76,20}})));
Modelica.Blocks.Logical.Timer timer annotation (Placement(transformation(
origin={-4,-30},
extent={{-10,-10},{10,10}},
rotation=270)));
Modelica.Blocks.Sources.BooleanExpression SetBoolean1(y=timer.y > 1) annotation (Placement(
transformation(extent={{28,-40},{60,-20}})));
Modelica.Blocks.Sources.BooleanExpression SetBoolean2(y=step.active) annotation (Placement(
transformation(extent={{-68,-40},{-36,-20}})));
inner StateGraphRoot stateGraphRoot
annotation (Placement(transformation(extent={{-80,60},{-60,80}})));
equation
connect(initialStep.outPort[1], transition1.inPort)
annotation (Line(points={{-49.5,10},{-36,10}}));
connect(transition1.outPort, step.inPort[1])
annotation (Line(points={{-30.5,10},{-15,10}}));
connect(step.active, timer.u) annotation (Line(points={{-4,-1},{-4,-9.5},{
-4,-18},{-4,-18}}, color={255,0,255}));
connect(step.outPort[1], transition2.inPort)
annotation (Line(points={{6.5,10},{62,10}}));
connect(transition2.outPort, initialStep.inPort[1]) annotation (Line(points=
{{67.5,10},{82,10},{82,32},{-80,32},{-80,10},{-71,10}}));
connect(SetBoolean1.y, transition2.condition) annotation (Line(points={{
61.6,-30},{66,-30},{66,-2}}, color={255,0,255}));
annotation (experiment(StopTime=5.5));
end FirstExample_Variant3;
model ExecutionPaths
"Example to demonstrate parallel and alternative execution paths"
extends Modelica.Icons.Example;
InitialStep step0(nIn=1, nOut=1) annotation (
Placement(transformation(extent={{-140,-100},{-120,-80}})));
Transition transition1(enableTimer=true, waitTime=1)
annotation (Placement(
transformation(extent={{-100,-100},{-80,-80}})));
Step step1(nIn=1, nOut=1) annotation (
Placement(transformation(extent={{-10,-40},{10,-20}})));
Transition transition2(enableTimer=true, waitTime=1)
annotation (Placement(
transformation(extent={{90,-100},{110,-80}})));
Step step6(nIn=1, nOut=1) annotation (Placement(
transformation(extent={{120,-100},{140,-80}})));
Step step2(nIn=1, nOut=1) annotation (
Placement(transformation(extent={{-98,40},{-78,60}})));
Transition transition3(enableTimer=true, waitTime=1)
annotation (Placement(
transformation(extent={{-42,80},{-22,100}})));
Transition transition4(enableTimer=true, waitTime=1)
annotation (Placement(
transformation(extent={{-42,40},{-22,60}})));
Step step3(nIn=1, nOut=1) annotation (Placement(
transformation(extent={{-8,80},{12,100}})));
Step step4(nIn=1, nOut=1) annotation (Placement(
transformation(extent={{-8,40},{12,60}})));
Transition transition5(enableTimer=true, waitTime=1)
annotation (Placement(
transformation(extent={{26,80},{46,100}})));
Transition transition6(enableTimer=true, waitTime=1)
annotation (Placement(
transformation(extent={{26,40},{46,60}})));
Step step5(nIn=1, nOut=1) annotation (Placement(
transformation(extent={{80,40},{100,60}})));
Modelica.Blocks.Sources.RealExpression setReal(y=time)
annotation (Placement(transformation(extent={{21,-160},{41,-140}})));
TransitionWithSignal transition7 annotation (Placement(transformation(
extent={{9,-134},{-11,-114}})));
Modelica.Blocks.Sources.BooleanExpression setCondition(y=time >= 7)
annotation (Placement(transformation(extent={{-77,-160},{-19,-140}})));
Transition transition4a(enableTimer=true, waitTime=1)
annotation (Placement(transformation(extent={{-42,0},{-22,20}})));
Step step4a(nIn=1, nOut=1) annotation (Placement(
transformation(extent={{-8,0},{12,20}})));
Transition transition6a(enableTimer=true, waitTime=2)
annotation (Placement(
transformation(extent={{26,0},{46,20}})));
Modelica.Blocks.Interaction.Show.RealValue NumericValue1(
significantDigits=3)
annotation (Placement(transformation(extent={{61,-160},{81,-140}})));
Alternative alternative(nBranches=3) annotation (Placement(transformation(
extent={{-70,-10},{72,110}})));
Parallel Parallel1 annotation (Placement(transformation(extent={{-154,-50},
{152,120}})));
inner StateGraphRoot stateGraphRoot
annotation (Placement(transformation(extent={{-160,120},{-140,140}})));
equation
connect(transition3.outPort, step3.inPort[1])
annotation (Line(points={{-30.5,90},{-9,90}}));
connect(step3.outPort[1], transition5.inPort)
annotation (Line(points={{12.5,90},{32,90}}));
connect(transition4.outPort, step4.inPort[1])
annotation (Line(points={{-30.5,50},{-9,50}}));
connect(step4.outPort[1], transition6.inPort)
annotation (Line(points={{12.5,50},{32,50}}));
connect(transition7.outPort, step0.inPort[1]) annotation (Line(points={{
-2.5,-124},{-149,-124},{-149,-90},{-141,-90}}));
connect(step6.outPort[1], transition7.inPort) annotation (Line(points={{
140.5,-90},{150,-90},{150,-124},{3,-124}}));
connect(transition4a.outPort, step4a.inPort[1])
annotation (Line(points={{-30.5,10},{-9,10}}));
connect(step4a.outPort[1], transition6a.inPort)
annotation (Line(points={{12.5,10},{32,10}}));
connect(setCondition.y, transition7.condition) annotation (Line(points={{
-16.1,-150},{-1,-150},{-1,-136}}, color={255,0,255}));
connect(setReal.y, NumericValue1.numberPort) annotation (Line(
points={{42,-150},{59,-150}}, color={0,0,255}));
connect(transition3.inPort, alternative.split[1]) annotation (Line(points={{-36,90},
{-55.09,90}}));
connect(transition4.inPort, alternative.split[2]) annotation (Line(points={{-36,50},
{-55.09,50}}));
connect(transition4a.inPort, alternative.split[3]) annotation (Line(points={{-36,10},
{-45.0125,10},{-45.0125,10},{-55.09,10}}));
connect(transition5.outPort, alternative.join[1]) annotation (Line(points={{37.5,90},
{57.09,90}}));
connect(transition6.outPort, alternative.join[2]) annotation (Line(points={{37.5,50},
{57.09,50}}));
connect(transition6a.outPort, alternative.join[3]) annotation (Line(points={{37.5,10},
{46.7625,10},{46.7625,10},{57.09,10}}));
connect(step2.outPort[1], alternative.inPort) annotation (Line(points={{
-77.5,50},{-72.13,50}}));
connect(alternative.outPort, step5.inPort[1])
annotation (Line(points={{73.42,50},{79,50}}));
connect(step2.inPort[1], Parallel1.split[1]) annotation (Line(points={{-99,
50},{-118,50},{-118,78},{-119.575,78},{-119.575,77.5}}));
connect(step1.outPort[1], Parallel1.join[2]) annotation (Line(points={{10.5,
-30},{118,-30},{118,-7.5},{117.575,-7.5}}));
connect(step0.outPort[1], transition1.inPort) annotation (Line(points={{
-119.5,-90},{-94,-90}}));
connect(transition2.outPort, step6.inPort[1]) annotation (Line(points={{
101.5,-90},{119,-90}}));
connect(transition1.outPort, Parallel1.inPort) annotation (Line(points={{
-88.5,-90},{-70,-90},{-70,-64},{-174,-64},{-174,35},{-158.59,35}}));
connect(Parallel1.outPort, transition2.inPort) annotation (Line(points={{
155.06,35},{168,35},{168,-60},{80,-60},{80,-90},{96,-90}}));
connect(step5.outPort[1], Parallel1.join[1]) annotation (Line(points={{
100.5,50},{116,50},{116,77.5},{117.575,77.5}}));
connect(Parallel1.split[2], step1.inPort[1]) annotation (Line(points={{
-119.575,-7.5},{-118,-8},{-118,-30},{-11,-30}}));