So this has been a thought I’ve had for quite a bit of time now.
Currently its not possible to schedule the subsystem periodic method at a different frequency via the CommandScheduler.
You could use addPeriodic to schedule a subsystem’s periodic method at a different frequency. However you would have to prevent it from being called by the CommandScheduler.
So that would mean not registering it. Not using SubsystemBase (just the Subsystem interface) when declaring your subsystem. And not using a default command.
Here is a super tiny example. I used an anonymous class for the subsystem to keep it all together in one file.
Not you still have to call CommandScheduler’s run method in the robotPeriodic method, but I put it as its own addPeriodic (just for fun).
public class Robot extends TimedRobot {
@SuppressWarnings("resource")
public Robot() {
CommandXboxController controller = new CommandXboxController(0);
controller.a().onTrue(Commands.run(() -> System.out.println(Timer.getFPGATimestamp())));
addPeriodic(CommandScheduler.getInstance()::run, 0.020);
@SuppressWarnings("unused")
Subsystem subsystem = new Subsystem() {
@Override
public void periodic() {
System.out.println("Subsystem Periodic Time" + Timer.getFPGATimestamp());
};
};
addPeriodic(subsystem::periodic, 0.005);
}
}
An interesting idea for future years might be to merge TimedRobot and CommandScheduler. Combining their functionality could allow a variety of things such as
in build support for running subsystem periodics at different speeds
restricting users of command based to the command based paradigm (ie not exposing teleopPeriodic etc)
One interesting way of approaching this as is would be adding a periodic to your Superstructure and running that at a different frequency. Its difficult to make this cover all usecases while still working fully with the command based framework but could be good for something like higher frequency sensor reads.
In ROS you can set the frequency of publishers on different topics. This is super handy and I would love to see some version of this in command based with setting hz as the team needs for different purposes.
Just use a different method name (i.e. anything other than periodic). Then you can schedule it however youd like with addPeriodic(), and can still let the scheduler manage the subsystem
That’s an option too. My goal was to use the existing periodic method on its own timer and not have to create another.
You can still do this with this approach and the scheduler manager is now just handling the scheduling of commands and not the running of subsystem periodics
In many respects The CommandScheduler feels like it violates the Single Responsibility principle. It handles the scheduling of commands (and the running of subsystem periodics).
The easy solution would be to have a PeriodicScheduler, but I wanted to avoid the plumbing there and use the existing setup.
This does sound interesting but would probably complicate NT more to end users which would probably be undesirable, a lot of people already struggle with using NT directly.
Not sure. I think to do this cleanly it would be better to make more major structural changes (ie my earlier post about merging the scheduler and timed robot)