We have been using the command based paradigm (in C++) in our programs for the past three years, and plan to use it again next year (maybe in Python). We have found that when we create a Command only a few methods are unique. For example, we usually only write code for the constructor and one or two other methods (usually Execute, Initialize, or IsFinished). The rest have empty bodies.
Noticing a pattern, we created some generic classes, which can be found in our GitHub repository. We try to create sensible defaults: Initialize, Execute, and End do nothing; IsFinished returns false; and Interrupted calls End. That has saved us a lot of typing.
We also noticed that certain variations come up a lot. The most noticeable are commands that run for a fixed duration and commands that change one thing and then end. So we created TimedCommand which requires a timeout value and checks IsTimedOut in IsFinished, and InstantCommand which returns true in IsFinished. We then inherit from those to get the behavior we want.
Many of our team members are interested in Python this year, so we are experimenting with it, and the maintainer of robotpy-wpilib asked if we'd be interested in adding helper classes for command based programming to the utilities repository, since currently command based programming is regarded as having too much boilerplate code for Python. When we submitted our pull request, we were told we should mention our changes here, in case there was an interest in changing the default behavior.
The basic idea would be to implement default methods in the Command class (instead of making them pure abstract), and add TimedCommand and InstantCommand alongside the other existing commands. As far as we can see, this would not have any impact on existing robot programs, but it might save teams from typing so much boilerplate when creating new commands.
We can write the C++ code, but someone else would have to handle the Java side.
We have been using the command based paradigm (in C++) in our programs for the past three years, and plan to use it again next year (maybe in Python). We have found that when we create a
Command
only a few methods are unique. For example, we usually only write code for the constructor and one or two other methods (usuallyExecute
,Initialize
, orIsFinished
). The rest have empty bodies.Noticing a pattern, we created some generic classes, which can be found in our GitHub repository. We try to create sensible defaults:
Initialize
,Execute
, andEnd
do nothing;IsFinished
returns false; andInterrupted
callsEnd
. That has saved us a lot of typing.We also noticed that certain variations come up a lot. The most noticeable are commands that run for a fixed duration and commands that change one thing and then end. So we created
TimedCommand
which requires a timeout value and checksIsTimedOut
inIsFinished
, andInstantCommand
which returns true inIsFinished
. We then inherit from those to get the behavior we want.Many of our team members are interested in Python this year, so we are experimenting with it, and the maintainer of robotpy-wpilib asked if we'd be interested in adding helper classes for command based programming to the utilities repository, since currently command based programming is regarded as having too much boilerplate code for Python. When we submitted our pull request, we were told we should mention our changes here, in case there was an interest in changing the default behavior.
The basic idea would be to implement default methods in the
Command
class (instead of making them pure abstract), and addTimedCommand
andInstantCommand
alongside the other existing commands. As far as we can see, this would not have any impact on existing robot programs, but it might save teams from typing so much boilerplate when creating new commands.We can write the C++ code, but someone else would have to handle the Java side.