Schedule subsystem periodics at different frequencies

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);

  }
}
1 Like

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.

1 Like

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.

putting the CommandScheduler in addPeriodic just looked cleaner than overriding robotPeriodic

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

1 Like

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.

Something like notifer perchance?

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.

1 Like

So doesn’t notifier create a separate thread where as add periodic runs single threaded.

Yes

Any idea how many notifiers are safe to make on the rio

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)