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}