001/*----------------------------------------------------------------------------*/ 002/* Copyright (c) FIRST 2008-2012. 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/*----------------------------------------------------------------------------*/ 007package edu.wpi.first.wpilibj; 008 009import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary; 010import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances; 011import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType; 012import edu.wpi.first.wpilibj.communication.UsageReporting; 013import edu.wpi.first.wpilibj.Timer; 014import edu.wpi.first.wpilibj.livewindow.LiveWindow; 015 016/** 017 * IterativeRobot implements a specific type of Robot Program framework, extending the RobotBase class. 018 * 019 * The IterativeRobot class is intended to be subclassed by a user creating a robot program. 020 * 021 * This class is intended to implement the "old style" default code, by providing 022 * the following functions which are called by the main loop, startCompetition(), at the appropriate times: 023 * 024 * robotInit() -- provide for initialization at robot power-on 025 * 026 * init() functions -- each of the following functions is called once when the 027 * appropriate mode is entered: 028 * - DisabledInit() -- called only when first disabled 029 * - AutonomousInit() -- called each and every time autonomous is entered from another mode 030 * - TeleopInit() -- called each and every time teleop is entered from another mode 031 * - TestInit() -- called each and every time test mode is entered from anothermode 032 * 033 * Periodic() functions -- each of these functions is called iteratively at the 034 * appropriate periodic rate (aka the "slow loop"). The period of 035 * the iterative robot is synced to the driver station control packets, 036 * giving a periodic frequency of about 50Hz (50 times per second). 037 * - disabledPeriodic() 038 * - autonomousPeriodic() 039 * - teleopPeriodic() 040 * - testPeriodoc() 041 * 042 */ 043public class IterativeRobot extends RobotBase { 044 private boolean m_disabledInitialized; 045 private boolean m_autonomousInitialized; 046 private boolean m_teleopInitialized; 047 private boolean m_testInitialized; 048 049 /** 050 * Constructor for RobotIterativeBase 051 * 052 * The constructor initializes the instance variables for the robot to indicate 053 * the status of initialization for disabled, autonomous, and teleop code. 054 */ 055 public IterativeRobot() { 056 // set status for initialization of disabled, autonomous, and teleop code. 057 m_disabledInitialized = false; 058 m_autonomousInitialized = false; 059 m_teleopInitialized = false; 060 m_testInitialized = false; 061 } 062 063 @Override 064 protected void prestart() { 065 // Don't immediately say that the robot's ready to be enabled. 066 // See below. 067 } 068 069 /** 070 * Provide an alternate "main loop" via startCompetition(). 071 * 072 */ 073 public void startCompetition() { 074 UsageReporting.report(tResourceType.kResourceType_Framework, tInstances.kFramework_Iterative); 075 076 robotInit(); 077 078 // We call this now (not in prestart like default) so that the robot 079 // won't enable until the initialization has finished. This is useful 080 // because otherwise it's sometimes possible to enable the robot 081 // before the code is ready. 082 FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramStarting(); 083 084 // loop forever, calling the appropriate mode-dependent function 085 LiveWindow.setEnabled(false); 086 while (true) { 087 // Call the appropriate function depending upon the current robot mode 088 if (isDisabled()) { 089 // call DisabledInit() if we are now just entering disabled mode from 090 // either a different mode or from power-on 091 if (!m_disabledInitialized) { 092 LiveWindow.setEnabled(false); 093 disabledInit(); 094 m_disabledInitialized = true; 095 // reset the initialization flags for the other modes 096 m_autonomousInitialized = false; 097 m_teleopInitialized = false; 098 m_testInitialized = false; 099 } 100 if (nextPeriodReady()) { 101 FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramDisabled(); 102 disabledPeriodic(); 103 } 104 } else if (isTest()) { 105 // call TestInit() if we are now just entering test mode from either 106 // a different mode or from power-on 107 if (!m_testInitialized) { 108 LiveWindow.setEnabled(true); 109 testInit(); 110 m_testInitialized = true; 111 m_autonomousInitialized = false; 112 m_teleopInitialized = false; 113 m_disabledInitialized = false; 114 } 115 if (nextPeriodReady()) { 116 FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramTest(); 117 testPeriodic(); 118 } 119 } else if (isAutonomous()) { 120 // call Autonomous_Init() if this is the first time 121 // we've entered autonomous_mode 122 if (!m_autonomousInitialized) { 123 LiveWindow.setEnabled(false); 124 // KBS NOTE: old code reset all PWMs and relays to "safe values" 125 // whenever entering autonomous mode, before calling 126 // "Autonomous_Init()" 127 autonomousInit(); 128 m_autonomousInitialized = true; 129 m_testInitialized = false; 130 m_teleopInitialized = false; 131 m_disabledInitialized = false; 132 } 133 if (nextPeriodReady()) { 134 FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramAutonomous(); 135 autonomousPeriodic(); 136 } 137 } else { 138 // call Teleop_Init() if this is the first time 139 // we've entered teleop_mode 140 if (!m_teleopInitialized) { 141 LiveWindow.setEnabled(false); 142 teleopInit(); 143 m_teleopInitialized = true; 144 m_testInitialized = false; 145 m_autonomousInitialized = false; 146 m_disabledInitialized = false; 147 } 148 if (nextPeriodReady()) { 149 FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramTeleop(); 150 teleopPeriodic(); 151 } 152 } 153 m_ds.waitForData(); 154 } 155 } 156 157 /** 158 * Determine if the appropriate next periodic function should be called. 159 * Call the periodic functions whenever a packet is received from the Driver Station, or about every 20ms. 160 */ 161 private boolean nextPeriodReady() { 162 return m_ds.isNewControlData(); 163 } 164 165 /* ----------- Overridable initialization code -----------------*/ 166 167 /** 168 * Robot-wide initialization code should go here. 169 * 170 * Users should override this method for default Robot-wide initialization which will 171 * be called when the robot is first powered on. It will be called exactly 1 time. 172 */ 173 public void robotInit() { 174 System.out.println("Default IterativeRobot.robotInit() method... Overload me!"); 175 } 176 177 /** 178 * Initialization code for disabled mode should go here. 179 * 180 * Users should override this method for initialization code which will be called each time 181 * the robot enters disabled mode. 182 */ 183 public void disabledInit() { 184 System.out.println("Default IterativeRobot.disabledInit() method... Overload me!"); 185 } 186 187 /** 188 * Initialization code for autonomous mode should go here. 189 * 190 * Users should override this method for initialization code which will be called each time 191 * the robot enters autonomous mode. 192 */ 193 public void autonomousInit() { 194 System.out.println("Default IterativeRobot.autonomousInit() method... Overload me!"); 195 } 196 197 /** 198 * Initialization code for teleop mode should go here. 199 * 200 * Users should override this method for initialization code which will be called each time 201 * the robot enters teleop mode. 202 */ 203 public void teleopInit() { 204 System.out.println("Default IterativeRobot.teleopInit() method... Overload me!"); 205 } 206 207 /** 208 * Initialization code for test mode should go here. 209 * 210 * Users should override this method for initialization code which will be called each time 211 * the robot enters test mode. 212 */ 213 public void testInit() { 214 System.out.println("Default IterativeRobot.testInit() method... Overload me!"); 215 } 216 217 /* ----------- Overridable periodic code -----------------*/ 218 219 private boolean dpFirstRun = true; 220 /** 221 * Periodic code for disabled mode should go here. 222 * 223 * Users should override this method for code which will be called periodically at a regular 224 * rate while the robot is in disabled mode. 225 */ 226 public void disabledPeriodic() { 227 if (dpFirstRun) { 228 System.out.println("Default IterativeRobot.disabledPeriodic() method... Overload me!"); 229 dpFirstRun = false; 230 } 231 Timer.delay(0.001); 232 } 233 234 private boolean apFirstRun = true; 235 236 /** 237 * Periodic code for autonomous mode should go here. 238 * 239 * Users should override this method for code which will be called periodically at a regular 240 * rate while the robot is in autonomous mode. 241 */ 242 public void autonomousPeriodic() { 243 if (apFirstRun) { 244 System.out.println("Default IterativeRobot.autonomousPeriodic() method... Overload me!"); 245 apFirstRun = false; 246 } 247 Timer.delay(0.001); 248 } 249 250 private boolean tpFirstRun = true; 251 252 /** 253 * Periodic code for teleop mode should go here. 254 * 255 * Users should override this method for code which will be called periodically at a regular 256 * rate while the robot is in teleop mode. 257 */ 258 public void teleopPeriodic() { 259 if (tpFirstRun) { 260 System.out.println("Default IterativeRobot.teleopPeriodic() method... Overload me!"); 261 tpFirstRun = false; 262 } 263 Timer.delay(0.001); 264 } 265 266 private boolean tmpFirstRun = true; 267 268 /** 269 * Periodic code for test mode should go here 270 * 271 * Users should override this method for code which will be called periodically at a regular rate 272 * while the robot is in test mode. 273 */ 274 public void testPeriodic() { 275 if (tmpFirstRun) { 276 System.out.println("Default IterativeRobot.testPeriodic() method... Overload me!"); 277 tmpFirstRun = false; 278 } 279 } 280}