For a number of years, my team has used WPILib’s Sample Robot class to provide more customizability and freedom in our development. What do you all think about it’s deprecation, and do you see it being completely removed in the future?
Could you elaborate on what kinds of customization you’ve needed to do? I’ve been a proponent of removing SampleRobot for years because TimedRobot is superior in the vast majority of usecases. We haven’t done so because nothing has completely superseded it in the way TimedRobot has superseded IterativeRobot.
I think TimedRobot’s the way to go for almost any non-command-based use case.
With the exposure of the main entrypoint as well this year, I would think the flexibility went up in all template starting points.
We have used SampleRobot (formerly SimpleRobot) since the introduction of C++ and the cRIO in 2009. Over the years we have developed an architecture that we can rely on to perform our control system tasks reliably. We prefer the flexibility and control of maintaining our own timing loop as well as allowing us to perform tasks (such as mechanism calibration) before and/or after that timing loop for the duration of the autonomous or teleop period. I see no reason that it should be deprecated or removed. Why would you remove the opportunity for a team to structure their code as they prefer??
The problem with SampleRobot is it sits in a poor place in how much functionality it provides. This function is the entirety of what it provides, but to use it successfully, your code has to call nearly all the same functions as the library code (e.g. call isDisabled() et al) to know when to exit your function so that mode switching works.
If you are an advanced user scheduling tasks across mode boundaries (which it sounds like you are), you almost certainly end up overriding RobotMain() to get robust mode switching functionality, in which case you’re probably better off just deriving from RobotBase (you can easily make the one-line call to observeUserProgramStarting). The rest of the structure of the while loop is very easy for an advanced user to implement in the way they would prefer (e.g. if they’re advanced enough to do their own architecture instead of TimedRobot, they’ve probably outgrown what that loop provides in terms of functionality).
If you are a novice user, SampleRobot is very risky to use because the transition between modes is controlled by the user. This was a particular problem when it was called SimpleRobot and we had our sample programs use it–we saw a large number of novice teams using it because it was “Simple” or because they started from a sample, and writing loops that only exited based on time or a condition being met, which led to them not successfully switching modes (e.g. they couldn’t control their robot in teleop because it never exited auto). It is very appealing for auto because it lets you write sequences in a clear way, but with the mode switching requirements, it’s just too risky. Using TimedRobot and just saying “don’t use unbounded loops” is much easier to teach.
So basically SampleRobot doesn’t do a good job of meeting the needs of either advanced users (who can just use RobotBase) or novice users, and intermediate users would be best using TimedRobot as well.
Periodic loops are precisely what TimedRobot is good at; it uses a Notifier, which is triggered by the FPGA, to keep tight scheduling, so it’ll perform better than some time-then-wait loop in SampleRobot. The mechanism calibration you mention can be done in teleopInit(), disabledInit(), or autonomousInit() and the periodic things would use one of the teleop/disabled/autonomous/robot Periodic() functions (robotPeriodic() runs in all modes).
By the way, I was looking at your 2018 code, and you should consider using wpi::outs() from wpi/raw_ostream.h. It’s more readable than printf() and just as fast. wpi::format() from wpi/Format.h does formatting if you need to pad things with zeroes or something. There’s a lot of other goodies from LLVM in there too.