Resolved artf3579: robot can no longer be enabled until robotInit() finishes in IterativeRobot; similar options available by overriding prestart() for other base classes.

Change-Id: I07fde4b1bd2fae0c2e2a04336639b44ec715628a
This commit is contained in:
Colby Skeggs
2014-12-09 02:30:34 +00:00
parent ac60198842
commit 1c24096cc9
7 changed files with 55 additions and 21 deletions

View File

@@ -60,6 +60,8 @@ public:
virtual void TestPeriodic();
protected:
virtual void Prestart();
virtual ~IterativeRobot();
IterativeRobot();

View File

@@ -14,9 +14,10 @@ class DriverStation;
int main() \
{ \
if (!HALInitialize()){std::cerr<<"FATAL ERROR: HAL could not be initialized"<<std::endl;return -1;} \
HALNetworkCommunicationObserveUserProgramStarting(); \
HALReport(HALUsageReporting::kResourceType_Language, HALUsageReporting::kLanguage_CPlusPlus); \
(new _ClassName_())->StartCompetition(); \
_ClassName_ *robot = new _ClassName_(); \
robot->Prestart();\
robot->StartCompetition(); \
return 0; \
}
@@ -49,6 +50,8 @@ protected:
virtual ~RobotBase();
RobotBase();
virtual void Prestart();
Task *m_task;
DriverStation *m_ds;

View File

