Files
allwpilib/wpilibc/src/main/native/cpp/framework/TimedRobot.cpp
Zach Harel a8c7f3e3c6 [wpilib] Change opmodes to purely periodic (#8652)
1. Make the OpMode interface itself periodic; this means the only
differences between `OpMode` and `PeriodicOpMode` are the latter's
methods to add sideloaded periodic callbacks
2. Make OpModeRobot process callbacks in a similar fashion to TimedRobot
and
3. Add some lifecycle functions (discussed below)
4. Pull the callback priority queue from TimedRobot to a new class
called `PeriodicPriorityQueue` so that `TimedRobot` and `OpModeRobot`
have less duplication
5. Fix a typo in the DriverStationJNI class that causes a memory leak
when certain driver station sim calls
6. Port the C++ OpModeRobot tests to Java 

`OpModeRobot` now possesses some `IterativeRobotBase`-stye lifecycle
functions; these functions
1. `robotPeriodic` 
2. `simulationInit` and `simulationPeriodic` 
3. `disabledInit`, `disabledPeriodic`, and `disabledExit`
(note that `simulationInit` and `disabledInit` may be renamed to match
wpilibsuite#8719)

`OpModeRobot` also now processes `OpMode` changes (by the Driver
Station) in its `loopFunc` method, similar to
`IterativeRobotBase.loopFunc` processing game mode changes; `loopFunc`
is, similarly to `TimedRobot`, provided as a default `Callback`

---------

Signed-off-by: Zach Harel <zach@zharel.me>
Co-authored-by: Joseph Eng <91924258+KangarooKoala@users.noreply.github.com>
2026-04-10 13:40:17 -07:00

69 lines
1.9 KiB
C++

// Copyright (c) FIRST and other WPILib contributors.
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include "wpi/framework/TimedRobot.hpp"
#include <stdint.h>
#include <cstdio>
#include <utility>
#include "wpi/driverstation/DriverStation.hpp"
#include "wpi/hal/DriverStation.hpp"
#include "wpi/hal/UsageReporting.hpp"
#include "wpi/system/Errors.hpp"
#include "wpi/system/RobotController.hpp"
using namespace wpi;
void TimedRobot::StartCompetition() {
if constexpr (IsSimulation()) {
SimulationInit();
}
// Tell the DS that the robot is ready to be enabled
std::puts("\n********** Robot program startup complete **********");
DriverStation::ObserveUserProgramStarting();
// Loop forever, calling the appropriate mode-dependent function
while (true) {
if (!m_callbacks.RunCallbacks(m_notifier)) {
break;
}
}
}
void TimedRobot::EndCompetition() {
HAL_DestroyNotifier(m_notifier);
m_notifier = HAL_INVALID_HANDLE;
}
TimedRobot::TimedRobot(wpi::units::second_t period)
: IterativeRobotBase(period) {
m_startTime = std::chrono::microseconds{RobotController::GetMonotonicTime()};
AddPeriodic([=, this] { LoopFunc(); }, period);
int32_t status = 0;
m_notifier = HAL_CreateNotifier(&status);
WPILIB_CheckErrorStatus(status, "InitializeNotifier");
HAL_SetNotifierName(m_notifier, "TimedRobot", &status);
HAL_ReportUsage("Framework", "TimedRobot");
}
TimedRobot::TimedRobot(wpi::units::hertz_t frequency)
: TimedRobot{1 / frequency} {}
TimedRobot::~TimedRobot() {
if (m_notifier != HAL_INVALID_HANDLE) {
HAL_DestroyNotifier(m_notifier);
}
}
void TimedRobot::AddPeriodic(std::function<void()> callback,
wpi::units::second_t period,
wpi::units::second_t offset) {
m_callbacks.Add(std::move(callback), m_startTime, period, offset);
}