/
Logix.shtml
963 lines (830 loc) · 47.7 KB
/
Logix.shtml
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
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html lang="en">
<head>
<meta name="generator" content=
"HTML Tidy for Mac OS X (vers 31 October 2006 - Apple Inc. build 15.17), see www.w3.org">
<title>JMRI: Logix Documentation</title>
<meta name="author" content="David Duchamp">
<meta name="keywords" content="java model railroad JMRI Logix">
<!-- Style -->
<meta http-equiv="Content-Type" content=
"text/html; charset=us-ascii">
<link rel="stylesheet" type="text/css" href="/css/default.css"
media="screen">
<link rel="stylesheet" type="text/css" href="/css/print.css"
media="print">
<link rel="icon" href="/images/jmri.ico" type="image/png">
<link rel="home" title="Home" href="/">
<!-- /Style -->
</head>
<body>
<!--#include virtual="/Header" -->
<div id="mBody">
<!--#include virtual="Sidebar" -->
<div id="mainContent">
<h1>JMRI: Logix Documentation</h1>
<p>Logix™ provide a powerful capability for JMRI to
monitor one or more conditions on a layout, and take action
when these conditions change in a user-specified way. Logix
can be used to control signals, crossing gates, and other
types of automation on the layout. The user interface is
designed to be user friendly to all users with basic
familiarity with JMRI. A Logix provides a means for setting
up user-specified logic in an intuitive manner, without the
user having to be familiar with mathematical
logic.</p><a name="contents" id="contents"></a>
<h2>Contents</h2>
<p>The documentation below describes Logix, and discusses how
to set them up. The documentation is divided into sections;
click below for easy access to a listed section. If you
prefer to try before reading much, read <a href=
"#intro">Introduction to Logix and Conditionals</a>, then
click <a href="#start">Getting Started</a> and follow those
instructions. Return here to read about what you did.</p>
<ul>
<li><a href="#intro">Introduction to Logix and
Conditionals</a></li>
<li><a href="#logix">What are Logix</a></li>
<li><a href="#conditional">Conditionals</a></li>
<li><a href="#editconditional">The Edit Conditional
Window</a></li>
<li><a href="#logicalexpression">The Logical
Expression</a></li>
<li><a href="#thepolicy">Triggering the Actions</a></li>
<li><a href="#theactions">The Actions</a></li>
<li><a href="#start">Getting Started</a></li>
<li><a href="#notes">Additional Notes</a></li>
</ul><a name="intro" id="intro"></a>
<p>Detail <strong>State Variable</strong> and <strong>Action</strong> Lists:</p>
<ul>
<li><a href="../../package/jmri/jmrit/conditional/StateVariableActionList.shtml#variable">State Variables</a> </li>
<li><a href="../../package/jmri/jmrit/conditional/StateVariableActionList.shtml#action">Actions</a></li>
</ul>
<p><strong>Notice:</strong> The examples described in this document use the traditional
<strong>Conditional List</strong> editor.</p>
<p>Conditional Editor details:</p>
<ul>
<li><a href="../../package/jmri/jmrit/conditional/ConditionalListEditor.shtml">Conditional List Editor</a> </li>
<li><a href="../../package/jmri/jmrit/conditional/ConditionalTreeEditor.shtml">Conditional Tree Editor</a></li>
</ul>
<h2>Introduction to Logix and Conditionals</h2>
<p>A Logix is a small group of Conditionals focused on a
single task on the layout. Each <a href=
"#conditional">Conditional</a> may be viewed as a statement
of the form:</p>
<div style="margin-left: 2em;"><p><code>if (logical expression) then (action)</code></p></div>
<p>The "logical expression" part of a Conditional tests the
state of a group of user-specified conditions on the layout,
for example, whether certain turnouts are closed or thrown,
or whether a block is occupied. The "action" part of the
Conditional specifies what action is to be taken if the state
of the logical expression changes.</p>
<p>For example, one Logix with several Conditionals could
control the appearance of one signal head. The first
Conditional could check conditions for a GREEN appearance. A
second Conditional could check on another allowed appearance.
Other Conditionals could check for other appearances. A Logix
is flexible enough so that the signal rules of any railroad
might be set up, provided, of course, information needed to
test the required conditions is available. So with only one
Logix, a user should be able to set up the required logic for
setting the appearance of one signal head.</p>
<p>Think of a Logix as a <strong>small</strong> group of one or more
Conditionals that address a single need. Being able to group
all the Conditionals that address that single need in one
Logix simplifies things. Only one System Name is needed for
all the logic addressing the task, and grouping all the logic
for the task in one place, makes it much easier to see how
related logical expressions might work together and how they
might affect each other.</p><a name="logix" id="logix"></a>
<h2>What are Logix?</h2>
<p>Except when it is being created or edited, a Logix is
"active", which means that the entities (turnouts, sensors,
lights, etc.) in logical expressions of the Logix's
Conditionals are being monitored. Whenever the state of any
of the monitored entities of a Conditional changes, that
Conditional "calculates" its logical expression. If the
result of the calculation changes the value of the logical
expression, then the specified actions of the Conditional are
taken.</p>
<p>The monitored entities specified in the logical expression
of a Conditional are called "State Variables" and the result
of the calculation is the <strong>state</strong> of the Conditional. It
is the change of state of the Conditional that causes it to
issue commands for its actions to occur. The logical
expression is also referred to as the "antecedent" of the
Conditional and the group of actions to take is also called
the "consequent" of the Conditional.</p>
<p>A Logix does not have a state as many JMRI entities do. A
Logix does have the capability of being "enabled" or
"disabled", however. When a Logix is disabled (not enabled),
the logical expressions of its Conditionals are still
evaluated, but the actions specified in the Conditionals are
not taken. Whether each Logix is enabled or disabled is saved
when the Logix is saved to disk, so a Logix that was disabled
when last stored will start up disabled when next loaded from
the configuration file. When a Logix that has been disabled
is enabled, the states of all its Conditionals are set to
UNKNOWN, and all Conditionals are calculated.</p>
<h3>The Logix Table</h3>
<p>A Logix is defined via the <a href=
"../../package/jmri/jmrit/beantable/LogixTable.shtml">Logix
Table</a> that can be accessed by selecting <strong>Logix
Table</strong> in the Tools menu. The Logix Table lists all
currently defined Logix by their System Name and User Name.
The table also shows whether a Logix is "Enabled". The last
column of the table provides an easy way to edit a Logix and
its Conditionals. Clicking the <strong>Select</strong> choice box for a
Logix, will drop down a menu with four choices; <strong>Edit</strong>,
<strong>Browse</strong>, <strong>Copy</strong> and <strong>Delete</strong>.
Each choice will bring up a pane for the corresponding operation.</p>
<h4>Logix Table controls</h4>
<ul>
<li>Below the Logix Table is the <strong>Add...</strong> button.</li>
<li>The Options menu has three sections:
<ul>
<li>
The first section lets you <strong>Enable</strong> or
<strong>Disable</strong> all Logixs.
</li>
<li>
The second section lets you select a user name selection
method. See the
<a href="../../package/jmri/jmrit/beantable/LogixTable.shtml#logixOptions">
Logix Options</a> menu for details.<span class="since">since 4.7.3</span>
</li>
<li>
The third section lets you select a Conditional Editor. See the
<a href="../../package/jmri/jmrit/beantable/LogixTable.shtml#logixOptions">
Logix Options</a> menu for details.<span class="since">since 4.9.2</span>
</li>
</ul></li>
<li>The Tools menu contains five Logix maintenance tools:
<ul>
<li>Open picklist tables</li>
<li>Find orphaned items</li>
<li>Find empty Conditionals</li>
<li>Find Cross References</li>
<li>Conditional Variable References<span class="since">since 4.7.4</span><br>
<a href="../../package/jmri/jmrit/beantable/images/VariableReferences.png">
<img src="../../package/jmri/jmrit/beantable/images/VariableReferences.png"
alt="Variable Reference Window" height="320" width="339">
</a>
</li>
</ul>
</li>
</ul>
<h3>Creating a new Logix</h3>
<p>To create a new Logix, click the <strong>Add...</strong> button at
the bottom of the Logix Table pane. This will bring up a
Create Logix window. Entering a System Name and a User Name,
then clicking <strong>Create Logix</strong>, will create the Logix, and
bring up the Edit Logix window. This window allows
Conditionals to be created and edited. Once a Logix is
created, its System Name cannot be changed. Its User Name,
however, may be changed in either the Logix Table or the Edit
Logix window. A new User Name may be any useful text,
provided the new User Name was not previously assigned to
another Logix.</p>
<p>A Logix is named using the JMRI convention. The System
Name for the Logix always must begin with the two letters IX
and is usually followed by a number selected by the user. For
example, valid Logix System Names include: IX1, IX34, and
IX100. The user name is whatever the user wants to use to
identify the particular Logix, for example, "Signal 5
Control". All letters in a System Name must be in upper case.
If the user enters lower case letters, JMRI will
automatically convert them to upper case. Also, as a
convenience to the user, if the entered System Name does not
begin with IX, the program will add IX in front of what is
entered. For example, to enter a System Name of IX32, simply
enter 32 in the System Name field, and the program will do
the rest.</p>
<p>The Edit Logix window displays the System Name and User
Name of the Logix at the top. The User Name may be changed by
entering/modifying the text in the User Name field. Next is a
table of Conditionals belonging to the Logix. To add a new
Conditional, click the <strong>New Conditional</strong> button under
the Conditional Table. This will create a new Conditional and
open the Edit Conditional window allowing the logical
expression and actions of the new Conditional to be defined.
An existing Conditional may be edited by clicking the
<strong>Edit</strong> button of that Conditional in the table. The User
Name of the Conditional may be changed in the table. The User
Name of a Conditional may be any useful text, provided it is
not the same as the User Name of another Conditional in the
same Logix. The User Name may be the same as the User Name of
a Conditional in another Logix. <em>When editing the User Name
(or any item in any JMRI table) please remember to move to
another cell in the table so that the program is notified
that you have finished your entry, otherwise the entry may
not take effect.</em></p>
<p>Clicking <strong>Calculate</strong> under the Conditional Table
causes all Conditionals of the Logix to be calculated.
Resulting states are displayed in the State column of the
table. However, since the Logix is being edited it is
inactive and therefore no Conditional actions are taken. When
the editing of the Logix is done, the Logix is activated and
may be enabled to allow Conditionals to execute their
actions.</p>
<p>The order of Conditionals in the Conditional Table may be
changed by clicking <strong>Reorder</strong> (below the Conditional
Table). Clicking <strong>Reorder</strong> changes all edit buttons in
the last Column of the table to <strong>First</strong>. Select the
Conditional that is to be first, and it is immediately moved
to the top of the table. All remaining buttons change to
<strong>Next</strong>. Select remaining Conditionals in desired order,
until all buttons change back to <strong>Edit</strong>.</p>
<p>The only time when the Conditionals are evaluated in the
order listed is when all of their states are UNKNOWN, such as
when the Logix is being enabled. Conditionals are evaluated
when one of their state variables changes its state. If an
entity is used as a state variable in more than one
conditional, it is indeterminate which conditional is
evaluated first.</p>
<p>When <strong>Done</strong> is clicked at the bottom of the Edit
Logix window, any change in the Logix User Name is checked
and made. A check is made for inconsistencies in specifying
that an entity (sensor, turnout, etc.) referenced in multiple
state variables is not monitored as a trigger for calculation
of the Logix, and a warning message appears if any
inconsistencies are found. Then the Logix is activated, the
Edit Logix window is dismissed, and the user is returned to
the Logix Table. Immediately before the Logix is activated,
the state of all its Conditionals is set to UNKNOWN.
Immediately after activation, all Conditionals are
calculated.</p>
<p>The Edit Logix window also provides a way to delete a
Logix if it is no longer needed. Click <strong>Delete Logix</strong> to
delete the Logix being edited and all its Conditionals. This
operation can also be done by selecting the <strong>Delete</strong>
item from the drop down <strong>Select</strong> menu on the Logix
Table.</p>
<p>Selecting the <strong>Browse</strong> item from the drop down
menu on the Logix Table will open a window with a list showing
the details for each conditional. It is an effective way to
review the entire contents of a Logix. Click on the close button
to close the window.<span class="since">since 4.7.3</span>
<div style="margin-left: 2em">
<a href="../../package/jmri/jmrit/beantable/images/ConditionalBrowser.png">
<img src="../../package/jmri/jmrit/beantable/images/ConditionalBrowser.png"
alt="Conditional Browser Window" height="296" width="562">
</a>
</div>
<p>Selecting the <strong>Copy</strong> item from the drop down
<strong>select</strong> menu on the Logix Table will show a series of
dialog windows that provide a way to copy the Logix and any
or all of its Conditional to a new or existing
Logix.</p><a name="conditional" id="conditional"></a>
<h2>Conditionals</h2>
<p>A Conditional's System Name has the form IXnnnnCmm, and is
set automatically when the Conditional is created by the user
clicking <strong>New Conditional</strong> in the Edit Logix window. The
System Name of the first Conditional for Logix IXnnn will
always be IXnnnC1, the second Conditional will have System
Name IXnnnC2, and so on. The User Name of a Conditional is
whatever the user wants to assign to identify the use of the
Conditional. An entered User Name must not be used by more
than one Conditional within a given Logix, however. The
System Name and User Name are displayed at the top of the
Edit Conditional window. The User Name may be entered/edited
there or in the Conditional Table of the Edit Logix window.
The User Name of a Conditional may be any useful text,
provided it is not the same as the User Name of another
Conditional in the same Logix. The user name may be the same
as the User Name of a Conditional in another Logix.</p>
<p>As mentioned above, Conditionals are statements of the
form:</p>
<div style="margin-left: 2em;"><p><code>if (antecedent) then (consequent).
</code></p></div>
<p>Therefore a Conditional has two distinct parts: its
"logical expression" and its "actions". These are discussed
separately below.</p>
<p>Logical expressions connect the states (true or false) of
"state variables". State variables test conditions on the
layout or in the program, for example, if a sensor is active
or inactive, if a turnout is closed, if a signal head is red,
if the fast clock time is between 10:00 and 11:00, etc. State
variables are linked together in a logical expression by
logic operators. For a list of currently available state variables, see
<a href="../../package/jmri/jmrit/beantable/ConditionalAddEdit.shtml#variable">State Variables</a></p>
<p>Logic operators currently available are NOT, AND, AND
NOT, OR and OR NOT. The AND operator is set up automatically
by the program.
For each state variable, the user selects whether the NOT
operator is to precede the state variable. If the NOT
operator precedes the state variable, the true/false value of
the state variable is reversed. For example, if "Sensor
Active CS5" is true, "NOT Sensor Active CS5" will be false,
and vice versa. Note that "Sensor Active CS5" is sometimes
not the same as "NOT Sensor Inactive CS5", because Sensor CS5
may be in the UNKNOWN state.</p>
<p>Logical expressions read like written statements. It is
easy to set up a logical expression to evaluate many
situations on the layout. For example, "if block 10 and block
11 are occupied and turnout 20 is thrown" would be set up
as:</p>
<ul>
<li><code>Sensor "LS1020" is Sensor Active AND Sensor
"LS1021" is Sensor Active AND Turnout "LT20" is Turnout
Thrown</code></li>
</ul>
<p>where LS1020 is a sensor that is true when block 10 is
occupied (perhaps from a BDL168), sensor LS1021 is true when
block 11 is occupied, and Turnout Thrown LT20 is true when
turnout LT20 is thrown. This logical expression would
calculate to true if all three of the state variables are
true, i.e., if block 10 is occupied AND block 11 is occupied
AND turnout 20 is thrown; otherwise it would calculate
false.</p>
<p>Actions may be specified for each Conditional. A number of
action types are available. For example, Set Turnout, Set
Signal Appearance, Trigger Route, etc. For a list of currently
available action types, see <a href="../../package/jmri/jmrit/beantable/ConditionalAddEdit.shtml#action">Actions</a>. Each
action has a user selectable option of being performed if: 1)
the logical expression changes to true, 2) the logical
expression changes to false, or 3) the logical expression
changes. This means a conditional may actually be three
statements.</p>
<ul><li>if (antecedent is true) then (do "on change to true"
actions)</li>
<li>if (antecedent is false) then (do "on change to false"
actions)</li>
<li>if (antecedent state changes) then (do "on change"
actions)</li>
</ul>
<a name="editconditional" id="editconditional"></a>
<h3>The Edit Conditional Window</h3>
<p>The Edit Conditional window is where logical expressions
are set up and where actions are specified. The Edit
Conditional window is displayed when a Conditional is
created, or when the <strong>Edit</strong> button of a Conditional is
pressed in the Edit Logix window. The Edit Conditional window
displays the System Name and User Name of the Conditional at
the top. The User Name may be edited by entering/modifying
the text in the User Name field. Any text may be used,
provided it doesn't duplicate the user name of another
Conditional in the same Logix. Next are two sections--one for
the setup of a logical expression and one for set up of the
actions.</p><a name="logicalexpression" id=
"logicalexpression"></a>
<h3>The Logical Expression</h3>
<p>The logical expression section contains a table of state
variables, with two buttons and a drop down menu box below.
The drop down menu allows the choice of what logical
operators to use in the antecedent. The choices are: all
<strong>AND</strong>'s, all <strong>OR</strong>'s or
<strong>Mixed</strong>. Mixed allows the user to specify any combination of
AND's, OR's and NOT's. When this choice is made the logical expression
requires parentheses in order to be unambiguous. So, when this choice
is made, a text field is displayed so that parentheses can be
inserted and the expression modified. The state variables are
represented in the expression by their row number.</p>
<p>The first column in the state variable table is the row
number of the variable. The next column displays the logic
operation preceding the variable in the expression. In the
case of "Mixed" a choice box allows the user to choose an
operation. However these choices can be changed in the
antecedent text field and it is the text field expression
that the Conditional uses to determine its state. The third
column contains a choice box that allows the user to select
the NOT operator as needed.</p>
<p>The fourth column is a description of state variable and
the condition to be monitored to be for its state to be true.
The next column shows the state that was last tested for the
variable (true or false). The state displayed includes the
effect of the NOT operator, if NOT is selected.</p>
<p>The "Trigger" column sets whether the state variable
should cause the Conditional to perform its actions when this
variable changes. Note that the current states of all the
variables are <strong>always</strong> used in the calculation of the
Conditional's state. The "Trigger" setting allows a state
variable to be "passive" and not cause the conditional to
evaluate its state. That is, such a variable state is a
necessary condition, but not a sufficient one to cause any
actions to take place.</p>
<p><strong>Note:</strong> Disabling state variable triggers should be
done with caution. Actions are performed only when the state
of the logical expression changes. Disabling a trigger can
prevent actions from be executed even when this state has
changed.</p>
<p>Next is a column of <strong>Edit</strong> button to modify an
existing state variable. The last column of the table
(<strong>Delete</strong> buttons) is used to delete a state variable if
you decide it is no longer needed.</p>
<p>Press the <strong>Add State Variable</strong> to add a state
variable (a row in the state variable table). This brings up
a window with a choice box for the user to select a state
variable type. Available state variables are documented at
<a href="../../package/jmri/jmrit/beantable/ConditionalAddEdit.shtml#variable">State Variables</a>. When a type is chosen the Edit
Variable window displays a text field for the name of the
entity to be used for the state variable. When a name (either
System Name or user name) is entered, it must correspond to
an existing entity (sensor, turnout, light, etc.). Depending on
your <a href="../../package/jmri/jmrit/beantable/LogixTable.shtml#selectMethod">selection method</a>, a tabbed Pick List,
a single Pick List or a dropdown combo box will be displayed to
aid in name selection.</p>
<p>At any time during the entry of state variable data, the
<strong>Check State Variables</strong> button may be clicked to check
the entered data and evaluate the state variables. When this
button is pressed, the checking and evaluation proceeds until
the check completes successfully, or an error is detected. If
an error is detected, the checking stops for the user to
correct the error and click <strong>Check State Variables</strong>
again. <em>Please remember after editing the System Name and
data items to click a different cell in the table before
clicking <strong>Check State Variables</strong> (or <strong>Update
Conditional</strong> at the bottom of the window) so that the
program is notified that you have finished your entry.
Otherwise your entry may not take effect, and an error may be
reported unnecessarily.</em></p><a name="thepolicy" id=
"thepolicy"></a>
<h3>Triggering the Actions</h3>
<p>There are two policies that can be taken after a
conditional's state is evaluated:</p>
<ul>
<li>Execute the conditional actions only if the state of
the conditional has changed</li>
<li>Execute the conditional actions regardless whether the
state has changed</li>
</ul>
<p>Which policy to use is chosen by the radio buttons in the
middle of the Edit Conditional window. The <strong>Execute actions
on change of state only</strong> button prevents unwanted behavior
from occurring when multiple instances of the "on true" or
"on false" actions are executed. That is, if successive
triggers cause the logical expression to be evaluated to the
same state, only the first trigger will execute the actions.
Normally, it is best for a conditional to execute its actions
only when the state of the conditional changes. However, if
it is important to maintain the actions associated with a
particular state of the Conditional the <strong>Execute actions
whenever triggered</strong> button should be used. If external
events undo some of the actions of the conditional but do not
change the state of the conditional, then this policy will
execute the action on any trigger.</p><a name="theactions"
id="theactions"></a>
<h3>The Actions</h3>
<p>The Actions section of the Edit Conditional window
contains a table of actions, with two buttons below for
adding a new action and reordering the list of actions. The
section provides for specifying the actions to be taken when
a Conditional is calculated and changes its state. The action
table consists of a column for the description of the action
to be taken and two columns of buttons, <strong>Edit</strong> and
<strong>Delete</strong>, for editing or deleting an existing action. To
add a new action, press the "Add Action" button. A new "Edit
Action" window will appear. Select an action type in the type
box, and data items needed to completely specify the action
will appear to the right of the type box. When a name must be
entered, the name must correspond to the System Name or the
User Name of an existing entity (sensor, turnout, signal
head, etc.) of the proper type. Depending on your
<a href="../../package/jmri/jmrit/beantable/LogixTable.shtml#selectMethod">selection method</a>, a tabbed Pick List, a single Pick List or a dropdown
combo box will be displayed to aid in name selection. Available
action types are described in detail at
<a href="../../package/jmri/jmrit/beantable/ConditionalAddEdit.shtml#action">Actions</a>.
<em>If you use User Names to specify your actions, the same caution noted above
applies. Be very careful when editing User Names that are used to
specify actions.</em></p>
<p>For each action, three options are available for when to
perform the action: 1) On Change to True, 2) On Change to
False, and 3) On Change. These refer to the calculated state
of the Conditional, which is equal to the value of the
logical expression as specified in the state variable table.
One of these options must be selected. When done, click
either "Update" to install your changes, "Cancel" to close
the window without any changes or "Delete" to remove the
action entirely.</p>
<p>To change the order order of the Conditionals in a Logix,
or the order of the actions in a conditional click the
"Reorder" button. The right-most buttons in the table will
then let you select the first one, next one, etc. Note
however, this is merely the order in which the commands are
issued but do not guarantee that their final effect will
occur in the same order. If it is necessary to have actions
take place in a specified order, use separate Conditionals
for each action and chain the Conditionals such that a
preceding action's completed state is the state variable for
the succeeding action.</p><a name="updateconditional" id=
"updateconditional"></a>
<h3>Saving the Conditional</h3>
<p>When the logical expression and actions have been
specified, click <strong>Update Conditional</strong> at the bottom of
the window. This initiates a check of the logical expression
(the same as done by <strong>Check State Variables</strong>) and a
check of entered data for actions. If the Conditional's User
Name has been edited, it is also checked. If an error is
found, a message box opens announcing the error, and the
update is stopped to allow the user to correct the error and
click <strong>Update Conditional</strong> again. If no error is found,
the Conditional is updated with the entered data, the Edit
Conditional window is closed, and the user is returned to the
Edit Logix window.</p>
<p>Two other buttons are available at the bottom of the Edit
Conditional window. Clicking <strong>Cancel</strong> will close the
Edit Conditional window without updating the Conditional.
Clicking <strong>Cancel</strong> results in loss of any data that has
been entered. The other button, <strong>Delete Conditional</strong>,
provides an easy way to delete an unneeded Conditional. Click
<strong>Delete Conditional</strong> to delete the Conditional being
edited and return to the Edit Logix window.</p><a name=
"start" id="start"></a>
<h2>Getting Started</h2>
<p>The following steps let you create your first Logix and
become familiar with how the Logix user interface works.</p>
<ol>
<li>Select Table -> <strong><a href=
"../../package/jmri/jmrit/beantable/LogixTable.shtml">Logix</a></strong>
in the <strong>Tools</strong> menu.</li>
<li>Click the <strong><a href=
"../../package/jmri/jmrit/beantable/LogixAddEdit.shtml">Add...</a></strong>
button below the Logix Table.</li>
<li>In the Create Logix window that appears, enter 6 for
System Name, and "test" for User Name, then click <strong>Create
Logix</strong>.</li>
<li>In the Edit Logix window that appears, click <strong>New
Conditional</strong>.</li>
<li>In the Edit Conditional window that appears, click
<strong>Add State Variable</strong> to begin defining a logical
expression for the Conditional.</li>
<li>In the new window that appears, click the "Variable
Type" choice box to reveal a scrolling selection box.
Select "Sensor".</li>
<li>Note that a text field appears asking for entry of a
sensor name. Enter the name (either System Name or User
Name) of any of your existing sensors. (If you don't have
an existing sensor, select <strong>Sensor Table</strong> in the
<strong>Tools</strong> menu and create one.) Select <strong>Inactive</strong>
from the Variable State drop down.</li>
<li>Click the <strong>Update</strong> button and note the row entries
that appear in the state variable table.</li>
<li>Click <strong>New State Variable</strong> to create another row
in the table. Note that AND appears in the first column of
the new row. Again select "Sensor" as the variable
type, and enter the name and desired state of a different
sensor (create it if needed).</li>
<li>Click the third column entry of the second row to
reveal the selection box for NOT. Select NOT, then click
<strong>Check State Variables</strong> again. Note that the State of
the second state variable has reversed.</li>
<li>For an Action click <strong>Add Action</strong>.</li>
<li>In the new window that appears, click the "Action Type"
choice box to reveal a scrolling selection box. Select
"Turnout", and enter the name (System Name or User Name) of
one of your turnouts. (If you don't have any turnouts,
create one using the <strong>Add</strong> button in the Turnout
Table.) Select <strong>Set Turnout</strong> for the Action Type,
leave the "Turnout Position" option at "Closed" and
"Change Option" at "On Change to True".</li>
<li>Click the <strong>Update</strong> button and note the row entries
that appear in the action table.</li>
<li>For another Action - again click <strong>Add Action</strong> and
select "Turnout". Enter the name of the same turnout
entered before. Select "On Change to False" as the Trigger
Option, and "Thrown" as the Turnout Position.</li>
<li>Click <strong>Update</strong> to close the Edit Conditional
window and return to the Edit Logix window.</li>
<li>Click <strong>Done</strong> to close the Edit Logix window and
activate your new Logix. Click <strong>OK</strong> in the
reminder-to-save dialog that appears.</li>
</ol>
<p>You'll have created a Logix to control the setting of a
turnout according to the states of two sensors. It's as
simple as that. It took you more time to read this tutorial
than to create the Logix.</p><a name="variable" id=
"variable"></a>
<a name="notes" id="notes"></a>
<h2>Additional Notes</h2>
<p>This section contains questions and answers that normally
are not needed by Logix users, but in some cases were
important or of interest for previous versions of Logix.</p>
<ul>
<li>
<p><strong>Why have a "group" of Conditionals instead of just
single Conditionals?</strong></p>
<p>A group of Conditionals was chosen for several
reasons, including:</p>
<ol>
<li>Grouping Conditionals into a Logix, and focusing
the Logix on one task should end up being much more
user friendly. Think about one Logix with several
Conditionals controlling one three-turnout signal head.
The first Conditional could check conditions for a RED
appearance, and take appropriate action. The second
Conditional could check on another allowed appearance
which, depending upon the rules of the railroad being
modeled could depend upon the calculated state of the
first Conditional. Other Conditionals would check for
other appearances according to the rules of the
railroad. So with only one Logix, a user should be able
to set up the required logic for setting appearances
for one signal head. Thus once the sensors, turnouts,
and signal heads are set up, only one new System Name,
the System Name of the Logix, need be defined and kept
track of.</li>
<li>Another reason for grouping multiple Conditionals
is simpler operation. Fewer behind the scene listeners
are needed to accomplish the same task. Even though,
following the example above, the logic for each
appearance of the signal head (each Conditional) may
depend upon a particular sensor (a block occupancy for
example), if the Conditionals are combined into a
single Logix, only _one_ listener for that sensor is
required. This is simpler in implementation than having
multiple listeners.</li>
</ol>
</li>
<li>
<p><strong>How is a Logix started?</strong></p>
<p>Start of a Logix is similar to the way a light, a
route, or other continuously running JMRI entity starts.
Internally a Logix has an "activate" method, that is
called when the Logix is created, after it is edited, or
when it is loaded from a configuration file. This method
starts listeners for items in the state variables of the
Logix's Conditionals. When any of these listeners fires
(indicating that the watched property of a state variable
has changed), the Logix is calculated, resulting in
appropriate actions being taken, provided the Logix is
enabled.</p>
</li>
<li>
<p><strong>What is the initial state of a Logix and its
Conditionals?</strong></p>
<p>When a Logix is created or edited, the initial state
of each Conditional is true or false as shown in the Edit
Logix window. When a Logix is loaded from a configuration
file, the initial state of each Conditional is
UNKNOWN.</p>
<p>A Logix is enabled automatically when it is created. A
Logix may be disabled/enabled by unchecking/checking the
button in the Enable column in the Logix table. For
example, you might want to disable a Logix while you're
creating and debugging it, until you're certain that you
have it set up properly. A Logix may be enabled or
disabled dynamically by another Logix (see allowed
<a href="../../package/jmri/jmrit/beantable/ConditionalAddEdit.shtml#action">Actions</a>.
).</p>
<p>When JMRI stores the layout configuration in a file,
e.g. a panel file, all Logix information, including the
enabled/disabled state of the Logix, is stored. When a
Logix is loaded from a configuration file, it's enabled
or disabled status is set according to what was saved in
the configuration file. This is done so that people can
disable their Logix while debugging them, yet still save
and restore the configuration as needed.</p>
</li>
<li>
<strong>What happens when a JMRI program starts up or when a
configuration file is loaded by a JMRI program?</strong>
<p>This is a complex question that depends upon many
things, such as, how the user has set up for turnout
feedback, block detection, etc. When a configuration file
is read, the various entities (sensors, turnouts, signal
heads, etc.) are loaded in an almost random order. So
it's not reasonable, for example, to calculate each Logix
as it is loaded, since the needed state variable entities
might not be present when the Logix is loaded. And, since
most entities will load in UNKNOWN state, calculating a
Logix immediately after the entire configuration file is
loaded doesn't produce a clean start up either. So when a
Logix is loaded, the state of each Conditional starts as
UNKNOWN. Immediately after the entire configuration file
is loaded, all Logix are activated, and then all the
Logix are calculated. The state of Conditionals changes
from UNKNOWN to true or false. But will the calculated
state of the Conditional be "correct" if one or more of
the state variables is evaluated from an entity in an
UNKNOWN state? For example, think of a turnout in an
UNKNOWN state--Turnout Thrown and Turnout Closed will
both evaluate to false. As listeners continue to fire for
state variables, eventually every entity has its correct
current state and the Logix will work fine. You can
monitor this action by watching states in the Sensor
Table, the Turnout Table, etc. Conditions at start up
certainly are something to keep in mind when setting up a
Logix.</p>
</li>
<li>
<strong>When should Triggers Calculation be unchecked in a
state variable?</strong>
<p>Normally Triggers Calculation should be checked in all
state variables, so a change in any of its state variable
will trigger calculation of a Logix. This results in the
Logix quickly reacting to changes on the layout, and
maintaining the status of signals, turnouts, etc. as
desired. There are situations, however, where it is
desirable to test the state of an entity, but not use it
as a calculation trigger. The following paragraphs
describe a couple of those situations, but there are
others.</p>
<p>Occasionally a "logic loop" can result if triggering
is not suppressed. For example, if the state of a turnout
is tested in a state variable, and the same turnout is
set in an action of the same or another Conditional of
the same Logix, continuous triggering (a logic loop)
could result. The easiest way out of this dilemma is to
test the turnout, without using it as a triggering
entity. This is done by unchecking Triggers Calculation
in <strong>all</strong> state variables where the turnout is
specified. If the turnout is used in state variables of
more than one Conditional of the Logix, it must be
unchecked everywhere it is used to suppress using it as a
trigger.</p>
<p>Another situation arises when Delayed Set Sensor
action is used with an internal sensor to trigger a
second Logix after the delay time has elapsed. If the
second Logix is not to be triggered before the delay time
elapses, all of its state variables, except for the
delayed internal sensor, should be unchecked. This
scenario might occur, for example, if a Conditional turns
on something as its first action, and sets a Delayed Set
Sensor as its second action to turn off that something
after a specified time provided certain conditions are
met.</p>
</li>
<li>
<strong>What is a "logic loop" and how can it be avoided?</strong>
<p>A "logic loop" results when the program appears to
slow down significantly or lock up as multiple Logixs are
continuously triggered by changing references to each
other. The best way to avoid a "logic loop" is to be
aware of situations that can lead to a loop, and plan
your logic to avoid such situations.</p>
<p>A "logic loop" can result within a single Logix when a
state variable (sensor, turnout, etc.) that triggers the
Logix is also changed by that same Logix. The Logix
editor will detect some situations that could result in a
loop, and will issue a warning when you close the Logix.
<strong>Heed these warnings!</strong> A warning doesn't mean that a
loop definitely will result if you continue. The warning
message is a "wake up call" that you should study
carefully what you're doing to make sure a loop won't
result.</p>
<p>A more complicated situation involving two or more
Logixs can also result in a "logic loop". For example, if
Logix 1 is triggered by sensor A, and has an action that
changes turnout B, and Logix 2 is triggered by turnout B
and changes sensor A, the potential for a loop exists as
these Logixs trigger each other. You can easily extend
this idea to triggering chains (loops) involving three or
more Logixs, and even to interactions between Logixs and
Routes. There is no test in the program to warn about
loops involving multiple Logixs. (To develop such a test
would be very difficult.)</p>
</li>
<li>
<strong>What should I do if I think I have a "logic loop"?</strong>
<p>When they do occur, "logic loops" can be a bit scary
to trouble shoot. Your computer may appear to be locked
up, or slowed to a crawl as the loop uses up most of the
available computer time. Fortunately JMRI provides tools
to help in design and debugging. Unchecking "Triggers
Calculation" for a state variable (discussed above), can
help you design around loops when you have identified the
Logix causing the looping problem. To get around the lock
up or slow down problem, start with all your Logixs
disabled, (see below) then enable them one by one until
you discover the loop.</p>
<p>If the panel file containing Logixs loads
automatically when the program starts up, press and
release the shift key a few times rapidly as soon as you
see the small JMRI splash screen (the first thing you see
during start up). Your panel file will be loaded with all
Logixs disabled.</p>
<p>If you load your panel file manually using the Panels
menu, before loading your file, go to the <strong>Debug</strong>
menu and select <strong>Load Logixs Disabled</strong>. After
responding OK to the message, load your panel file as you
normally would. Your panel file will be loaded with all
Logixs disabled.</p>
<p>After loading your panel file, open the Logix Table
and verify that all Logixs are disabled. If you know
which Logix is causing the trouble, you can then fix it
or delete it, re-enable the other Logixs, and save your
panel file. If you don't know which Logix is causing the
problem, you can enable your Logixs, one by one, until
the loop occurs. When the loop starts, you know that the
last Logix you enabled is at least partly responsible for
the problem. At this point you should restart the program
with all Logixs disabled, and fix or delete the Logix you
identified.</p>
<p><strong>CAUTION:</strong> <strong>It's wise to save your panel file
frequently when entering Logixs.</strong> If a logic loop
occurs, it may be difficult, if not impossible, to save
your panel file before shutting down the program.
Remember that a Logix is activated as soon as you click
<strong>Done</strong> in the Edit Logix window. Also, remember that
hitting an <strong>Edit</strong> button in the Logix Table
deactivates the selected Logix before opening it for
editing, offering a possible way to break into a logic
loop without restarting the program.</p>
</li>
</ul>
<!--#include virtual="/Footer" -->
</div><!-- closes #mainContent-->
</div><!-- closes #mBody-->
</body>
</html>