Class BlockBossLogic

  • All Implemented Interfaces:
    java.beans.VetoableChangeListener, java.util.EventListener

    public class BlockBossLogic
    extends Siglet
    implements java.beans.VetoableChangeListener
    Drives the "simple signal" logic for one signal.

    Signals "protect" by telling the engineer about the conditions ahead. The engineer controls the speed of the train based on what the signals show, and the signals in turn react to whether the track ahead is occupied, what signals further down the line show, etc.

    There are four situations that this logic can handle:

    1. SINGLEBLOCK - A simple block, without a turnout.

      In this case, there is only a single set of sensors and a single next signal to protect.

    2. TRAILINGMAIN - This signal is protecting a trailing point turnout, which can only be passed when the turnout is closed. It can also be used for the upper head of a two head signal on the facing end of the turnout.

      In this case, the signal is forced red if the specified turnout is THROWN. When the turnout is CLOSED, there is a single set of sensors and next signal(s) to protect.

    3. TRAILINGDIVERGING - This signal is protecting a trailing point turnout, which can only be passed when the turnout is thrown. It can also be used for the lower head of a two head signal on the facing end of the turnout.

      In this case, the signal is forced red if the specified turnout is CLOSED. When the turnout is THROWN, there is a single set of sensors and next signal(s) to protect.

    4. FACING - This single head signal protects a facing point turnout, which may therefore have two next signals and two sets of next sensors for the closed and thrown states of the turnout.

      If the turnout is THROWN, one set of sensors and next signal(s) is protected. If the turnout is CLOSED, another set of sensors and next signal(s) is protected.

    Note that these four possibilities logically require that certain information be configured consistently; e.g. not specifying a turnout in TRAILINGMAIN doesn't make any sense. That's not enforced explicitly, but violating it can result in confusing behavior.

    The protected sensors should cover the track to the next signal. If any of the protected sensors show ACTIVE, the signal will be dropped to red. Normally, the protected sensors cover the occupancy of the track to the next signal. In this case, the signal will show red to prevent trains from entering an occupied stretch of track (often called a "block"). But the actual source of the sensors can be anything useful, for example a microswitch on a local turnout, etc.

    There are several variants to how a next signal is protected. In the simplest form, the controlled signal provides a warning to the engineer of what the signal being protected will show when it becomes visible:

    • If the next signal is red, the engineer needs to be told to slow down; this signal will be set to yellow.
    • If the next signal is green, the engineer can proceed at track speed; this signal will be set to green.
    If the next signal is yellow, there are two possible variants that can be configured:
    • For the common "three-aspect" signaling system, an engineer doesn't need any warning before a yellow signal. In this case, this signal is set to green when the protected signal is yellow.
    • For lines where track speed is very fast or braking distances are very long, it can be useful to give engineers warning that the next signal is yellow (and the one after that is red) so that slowing the train can start early. Usually flashing yellow preceeds the yellow signal, and the system is called "four-aspect" signaling.

    In some cases, you want a signal to show exactly what the next signal shows, instead of one speed faster. E.g. if the (protected) next signal is red, this one should be red, instead of yellow. In this case, this signal is called a "distant signal", as it provides a "distant" view of the protected signal heads's appearance. Note that when in this mode, this signal still protects the interveneing track, etc.

    The "hold" unbound parameter can be used to set this logic to show red, regardless of input. That's intended for use with CTC logic, etc.

    "Approach lit" signaling sets the signal head to dark (off) unless the specified sensor(s) are ACTIVE. Normally, those sensors are in front of (before) the signal head. The signal heads then only light when a train is approaching. This is used to preserve bulbs and batteries (and sometimes to reduce engineer workload) on prototype railroads, but is uncommon on model railroads; once the layout owner has gone to the trouble and expense of installing signals, he usually wants them lit up.

    Two signal heads can be protected. For example, if the next signal has two heads to control travel onto a main track or siding, then both heads should be provided here. The faster signal aspect will control the appearance of this head. For example, if the next signal is showing a green head and a red head, this signal will be green, because the train will be able to proceed at track speed when it reaches that next signal (along the track with the green signal).

    • Constructor Detail

      • BlockBossLogic

        public BlockBossLogic​(@Nonnull
                              java.lang.String name)
        Create an object to drive a specific signal head.
        Parameters:
        name - System or user name of the driven signal head, which must exist
    • Method Detail

      • getDrivenSignal

        @Nonnull
        public java.lang.String getDrivenSignal()
        The "driven signal" is controlled by this element.
        Returns:
        system name of the driven signal head
      • setSensor1

        public void setSensor1​(java.lang.String name)
      • setSensor2

        public void setSensor2​(java.lang.String name)
      • setSensor3

        public void setSensor3​(java.lang.String name)
      • setSensor4

        public void setSensor4​(java.lang.String name)
      • setSensor5

        public void setSensor5​(java.lang.String name)
      • getSensor1

        public java.lang.String getSensor1()
        Get the system name of the sensors 1-5 being monitored.
        Returns:
        system name; null if no sensor configured
      • getSensor2

        public java.lang.String getSensor2()
      • getSensor3

        public java.lang.String getSensor3()
      • getSensor4

        public java.lang.String getSensor4()
      • getSensor5

        public java.lang.String getSensor5()
      • setTurnout

        public void setTurnout​(java.lang.String name)
      • getTurnout

        public java.lang.String getTurnout()
        Get the system name of the turnout being monitored.
        Returns:
        system name; null if no turnout configured
      • setMode

        public void setMode​(int mode)
      • setComment

        public void setComment​(java.lang.String comment)
      • getComment

        public java.lang.String getComment()
      • setWatchedSignal1

        public void setWatchedSignal1​(java.lang.String name,
                                      boolean useFlash)
      • getWatchedSignal1

        public java.lang.String getWatchedSignal1()
        Get the system name of the signal head being monitored for first route.
        Returns:
        system name; null if no primary signal head is configured
      • getWatchedSignal1Alt

        public java.lang.String getWatchedSignal1Alt()
        Get the system name of the alternate signal head being monitored for first route.
        Returns:
        system name; null if no signal head is configured
      • getWatchedSignal2

        public java.lang.String getWatchedSignal2()
        Get the system name of the signal head being monitored for the 2nd route.
        Returns:
        system name; null if no signal head is configured
      • getWatchedSignal2Alt

        public java.lang.String getWatchedSignal2Alt()
        Get the system name of the secondary signal head being monitored for the 2nd route.
        Returns:
        system name; null if no secondary signal head is configured
      • getWatchedSensor1

        public java.lang.String getWatchedSensor1()
        Get the original name of the sensor1 being monitored.
        Returns:
        original name; null if no sensor is configured
      • getWatchedSensor1Alt

        public java.lang.String getWatchedSensor1Alt()
        Get the system name of the sensor1Alt being monitored.
        Returns:
        system name; null if no sensor is configured
      • getWatchedSensor2

        public java.lang.String getWatchedSensor2()
        Get the system name of the sensor2 being monitored.
        Returns:
        system name; null if no sensor is configured
      • getWatchedSensor2Alt

        public java.lang.String getWatchedSensor2Alt()
        Get the system name of the sensor2Alt being monitored.
        Returns:
        system name; null if no sensor is configured
      • setHold

        public void setHold​(boolean m)
        Set the current value of the "hold" parameter. If true, the output is forced to a RED "stop" appearance. This allows CTC and other higher-level functions to control permission to enter this section of track.
        Parameters:
        m - true to set Logic to Held
      • getApproachSensor1

        public java.lang.String getApproachSensor1()
        Get the system name of the sensor being monitored.
        Returns:
        system name; null if no sensor configured
      • defineIO

        public void defineIO()
        Define the siglet's input and output.
        Specified by:
        defineIO in class Siglet
      • setOutput

        public void setOutput()
        Recompute new output state and apply it.
        Specified by:
        setOutput in class Siglet
      • getStoppedObject

        @Nonnull
        public static BlockBossLogic getStoppedObject​(java.lang.String signal)
        Get the BlockBossLogic item governing a specific signal head by its name, having removed it from use.
        Parameters:
        signal - name of the signal head object
        Returns:
        never null
      • vetoableChange

        public void vetoableChange​(java.beans.PropertyChangeEvent evt)
                            throws java.beans.PropertyVetoException
        Specified by:
        vetoableChange in interface java.beans.VetoableChangeListener
        Throws:
        java.beans.PropertyVetoException