Files
JIMRI/help/en/html/tools/signaling/Logic.shtml
T
2026-06-17 14:00:51 +02:00

291 lines
12 KiB
Plaintext

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="generator" content="HTML Tidy for HTML5 for Apple macOS version 5.8.0">
<!-- Copyright Bob Jacobsen 2008 -->
<title>JMRI: Simple Signal Logic</title><!--#include virtual="/help/en/parts/Style.shtml" -->
</head>
<body>
<!--#include virtual="/help/en/parts/Header.shtml" -->
<div id="mBody">
<!--#include virtual="Sidebar.shtml" -->
<div id="mainContent">
<h1>JMRI: Simple Signal Logic</h1>
<p class="subtitle">Background information of the logic used to control simple signals</p>
<div class="para">
<p>This page describes the logic used by the JMRI Simple Signal panel to control
signals.</p>
<p>We display the actual code, so there's no ambiguity about what it's doing. This is from
JMRI test release 2.9.1.</p>
</div>
<div class="section">
<h2 id="single">On Single Block</h2>
<div class="para">
<p>This signal protects one end of a straight through block, with no signaled
turnouts.</p>
</div>
<div class="para">
<pre class="code">
void doSingleBlock() {
int appearance = SignalHead.GREEN;
int oldAppearance = ((SignalHead)outputs[0]).getAppearance();
// check for yellow, flashing yellow overriding green
if (protectWithFlashing &amp;& fastestColor1()==SignalHead.YELLOW)
appearance = SignalHead.FLASHYELLOW;
if (fastestColor1()==SignalHead.RED || fastestColor1()==SignalHead.FLASHRED)
appearance = SignalHead.YELLOW;
// if distant signal, show exactly what the home signal does
if (distantSignal)
appearance = fastestColor1();
// if limited speed and green, reduce to yellow
if (limitSpeed1)
appearance = slowerOf(appearance, SignalHead.YELLOW);
// check for red overriding yellow or green
if (watchSensor1!=null &amp;& watchSensor1.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor2!=null &amp;& watchSensor2.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor3!=null &amp;& watchSensor3.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor4!=null &amp;& watchSensor4.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
// check if signal if held, forcing a red aspect by this calculation
if (((SignalHead)outputs[0]).getHeld())
appearance = SignalHead.RED;
// handle approach lighting
doApproach();
// show result if changed
if (appearance != oldAppearance) {
((SignalHead)outputs[0]).setAppearance(appearance);
if (log.isDebugEnabled()) log.debug("Change appearance of "+name+" to "+appearance);
}
}
</pre>
</div>
</div>
<div class="section">
<h2 id="trailmain">On Main Leg ofTrailing-Point Turnout</h2>
<div class="para">
<p>This signal is along the main route through a turnout, which is defined as the
direction taken by trains when the turnout is closed. It's protecting the frog of the
turnout so that trains will stop before running through a turnout set against them.</p>
</div>
<div class="para">
<pre class="code">
void doTrailingMain() {
int appearance = SignalHead.GREEN;
int oldAppearance = ((SignalHead)outputs[0]).getAppearance();
// check for yellow, flashing yellow overriding green
if (protectWithFlashing &amp;& fastestColor1()==SignalHead.YELLOW)
appearance = SignalHead.FLASHYELLOW;
if (fastestColor1()==SignalHead.RED || fastestColor1()==SignalHead.FLASHRED)
appearance = SignalHead.YELLOW;
// if distant signal, show exactly what the home signal does
if (distantSignal)
appearance = fastestColor1();
// if limited speed and green, reduce to yellow
if (limitSpeed1)
appearance = slowerOf(appearance, SignalHead.YELLOW);
// check for red overriding yellow or green
if (watchSensor1!=null &amp;& watchSensor1.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor2!=null &amp;& watchSensor2.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor3!=null &amp;& watchSensor3.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor4!=null &amp;& watchSensor4.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchTurnout!=null &amp;& watchTurnout.getBean().getKnownState() != Turnout.CLOSED)
appearance = SignalHead.RED;
if (watchTurnout!=null &amp;& watchTurnout.getBean().getCommandedState() != Turnout.CLOSED)
appearance = SignalHead.RED;
// check if signal if held, forcing a red aspect by this calculation
if (((SignalHead)outputs[0]).getHeld())
appearance = SignalHead.RED;
// handle approach lighting
doApproach();
// show result if changed
if (appearance != oldAppearance) {
((SignalHead)outputs[0]).setAppearance(appearance);
log.debug("Change appearance of {} to {}", name, appearance);
}
}
</pre>
</div>
</div>
<div class="section">
<h2 id="traildiv">On Diverging Leg of Trailing-Point Turnout</h2>
<div class="para">
<p>This signal is along the diverging route through a turnout, which is defined as the
direction taken by trains when the turnout is set to "thrown". It's protecting the frog
of the turnout so that trains will stop before running through a turnout set against
them.</p>
</div>
<div class="para">
<pre class="code">
void doTrailingDiverging() {
int appearance = SignalHead.GREEN;
int oldAppearance = ((SignalHead)outputs[0]).getAppearance();
// check for yellow, flashing yellow overriding green
if (protectWithFlashing &amp;& fastestColor1()==SignalHead.YELLOW)
appearance = SignalHead.FLASHYELLOW;
if (fastestColor1()==SignalHead.RED || fastestColor1()==SignalHead.FLASHRED)
appearance = SignalHead.YELLOW;
// if distant signal, show exactly what the home signal does
if (distantSignal)
appearance = fastestColor1();
// if limited speed and green, reduce to yellow
if (limitSpeed2)
appearance = slowerOf(appearance, SignalHead.YELLOW);
// check for red overriding yellow or green
if (watchSensor1!=null &amp;& watchSensor1.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor2!=null &amp;& watchSensor2.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor3!=null &amp;& watchSensor3.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor4!=null &amp;& watchSensor4.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchTurnout!=null &amp;& watchTurnout.getBean().getKnownState() != Turnout.THROWN)
appearance = SignalHead.RED;
if (watchTurnout!=null &amp;& watchTurnout.getBean().getCommandedState() != Turnout.THROWN)
appearance = SignalHead.RED;
// check if signal if held, forcing a red aspect by this calculation
if (((SignalHead)outputs[0]).getHeld())
appearance = SignalHead.RED;
// handle approach lighting
doApproach();
// show result if changed
if (appearance != oldAppearance) {
((SignalHead)outputs[0]).setAppearance(appearance);
if (log.isDebugEnabled()) log.debug("Change appearance of "+name+" to "+appearance);
}
}
</pre>
</div>
</div>
<div class="section">
<h2 id="face">On Facing-Point Turnout</h2>
<div class="para">
<p>This signal is protecting the points-end of a turnout. Depending on whether the
turnout is thrown or closed, the train will take two different routes, and the signal
will protect different next blocks.</p>
</div>
<div class="para">
<pre class="code">
void doFacing() {
int appearance = SignalHead.GREEN;
int oldAppearance = ((SignalHead)outputs[0]).getAppearance();
// find downstream appearance, being pessimistic if we're not sure of the state
int s = SignalHead.GREEN;
if (watchTurnout!=null &amp;& watchTurnout.getBean().getKnownState() != Turnout.THROWN)
s = slowerOf(s, fastestColor1());
if (watchTurnout!=null &amp;& watchTurnout.getBean().getKnownState() != Turnout.CLOSED)
s = slowerOf(s, fastestColor2());
// check for yellow, flashing yellow overriding green
if (protectWithFlashing &amp;& s==SignalHead.YELLOW)
appearance = SignalHead.FLASHYELLOW;
if (s==SignalHead.RED || s==SignalHead.FLASHRED)
appearance = SignalHead.YELLOW;
// if distant signal, show exactly what the home signal does
if (distantSignal)
appearance = s;
// if limited speed and green or flashing yellow, reduce to yellow
if (watchTurnout!=null &amp;& limitSpeed1 &amp;& watchTurnout.getBean().getKnownState()!=Turnout.THROWN)
appearance = slowerOf(appearance, SignalHead.YELLOW);
if (watchTurnout!=null &amp;& limitSpeed2 &amp;& watchTurnout.getBean().getKnownState()!=Turnout.CLOSED)
appearance = slowerOf(appearance, SignalHead.YELLOW);
// check for red overriding yellow or green
if (watchSensor1!=null &amp;& watchSensor1.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor2!=null &amp;& watchSensor2.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor3!=null &amp;& watchSensor3.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if (watchSensor4!=null &amp;& watchSensor4.getBean().getKnownState() != Sensor.INACTIVE)
appearance = SignalHead.RED;
if ((watchTurnout!=null &amp;& watchTurnout.getBean().getKnownState() == Turnout.CLOSED)
&amp;& ((watchedSensor1!=null &amp;& watchedSensor1.getBean().getKnownState() != Sensor.INACTIVE)))
appearance = SignalHead.RED;
if ((watchTurnout!=null &amp;& watchTurnout.getBean().getKnownState() == Turnout.CLOSED) &amp;& ((watchedSensor1Alt!=null &amp;& watchedSensor1Alt.getBean().getKnownState() != Sensor.INACTIVE)))
appearance = SignalHead.RED;
if ((watchTurnout!=null &amp;& watchTurnout.getBean().getKnownState() == Turnout.THROWN) &amp;& ((watchedSensor2!=null &amp;& watchedSensor2.getBean().getKnownState() != Sensor.INACTIVE)))
appearance = SignalHead.RED;
if ((watchTurnout!=null &amp;& watchTurnout.getBean().getKnownState() == Turnout.THROWN) &amp;& ((watchedSensor2Alt!=null &amp;& watchedSensor2Alt.getBean().getKnownState() != Sensor.INACTIVE)))
appearance = SignalHead.RED;
// check if turnout in motion, if so force red
if (watchTurnout!=null &amp;& (watchTurnout.getBean().getKnownState() != watchTurnout.getBean().getCommandedState()) )
appearance = SignalHead.RED;
if (watchTurnout!=null &amp;& (watchTurnout.getBean().getKnownState() != Turnout.THROWN) &amp;& (watchTurnout.getBean().getKnownState() != Turnout.CLOSED) ) // checking for other states
appearance = SignalHead.RED;
// check if signal if held, forcing a red aspect by this calculation
if (((SignalHead)outputs[0]).getHeld())
appearance = SignalHead.RED;
// handle approach lighting
doApproach();
// show result if changed
if (appearance != oldAppearance)
((SignalHead)outputs[0]).setAppearance(appearance);
}
</pre>
</div>
<!--closes para-->
</div>
<!--closes section-->
<!--#include virtual="/help/en/parts/Footer.shtml" -->
</div>
</div>
<!-- close #mBody -->
<script src="/js/help.js"></script>
</body>
</html>