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