[wpilib] OpModeRobot: set up notifier before calling observe starting (#8547)

This avoids a simulation race.
This commit is contained in:
Peter Johnson
2026-01-12 19:11:58 -08:00
committed by GitHub
parent 05225a29a7
commit c2b339cfc9
2 changed files with 22 additions and 2 deletions

View File

@@ -92,7 +92,6 @@ class MonitorThread : public wpi::util::SafeThreadEvent {
void OpModeRobotBase::StartCompetition() {
fmt::print("********** Robot program startup complete **********\n");
HAL_ObserveUserProgramStarting();
wpi::util::Event event;
struct DSListener {
@@ -108,6 +107,7 @@ void OpModeRobotBase::StartCompetition() {
HAL_SetNotifierName(m_notifier, "OpModeRobot", &status);
int64_t lastModeId = -1;
bool calledObserveUserProgramStarting = false;
bool calledDriverStationConnected = false;
std::shared_ptr<OpMode> opMode;
WPI_EventHandle events[] = {event.GetHandle(),
@@ -116,6 +116,16 @@ void OpModeRobotBase::StartCompetition() {
for (;;) {
// Wait for new data from the driver station, with 50 ms timeout
HAL_SetNotifierAlarm(m_notifier, 50000, 0, false, true, &status);
// Call HAL_ObserveUserProgramStarting() here as a one-shot to ensure it is
// called after the notifier alarm is set. The notifier alarm is set using
// relative time, so tests that wait on the user program to start and then
// step time won't work correctly if we call this before setting the alarm.
if (!calledObserveUserProgramStarting) {
calledObserveUserProgramStarting = true;
HAL_ObserveUserProgramStarting();
}
auto signaled = wpi::util::WaitForObjects(events, signaledBuf);
if (signaled.empty()) {
return; // handles destroyed

View File

@@ -566,7 +566,6 @@ public abstract class OpModeRobot extends RobotBase {
@Override
public final void startCompetition() {
System.out.println("********** Robot program startup complete **********");
DriverStationJNI.observeUserProgramStarting();
int event = WPIUtilJNI.createEvent(false, false);
DriverStationJNI.provideNewDataEventHandle(event);
@@ -577,11 +576,22 @@ public abstract class OpModeRobot extends RobotBase {
try {
// Implement the opmode lifecycle
long lastModeId = -1;
boolean calledObserveUserProgramStarting = false;
boolean calledDriverStationConnected = false;
int[] events = {event, m_notifier};
while (true) {
// Wait for new data from the driver station, with 50 ms timeout
NotifierJNI.setNotifierAlarm(m_notifier, 50000, 0, false, true);
// Call observeUserProgramStarting() here as a one-shot to ensure it is called after the
// notifier alarm is set. The notifier alarm is set using relative time, so tests that
// wait on the user program to start and then step time won't work correctly if we call
// this before setting the alarm.
if (!calledObserveUserProgramStarting) {
calledObserveUserProgramStarting = true;
DriverStationJNI.observeUserProgramStarting();
}
try {
int[] signaled = WPIUtilJNI.waitForObjects(events);
for (int val : signaled) {