001/*----------------------------------------------------------------------------*/
002/* Copyright (c) FIRST 2008-2017. All Rights Reserved.                        */
003/* Open Source Software - may be modified and shared by FRC teams. The code   */
004/* must be accompanied by the FIRST BSD license file in the root directory of */
005/* the project.                                                               */
006/*----------------------------------------------------------------------------*/
007
008package edu.wpi.first.wpilibj;
009
010import edu.wpi.first.wpilibj.hal.FRCNetComm.tInstances;
011import edu.wpi.first.wpilibj.hal.FRCNetComm.tResourceType;
012import edu.wpi.first.wpilibj.hal.HAL;
013import edu.wpi.first.wpilibj.livewindow.LiveWindow;
014
015/**
016 * A simple robot base class that knows the standard FRC competition states (disabled, autonomous,
017 * or operator controlled).
018 *
019 * <p>You can build a simple robot program off of this by overriding the robotinit(), disabled(),
020 * autonomous() and operatorControl() methods. The startCompetition() method will calls these
021 * methods (sometimes repeatedly). depending on the state of the competition.
022 *
023 * <p>Alternatively you can override the robotMain() method and manage all aspects of the robot
024 * yourself.
025 */
026public class SampleRobot extends RobotBase {
027
028  private boolean m_robotMainOverridden;
029
030  /**
031   * Create a new SampleRobot.
032   */
033  public SampleRobot() {
034    super();
035    m_robotMainOverridden = true;
036  }
037
038  /**
039   * Robot-wide initialization code should go here.
040   *
041   * <p>Users should override this method for default Robot-wide initialization which will be called
042   * when the robot is first powered on. It will be called exactly one time.
043   *
044   * <p>Warning: the Driver Station "Robot Code" light and FMS "Robot Ready" indicators will be off
045   * until RobotInit() exits. Code in RobotInit() that waits for enable will cause the robot to
046   * never indicate that the code is ready, causing the robot to be bypassed in a match.
047   */
048  protected void robotInit() {
049    System.out.println("Default robotInit() method running, consider providing your own");
050  }
051
052  /**
053   * Disabled should go here. Users should overload this method to run code that should run while
054   * the field is disabled.
055   *
056   * <p>Called once each time the robot enters the disabled state.
057   */
058  protected void disabled() {
059    System.out.println("Default disabled() method running, consider providing your own");
060  }
061
062  /**
063   * Autonomous should go here. Users should add autonomous code to this method that should run
064   * while the field is in the autonomous period.
065   *
066   * <p>Called once each time the robot enters the autonomous state.
067   */
068  public void autonomous() {
069    System.out.println("Default autonomous() method running, consider providing your own");
070  }
071
072  /**
073   * Operator control (tele-operated) code should go here. Users should add Operator Control code to
074   * this method that should run while the field is in the Operator Control (tele-operated) period.
075   *
076   * <p>Called once each time the robot enters the operator-controlled state.
077   */
078  public void operatorControl() {
079    System.out.println("Default operatorControl() method running, consider providing your own");
080  }
081
082  /**
083   * Test code should go here. Users should add test code to this method that should run while the
084   * robot is in test mode.
085   */
086  @SuppressWarnings("PMD.JUnit4TestShouldUseTestAnnotation")
087  public void test() {
088    System.out.println("Default test() method running, consider providing your own");
089  }
090
091  /**
092   * Robot main program for free-form programs.
093   *
094   * <p>This should be overridden by user subclasses if the intent is to not use the autonomous()
095   * and operatorControl() methods. In that case, the program is responsible for sensing when to run
096   * the autonomous and operator control functions in their program.
097   *
098   * <p>This method will be called immediately after the constructor is called. If it has not been
099   * overridden by a user subclass (i.e. the default version runs), then the robotInit(),
100   * disabled(), autonomous() and operatorControl() methods will be called.
101   */
102  public void robotMain() {
103    m_robotMainOverridden = false;
104  }
105
106  /**
107   * Start a competition. This code tracks the order of the field starting to ensure that everything
108   * happens in the right order. Repeatedly run the correct method, either Autonomous or
109   * OperatorControl when the robot is enabled. After running the correct method, wait for some
110   * state to change, either the other mode starts or the robot is disabled. Then go back and wait
111   * for the robot to be enabled again.
112   */
113  public void startCompetition() {
114    HAL.report(tResourceType.kResourceType_Framework,
115                                   tInstances.kFramework_Simple);
116
117    robotInit();
118
119    // Tell the DS that the robot is ready to be enabled
120    HAL.observeUserProgramStarting();
121
122    robotMain();
123    if (!m_robotMainOverridden) {
124      // first and one-time initialization
125      LiveWindow.setEnabled(false);
126
127      while (true) {
128        if (isDisabled()) {
129          m_ds.InDisabled(true);
130          disabled();
131          m_ds.InDisabled(false);
132          while (isDisabled()) {
133            Timer.delay(0.01);
134          }
135        } else if (isAutonomous()) {
136          m_ds.InAutonomous(true);
137          autonomous();
138          m_ds.InAutonomous(false);
139          while (isAutonomous() && !isDisabled()) {
140            Timer.delay(0.01);
141          }
142        } else if (isTest()) {
143          LiveWindow.setEnabled(true);
144          m_ds.InTest(true);
145          test();
146          m_ds.InTest(false);
147          while (isTest() && isEnabled()) {
148            Timer.delay(0.01);
149          }
150          LiveWindow.setEnabled(false);
151        } else {
152          m_ds.InOperatorControl(true);
153          operatorControl();
154          m_ds.InOperatorControl(false);
155          while (isOperatorControl() && !isDisabled()) {
156            Timer.delay(0.01);
157          }
158        }
159      } /* while loop */
160    }
161  }
162}