-
Notifications
You must be signed in to change notification settings - Fork 611
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[commands] Clarified error messages for parallel composition commands #7161
base: main
Are you sure you want to change the base?
Conversation
This PR modifies commands. Please open a corresponding PR in Python Commands and include a link to this PR. |
|
/format |
You'll need to install and run wpiformat yourself, the PR format command will not work if the PR is based on your main branch. For the future, it's best to make a branch for each PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should only include the subsystems that are actually conflicting, since if we just report which ones the added command requires, we aren't actually communicating information that couldn't be found in other ways.
…between commands in a parallel group
var currentRequirements = getRequirements(); | ||
if (!Collections.disjoint(command.getRequirements(), currentRequirements)) { | ||
String requirementsStr = command.getRequirements() | ||
.stream() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Stream API is really inefficient (for these use cases) and is generally avoided in the WPILib codebase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like it’s probably fine to use the stream api here, even if it’s slow, because this code will only run when an error happens anyways
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keeping the Java and C++ implementations similar will make it easier to maintain, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It'd be good to extract the logic into a utility function, but personally I'm fine with this PR getting merged as it is to avoid further delays. Actual WPILib maintainers will need to weigh in, though.
throw new IllegalArgumentException( | ||
"Multiple commands in a parallel group cannot require the same subsystems"); | ||
String.format( | ||
"Command %s could not be added to this ParallelCommandGroup" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest avoiding the word ParallelCommandGroup
as that class is only one of the ones relevant. "Parallel composition" would be more accurate.
Alright just resolved the naming issues brought up by @Starlight220 and changed the method to a utility method. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit iffy about some things:
ensureDisjointRequirements()
doesn't feel the best to me (maybecheckDisjointRequirements()
would be nicer?). Ultimately I personally am fine if it stays with the name, but I would like a better name if we can think of one.- I'm not the happiest about C++ having a fairly different implementation- It's largely similar enough that I think okay, but it's suboptimal. The lack of a
retainAll()
equivalent is problematic, though.
* @param parallelGroup The parallel group command. | ||
* @param toAdd The command that will be added to the parallel group. | ||
*/ | ||
public static void ensureDisjointRequirements(Command parallelGroup, Command toAdd) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do we want to put this method? Right now Commands
consists solely of command factories, and it'd be nice if we kept it that way.
Here's some other options I thought of:
- Protected non-static method of
Command
. - Public static method of
Command
. - Public static method of
ParallelCommandGroup
(which the others use).
#6032 is somewhat relevant for the placement, since if that PR was merged we could just make it a private method of ParallelCommandGroup
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah a protected non-static Command method is a great idea honestly, didn't think of that.
Currently Command doesn't have any static methods so I was hesistant to make it a public method of that, and ended up choosing Commands instead(which i didnt really like either but yeah)
* Throws an error if a parallel group already shares | ||
* one or more requirements with a command | ||
* that will be added to it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an FYI, this will need to be formatted (and since your main
branch is a PR branch, /format on your PRs won't work). You can look at the comment-command .yml file to see what steps you should run to format. (pip3 install wpiformat==2024.45
, wpiformat
, and ./gradlew spotlessApply
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah forgot to run /format
protected void ensureDisjointRequirements(Command parallelGroup, Command toAdd) { | ||
var sharedRequirements = new HashSet<>(parallelGroup.getRequirements()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
protected void ensureDisjointRequirements(Command parallelGroup, Command toAdd) { | |
var sharedRequirements = new HashSet<>(parallelGroup.getRequirements()); | |
protected void ensureDisjointRequirements(Command toAdd) { | |
var sharedRequirements = new HashSet<>(getRequirements()); |
Might as well use that it's non-static.
*/ | ||
bool RequirementsDisjoint(Command* first, Command* second); | ||
void EnsureDisjointRequirements(Command* parallelGroup, Command* toAdd); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could move this into the Command
class too.
Co-authored-by: Joseph Eng <[email protected]>
Just added the requested changes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, great work! Unfortunately, it can take a while to finish all of the little details.
Formatting still needs to be done, and I'm about 90% happy with the name ensureRequirementsDisjoint()
- It works, but requireRequirementsDisjoint()
or requireDisjointRequirements()
might fit the existing naming better (CommandScheduler.requireNotComposed()
and CommandScheduler.requireNotComposedOrScheduled()
). The dual use of require
is a bit annoying though.
@rzblue and @Starlight220- Thoughts on the removal of frc2::RequirementsDisjoint
without deprecation?
Also, tests would be nice but tricky to do, so I'm not 100% sure if they're worth implementing.
Addresses Issue #6353.