001/*----------------------------------------------------------------------------*/
002/* Copyright (c) 2008-2018 FIRST. 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 *
026 * @deprecated WARNING: While it may look like a good choice to use for your code if you're
027 *     inexperienced, don't. Unless you know what you are doing, complex code will
028 *     be much more difficult under this system. Use TimedRobot or Command-Based
029 *     instead.
030 */
031@Deprecated
032public class SampleRobot extends RobotBase {
033  private boolean m_robotMainOverridden = true;
034
035  /**
036   * Create a new SampleRobot.
037   */
038  public SampleRobot() {
039    HAL.report(tResourceType.kResourceType_Framework, tInstances.kFramework_Simple);
040  }
041
042  /**
043   * Robot-wide initialization code should go here.
044   *
045   * <p>Users should override this method for default Robot-wide initialization which will be called
046   * when the robot is first powered on. It will be called exactly one time.
047   *
048   * <p>Warning: the Driver Station "Robot Code" light and FMS "Robot Ready" indicators will be off
049   * until RobotInit() exits. Code in RobotInit() that waits for enable will cause the robot to
050   * never indicate that the code is ready, causing the robot to be bypassed in a match.
051   */
052  protected void robotInit() {
053    System.out.println("Default robotInit() method running, consider providing your own");
054  }
055
056  /**
057   * Disabled should go here. Users should overload this method to run code that should run while
058   * the field is disabled.
059   *
060   * <p>Called once each time the robot enters the disabled state.
061   */
062  protected void disabled() {
063    System.out.println("Default disabled() method running, consider providing your own");
064  }
065
066  /**
067   * Autonomous should go here. Users should add autonomous code to this method that should run
068   * while the field is in the autonomous period.
069   *
070   * <p>Called once each time the robot enters the autonomous state.
071   */
072  public void autonomous() {
073    System.out.println("Default autonomous() method running, consider providing your own");
074  }
075
076  /**
077   * Operator control (tele-operated) code should go here. Users should add Operator Control code to
078   * this method that should run while the field is in the Operator Control (tele-operated) period.
079   *
080   * <p>Called once each time the robot enters the operator-controlled state.
081   */
082  public void operatorControl() {
083    System.out.println("Default operatorControl() method running, consider providing your own");
084  }
085
086  /**
087   * Test code should go here. Users should add test code to this method that should run while the
088   * robot is in test mode.
089   */
090  @SuppressWarnings("PMD.JUnit4TestShouldUseTestAnnotation")
091  public void test() {
092    System.out.println("Default test() method running, consider providing your own");
093  }
094
095  /**
096   * Robot main program for free-form programs.
097   *
098   * <p>This should be overridden by user subclasses if the intent is to not use the autonomous()
099   * and operatorControl() methods. In that case, the program is responsible for sensing when to run
100   * the autonomous and operator control functions in their program.
101   *
102   * <p>This method will be called immediately after the constructor is called. If it has not been
103   * overridden by a user subclass (i.e. the default version runs), then the robotInit(),
104   * disabled(), autonomous() and operatorControl() methods will be called.
105   */
106  public void robotMain() {
107    m_robotMainOverridden = false;
108  }
109
110  /**
111   * Start a competition. This code tracks the order of the field starting to ensure that everything
112   * happens in the right order. Repeatedly run the correct method, either Autonomous or
113   * OperatorControl when the robot is enabled. After running the correct method, wait for some
114   * state to change, either the other mode starts or the robot is disabled. Then go back and wait
115   * for the robot to be enabled again.
116   */
117  public void startCompetition() {
118    robotInit();
119
120    // Tell the DS that the robot is ready to be enabled
121    HAL.observeUserProgramStarting();
122
123    robotMain();
124
125    if (!m_robotMainOverridden) {
126      while (true) {
127        if (isDisabled()) {
128          m_ds.InDisabled(true);
129          disabled();
130          m_ds.InDisabled(false);
131          while (isDisabled()) {
132            Timer.delay(0.01);
133          }
134        } else if (isAutonomous()) {
135          m_ds.InAutonomous(true);
136          autonomous();
137          m_ds.InAutonomous(false);
138          while (isAutonomous() && !isDisabled()) {
139            Timer.delay(0.01);
140          }
141        } else if (isTest()) {
142          LiveWindow.setEnabled(true);
143          m_ds.InTest(true);
144          test();
145          m_ds.InTest(false);
146          while (isTest() && isEnabled()) {
147            Timer.delay(0.01);
148          }
149          LiveWindow.setEnabled(false);
150        } else {
151          m_ds.InOperatorControl(true);
152          operatorControl();
153          m_ds.InOperatorControl(false);
154          while (isOperatorControl() && !isDisabled()) {
155            Timer.delay(0.01);
156          }
157        }
158      } /* while loop */
159    }
160  }
161}