001package jmri.jmrit.automat;
002
003import jmri.DccThrottle;
004import jmri.InstanceManager;
005import jmri.Sensor;
006import org.slf4j.Logger;
007import org.slf4j.LoggerFactory;
008
009/**
010 * This sample Automaton runs a locomotive back and forth on a piece of track by
011 * watching two sensors.
012 * <p>
013 * The sensors and locomotive are hardcoded, as this is an example of just the
014 * Automaton function. Adding a GUI to configure these would be
015 * straight-forward. The values could be passed via the constructor, or the
016 * constructor (which can run in any required thread) could invoke a dialog.
017 * <p>
018 * For test purposes, one of these objects can be created and invoked by a
019 * SampleAutomaton3Action.
020 * <p>
021 * For more information on JMRI support for automation classes, please see the
022 * <a href="http://jmri.org/help/en/html/tools/automation/viaJava.shtml">JMRI
023 * Layout Automation in Java page</a>.
024 *
025 * @author Bob Jacobsen Copyright (C) 2003
026 * @see jmri.jmrit.automat.SampleAutomaton3Action
027 */
028public class SampleAutomaton3 extends AbstractAutomaton {
029
030    /**
031     * References the locomotive decoder to be controlled
032     */
033    DccThrottle throttle = null;
034
035    /**
036     * References the sensor the locomotive will enter when it moves forward to
037     * the limit.
038     */
039    Sensor fwdSensor;
040
041    /**
042     * References the sensor the locomotive will enter when it moves backward to
043     * the limit.
044     */
045    Sensor revSensor;
046
047    /**
048     * By default, monitors sensor "182" for the forward end of the track
049     */
050    String fwdSensorName = "182";
051
052    /**
053     * By default, monitors sensor "178" for the reverse end of the track
054     */
055    String revSensorName = "178";
056
057    /**
058     * By default, controls locomotive 77(short).
059     */
060    int locoNumber = 77;
061    boolean locoLong = false;
062
063    @Override
064    protected void init() {
065        // get references to sample layout objects
066
067        fwdSensor = InstanceManager.sensorManagerInstance().
068                provideSensor(fwdSensorName);
069
070        revSensor = InstanceManager.sensorManagerInstance().
071                provideSensor(revSensorName);
072
073        throttle = getThrottle(locoNumber, locoLong);
074    }
075
076    boolean moveFwd;
077    int fwdState;
078    int revState;
079
080    /**
081     * Watch the sensors, and change direction to match.
082     *
083     * @return Always returns true to continue operation
084     */
085    @Override
086    protected boolean handle() {
087
088        // we're supposed to be moving forward here
089        // This initialization is only needed the first time through,
090        // but it doesn't hurt to do it each time.
091        moveFwd = true;
092        throttle.setIsForward(moveFwd);
093        throttle.setSpeedSetting(0.50f);
094
095        // wait until the forward sensor is ACTIVE
096        log.debug("Waiting for state change");
097        while ((fwdState = fwdSensor.getKnownState()) != Sensor.ACTIVE) {
098            waitSensorChange(fwdState, fwdSensor);
099        }
100        log.debug("Forward sensor active");
101
102        moveFwd = false;
103        throttle.setIsForward(moveFwd);
104        throttle.setSpeedSetting(0.33f);
105
106        // wait until the reverse sensor is ACTIVE
107        while ((revState = revSensor.getKnownState()) != Sensor.ACTIVE) {
108            waitSensorChange(revState, revSensor);
109        }
110        log.debug("Backward sensor active");
111
112        moveFwd = true;
113        throttle.setIsForward(moveFwd);
114
115        return true;   // never terminate voluntarily
116    }
117
118    // initialize logging
119    private final static Logger log = LoggerFactory.getLogger(SampleAutomaton3.class);
120
121}