Running commands that control the drive subsystem in the middle of a path #146
Replies: 4 comments 16 replies
-
Thinking about this, I suppose one option would be to have a duplicate versions of commands (like auto aim and Shoot in our case) that are used in both in Autonomous and Teleop periods of the match. With the autonomous version of the command "not" requiring the drive subsystem. The drive subsystem would already be required by the path follower command so this would prevent the default drive joystick command from taking control. Then have another version of the "auto aim and shoot" command that is bound to a button for use during teleop with this command requiring the drive subsystem (So that it does interrupt the default drive command from the joystick) and hence allows the robot to auto aim and shoot. I wish I had of thought of this at the beginning of the year and it would have saved me a lot of pain with nested sequential command groups that were needed to get around this problem. Alternatively is there a way to add a command to command group at runtime and ignore the subsystem/s that they require to avoid this command interruption problem that occurs when more then one command in a sequential group require the same subsystem. |
Beta Was this translation helpful? Give feedback.
-
I'm not exactly sure what the problem here is. What "interruption problem"? Maybe C++ is different, but there's nothing wrong with doing new SequentialCommandGroup(
new PPSwerveControllerCommand(pathGroup[0], ...),
new TurnToTargetAndShoot(),
new PPSwerveControllerCommand(pathGroup[1], ...),
...
) at least in Java. |
Beta Was this translation helpful? Give feedback.
-
This would just prevent the marker command from running at all. If the schedule can't get the requirements it needs for a command to run (because an uninterruptible command currently has the requirement) it won't schedule the command and it will just skip it.
I'm really looking forward to this top level auto executor. My thoughts are there are two ways you could attack this. You could try and construct a sequential command group that is made up of a series of PPSwerveControllerCommands (that have the marker code as it stands now) followed by the commands that are added at the stop points (it wouldn't matter if these needed the same subsystem because they are in the same sequential command) with this pattern repeated over and over until all path segments in the path group and all the associated stop point commands have been traversed. Then execute this one constructed sequential command group when the auto starts. (i'm guessing that what you are thinking at the moment) Another alternative is to make this top level command have no commands at all with every command that needs to run, being run with a ->Schedule() call. This way you will never have a subsystem requirement killing the top level auto command. The only problem with this is once a command has been fired with the ->Schedule() method the top level command wouldn't know the state of where that command is up to (ie if its finished or not). You would have to continually poll the scheduler with an isScheduled() call on the command that is currently running in the auto routine (either a ppSwerveControllerCommand or a stop point command.) so that you know if you are allowed to move onto the next command or not. All this checking would be happening in the execute method of the top level auto command. It gets a bit tricky at the stop points trying to work out if you are allowed to go on or not. Sometimes you might want these stop point commands to be executing without waiting, other times you might not want the auto to continue until the stop point commands are done and other times you might want a time out. I'm not sure I like the wait time being hard coded into the stop point, I feel a better option would be build to a parallel command group on the fly at the stop point from the list of commands to be run at the stop point and then schedule it with a ->Schedule() call from the top level auto command. Ditch the wait time at the stop point and replace this with a true or false boolean at the stop point that indicates if these stop point commands should "execute and continue" or "execute and wait until done" before moving onto the next path segment. If people want to wait for seconds at a stop point they can add a delay command as one of the commands to be executed at the stop point with the wait until done flag set at the stop point. By using this method you give the end user the ability to execute these stop point commands in any way they want. If the end user wants commands to execute sequentially at a stop point they would need to build a sequential command group and add that command to the command map. If you want more granularity over the control at the stop points you could add an extra fields into the command map at the stop point.(not sure if this can be done). Or you could use the command name member variable of the command as a method to give you more control on how commands are executed at stop points. This rarely get used by teams and top level auto follower could check the name of the commands in the stop point command map using the GetName() method. If its blank or starts with p_ assume this is a command that is going to be run in parallel at the stop point. If it starts with s_ make this command run sequentially at the stop point and keep checking the IsScheduled() to know if you can move onto the next stop point command or onto the next path segment. I feel autonomous debugging would be easier if you used the later method with everything being run with the ->Schedule() approach. But I also see how building the sequential group completely before running means you wouldn't have to check if thing are finished with repeated IsScheduled() calls.
I actually prefer the scheduling at a marker approach as it stands at the moment, because in order to make this into an all in one command group you will need to create a parallel groups with delay times at the front of the marker commands to run in parallel with the path following commands. And the fact that you running them in parallel with the path following doesn't get around requirement issues anyway. "Additionally, requirements are enforced within all three types of parallel groups - a parallel group may not contain multiple commands that require the same subsystem." Quoted from the docs. I don't actually know what happens if you attempt to do this, I'm assuming it will interrupt itself) So I think it has to be a hard and fast rule that marker commands can't require the drive. This completely makes sense as the robot is following a path at this point in time so the marker commands can't take control of the drive. I'd even schedule the PPServerControllerCommands with the uninterruptible flag so this could never accidental happen. Personally, I like the option of the top level auto having no commands and no requirement so that it can never be canceled from a mistake of someone adding two commands that run in parallel that require the same subsystem at either marker points or stop points. |
Beta Was this translation helpful? Give feedback.
-
I just built PP from scratch. I noticed there is no option to add commands to a stop point command map at this point in time. Are you planning to have a different command map for the "Stop Point" Commands as compared to the "Marker Commands" or, are the stop point commands just normal marker commands with whole number values for their position? |
Beta Was this translation helpful? Give feedback.
-
With the addition of the ability to break paths into segments and run commands between segments I'm wondering how someone with a non turret robot (us) would use an auto aiming command in between two segments of a path.
What we did this year was use individual paths for each segment of the auto and we built a separate command to follow each segment.
Than we build a nested sequential command group that scheduled new SequentialCommandGroups each time we that did something that required the drive subsystem.
For example we had a sequential command group that
- Shoot command--> This used the limelight to check distance and bearing to target, rotate drive base until error to target was less than 1 degree and shoot until empty ----> This command required the drive subsystem (so that it could rotate to the target) this interrupted the top level command group but it didn't matter as the next command group was now running. Once shooting was done we then used a ScheduleCommand to schedule another command group to Open the intake and follow the 2nd segment of the path, stop and then used another ScheduleCommand to schedule another group to shoot etc, etc..
So basically the last command in each level of the command was a ScheduleCommand with a new SequentialCommandGroup that had the remaining steps in the auto routine.
Do you have any ideas how we make this fit into the new model of one command for an entire auto routine?
Code from Robot Container for one of our auto shown here if that helps.
Beta Was this translation helpful? Give feedback.
All reactions