@@ -36,6 +36,11 @@ IterativeRobot::~IterativeRobot()
{
}
void IterativeRobot::Prestart() {
// Don't immediately say that the robot's ready to be enabled.
// See below.
}
/**
* Provide an alternate "main loop" via StartCompetition().
*
@@ -54,6 +59,12 @@ void IterativeRobot::StartCompetition()
NetworkTable::GetTable("LiveWindow")->GetSubTable("~STATUS~")->PutBoolean("LW Enabled", false);
RobotInit();
// We call this now (not in Prestart like default) so that the robot
// won't enable until the initialization has finished. This is useful
// because otherwise it's sometimes possible to enable the robot
// before the code is ready.
HALNetworkCommunicationObserveUserProgramStarting();
// loop forever, calling the appropriate mode-dependent function
lw->SetEnabled(false);
while (true)

View File

@@ -39,7 +39,7 @@ RobotBase &RobotBase::getInstance()
/**
* Constructor for a generic robot program.
* User code should be placed in the constuctor that runs before the Autonomous or Operator
* User code should be placed in the constructor that runs before the Autonomous or Operator
* Control period starts. The constructor will run to completion before Autonomous is entered.
*
* This must be used to ensure that the communications code starts. In the future it would be
@@ -88,7 +88,7 @@ bool RobotBase::IsDisabled()
}
/**
* Determine if the robot is currently in Autnomous mode.
* Determine if the robot is currently in Autonomous mode.
* @return True if the robot is currently operating Autonomously as determined by the field controls.
*/
bool RobotBase::IsAutonomous()
@@ -114,6 +114,15 @@ bool RobotBase::IsTest()
return m_ds->IsTest();
}
/**
* This hook is called right before startCompetition(). By default, tell the DS that the robot is now ready to
* be enabled. If you don't want for the robot to be enabled yet, you can override this method to do nothing.
*/
void RobotBase::Prestart()
{
HALNetworkCommunicationObserveUserProgramStarting();
}
/**
* Indicates if new data is available from the driver station.
* @return Has new data arrived over the network since the last time this function was called?

View File

@@ -59,6 +59,12 @@ public class IterativeRobot extends RobotBase {
m_teleopInitialized = false;
m_testInitialized = false;
}
@Override
protected void prestart() {
// Don't immediately say that the robot's ready to be enabled.
// See below.
}
/**
* Provide an alternate "main loop" via startCompetition().
@@ -68,15 +74,12 @@ public class IterativeRobot extends RobotBase {
UsageReporting.report(tResourceType.kResourceType_Framework, tInstances.kFramework_Iterative);
robotInit();
// tracing support:
final int TRACE_LOOP_MAX = 100;
int loopCount = TRACE_LOOP_MAX;
Object marker = null;
boolean didDisabledPeriodic = false;
boolean didAutonomousPeriodic = false;
boolean didTeleopPeriodic = false;
boolean didTestPeriodic = false;
// We call this now (not in prestart like default) so that the robot
// won't enable until the initialization has finished. This is useful
// because otherwise it's sometimes possible to enable the robot
// before the code is ready.
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramStarting();
// loop forever, calling the appropriate mode-dependent function
LiveWindow.setEnabled(false);
@@ -97,7 +100,6 @@ public class IterativeRobot extends RobotBase {
if (nextPeriodReady()) {
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramDisabled();
disabledPeriodic();
didDisabledPeriodic = true;
}
} else if (isTest()) {
// call TestInit() if we are now just entering test mode from either
@@ -113,7 +115,6 @@ public class IterativeRobot extends RobotBase {
if (nextPeriodReady()) {
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramTest();
testPeriodic();
didTestPeriodic = true;
}
} else if (isAutonomous()) {
// call Autonomous_Init() if this is the first time
@@ -132,7 +133,6 @@ public class IterativeRobot extends RobotBase {
if (nextPeriodReady()) {
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramAutonomous();
autonomousPeriodic();
didAutonomousPeriodic = true;
}
} else {
// call Teleop_Init() if this is the first time
@@ -148,7 +148,6 @@ public class IterativeRobot extends RobotBase {
if (nextPeriodReady()) {
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramTeleop();
teleopPeriodic();
didTeleopPeriodic = true;
}
}
m_ds.waitForData();

View File

@@ -130,6 +130,15 @@ public abstract class RobotBase {
*/
public abstract void startCompetition();
/**
* This hook is called right before startCompetition(). By default, tell the
* DS that the robot is now ready to be enabled. If you don't want for the
* robot to be enabled yet, you can override this method to do nothing.
*/
protected void prestart() {
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramStarting();
}
public static boolean getBooleanProperty(String name, boolean defaultValue) {
String propVal = System.getProperty(name);
if (propVal == null) {
@@ -149,7 +158,6 @@ public abstract class RobotBase {
*/
public static void initializeHardwareConfiguration(){
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationReserve();
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramStarting();
// Set some implementations so that the static methods work properly
Timer.SetImplementation(new HardwareTimer());
@@ -161,8 +169,6 @@ public abstract class RobotBase {
* Starting point for the applications.
*/
public static void main(String args[]) {
boolean errorOnExit = false;
initializeHardwareConfiguration();
UsageReporting.report(tResourceType.kResourceType_Language, tInstances.kLanguage_Java);
@@ -182,14 +188,16 @@ public abstract class RobotBase {
RobotBase robot;
try {
robot = (RobotBase) Class.forName(robotName).newInstance();
robot.prestart();
} catch (Throwable t) {
DriverStation.reportError("ERROR Unhandled exception instantiating robot " + robotName + " " + t.toString() + " at " + Arrays.toString(t.getStackTrace()), false);
System.err.println("WARNING: Robots don't quit!");
System.err.println("ERROR: Could not instantiate robot "+robotName+"!");
System.err.println("ERROR: Could not instantiate robot " + robotName + "!");
System.exit(1);
return;
}
boolean errorOnExit = false;
try {
robot.startCompetition();
} catch (Throwable t) {

View File

@@ -18,6 +18,7 @@ import org.junit.runners.model.MultipleFailureException;
import edu.wpi.first.wpilibj.DriverStation;
import edu.wpi.first.wpilibj.RobotBase;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
@@ -44,6 +45,7 @@ public abstract class AbstractComsSetup {
if (!initialized) {
// Set some implementations so that the static methods work properly
RobotBase.initializeHardwareConfiguration();
FRCNetworkCommunicationsLibrary.FRCNetworkCommunicationObserveUserProgramStarting();
LiveWindow.setEnabled(false);
TestBench.out().println("Started coms");