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/*----------------------------------------------------------------------------*/ 007 008package edu.wpi.first.wpilibj; 009 010import java.io.File; 011import java.io.FileOutputStream; 012import java.io.IOException; 013import java.io.OutputStream; 014import java.io.IOException; 015import java.net.URL; 016import java.util.Enumeration; 017import java.util.jar.Manifest; 018import java.util.Arrays; 019 020import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary; 021import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tInstances; 022import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType; 023import edu.wpi.first.wpilibj.communication.UsageReporting; 024import edu.wpi.first.wpilibj.internal.HardwareHLUsageReporting; 025import edu.wpi.first.wpilibj.internal.HardwareTimer; 026import edu.wpi.first.wpilibj.networktables.NetworkTable; 027import edu.wpi.first.wpilibj.Utility; 028 029/** 030 * Implement a Robot Program framework. 031 * The RobotBase class is intended to be subclassed by a user creating a robot program. 032 * Overridden autonomous() and operatorControl() methods are called at the appropriate time 033 * as the match proceeds. In the current implementation, the Autonomous code will run to 034 * completion before the OperatorControl code could start. In the future the Autonomous code 035 * might be spawned as a task, then killed at the end of the Autonomous period. 036 */ 037public abstract class RobotBase { 038 /** 039 * The VxWorks priority that robot code should work at (so Java code should run at) 040 */ 041 public static final int ROBOT_TASK_PRIORITY = 101; 042 043 protected final DriverStation m_ds; 044 045 /** 046 * Constructor for a generic robot program. 047 * User code should be placed in the constructor that runs before the Autonomous or Operator 048 * Control period starts. The constructor will run to completion before Autonomous is entered. 049 * 050 * This must be used to ensure that the communications code starts. In the future it would be 051 * nice to put this code into it's own task that loads on boot so ensure that it runs. 052 */ 053 protected RobotBase() { 054 // TODO: StartCAPI(); 055 // TODO: See if the next line is necessary 056 // Resource.RestartProgram(); 057 058 NetworkTable.setServerMode();//must be before b 059 m_ds = DriverStation.getInstance(); 060 NetworkTable.getTable(""); // forces network tables to initialize 061 NetworkTable.getTable("LiveWindow").getSubTable("~STATUS~").putBoolean("LW Enabled", false); 062 } 063 064 /** 065 * Free the resources for a RobotBase class. 066 */ 067 public void free() { 068 } 069 070 /** 071 * @return If the robot is running in simulation. 072 */ 073 public static boolean isSimulation() { 074 return false; 075 } 076 077 /** 078 * @return If the robot is running in the real world. 079 */ 080 public static boolean isReal() { 081 return true; 082 } 083 084 /** 085 * Determine if the Robot is currently disabled. 086 * @return True if the Robot is currently disabled by the field controls. 087 */ 088 public boolean isDisabled() { 089 return m_ds.isDisabled(); 090 } 091 092 /** 093 * Determine if the Robot is currently enabled. 094 * @return True if the Robot is currently enabled by the field controls. 095 */ 096 public boolean isEnabled() { 097 return m_ds.isEnabled(); 098 } 099 100 /** 101 * Determine if the robot is currently in Autonomous mode. 102 * @return True if the robot is currently operating Autonomously as determined by the field controls. 103 */ 104 public boolean isAutonomous() { 105 return m_ds.isAutonomous(); 106 } 107 108 /** 109 * Determine if the robot is currently in Test mode 110 * @return True if the robot is currently operating in Test mode as determined by the driver station. 111 */ 112 public boolean isTest() { 113 return m_ds.isTest(); 114 } 115 116 /** 117 * Determine if the robot is currently in Operator Control mode. 118 * @return True if the robot is currently operating in Tele-Op mode as determined by the field controls. 119 */ 120 public boolean isOperatorControl() { 121 return m_ds.isOperatorControl(); 122 } 123 124 /** 125 * Indicates if new data is available from the driver station. 126 * @return Has new data arrived over the network since the last time this function was called? 127 */ 128 public boolean isNewDataAvailable() { 129 return m_ds.isNewControlData(); 130 } 131 132 /** 133 * Provide an alternate "main loop" via startCompetition(). 134 */ 135 public abstract void startCompetition(); 136 137 /** 138 * This hook is called right before startCompetition(). By default, tell the 139 * DS that the robot is now ready to be enabled. If you don't want for the 140 * robot to be enabled yet, you can override this method to do nothing. 141 * If you do so, you will need to call 142 * FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationOvserveUserProgramStarting() from 143 * your code when you are ready for the robot to be enabled. 144 */ 145 protected void prestart() { 146 FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramStarting(); 147 } 148 149 public static boolean getBooleanProperty(String name, boolean defaultValue) { 150 String propVal = System.getProperty(name); 151 if (propVal == null) { 152 return defaultValue; 153 } 154 if (propVal.equalsIgnoreCase("false")) { 155 return false; 156 } else if (propVal.equalsIgnoreCase("true")) { 157 return true; 158 } else { 159 throw new IllegalStateException(propVal); 160 } 161 } 162 163 /** 164 * Common initialization for all robot programs. 165 */ 166 public static void initializeHardwareConfiguration(){ 167 FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationReserve(); 168 169 // Set some implementations so that the static methods work properly 170 Timer.SetImplementation(new HardwareTimer()); 171 HLUsageReporting.SetImplementation(new HardwareHLUsageReporting()); 172 RobotState.SetImplementation(DriverStation.getInstance()); 173 } 174 175 /** 176 * Starting point for the applications. 177 */ 178 public static void main(String args[]) { 179 initializeHardwareConfiguration(); 180 181 UsageReporting.report(tResourceType.kResourceType_Language, tInstances.kLanguage_Java); 182 183 String robotName = ""; 184 Enumeration<URL> resources = null; 185 try { 186 resources = RobotBase.class.getClassLoader().getResources("META-INF/MANIFEST.MF"); 187 } catch (IOException e) {e.printStackTrace();} 188 while (resources != null && resources.hasMoreElements()) { 189 try { 190 Manifest manifest = new Manifest(resources.nextElement().openStream()); 191 robotName = manifest.getMainAttributes().getValue("Robot-Class"); 192 } catch (IOException e) {e.printStackTrace();} 193 } 194 195 RobotBase robot; 196 try { 197 robot = (RobotBase) Class.forName(robotName).newInstance(); 198 robot.prestart(); 199 } catch (Throwable t) { 200 DriverStation.reportError("ERROR Unhandled exception instantiating robot " + robotName + " " + t.toString() + " at " + Arrays.toString(t.getStackTrace()), false); 201 System.err.println("WARNING: Robots don't quit!"); 202 System.err.println("ERROR: Could not instantiate robot " + robotName + "!"); 203 System.exit(1); 204 return; 205 } 206 207 File file = null; 208 FileOutputStream output = null; 209 try { 210 file = new File("/tmp/frc_versions/FRC_Lib_Version.ini"); 211 212 if (file.exists()) 213 file.delete(); 214 215 file.createNewFile(); 216 217 output = new FileOutputStream(file); 218 219 output.write("2015 Java 1.0.0".getBytes()); 220 221 } catch (IOException ex) { 222 ex.printStackTrace(); 223 } finally { 224 if (output != null) { 225 try { 226 output.close(); 227 } catch (IOException ex) { 228 } 229 } 230 } 231 232 boolean errorOnExit = false; 233 try { 234 robot.startCompetition(); 235 } catch (Throwable t) { 236 DriverStation.reportError("ERROR Unhandled exception: " + t.toString() + " at " + Arrays.toString(t.getStackTrace()), false); 237 errorOnExit = true; 238 } finally { 239 // startCompetition never returns unless exception occurs.... 240 System.err.println("WARNING: Robots don't quit!"); 241 if (errorOnExit) { 242 System.err.println("---> The startCompetition() method (or methods called by it) should have handled the exception above."); 243 } else { 244 System.err.println("---> Unexpected return from startCompetition() method."); 245 } 246 } 247 System.exit(1); 248 } 249}