|
|
|
![]() |
|
|||||||
|
||||||||
![]() |
|
|
Thread Tools | Rate Thread | Display Modes |
|
|
|
#1
|
||||
|
||||
|
Command Based JAVA - Basic Tutorial
I have put together a basic tutorial on how to use the Command Based JAVA approach.
All Feedback is welcome! Dave Frederick Mentor, Team 1895 Manassas, VA |
|
#2
|
||||
|
||||
|
Re: Command Based JAVA - Basic Tutorial
Yes! I've been waiting for this
Even the last version you posted was one of the best compilations I'd seen. |
|
#3
|
||||
|
||||
|
Re: Command Based JAVA - Basic Tutorial
Very well presented and detailed. I will be saving that for future use, if you don't mind.
![]() |
|
#4
|
||||
|
||||
|
Re: Command Based JAVA - Basic Tutorial
For those of us who are curious but don't have the time right now to wade through this, can someone please post an "executive summary" of how this command-based architecture works "under the hood"? Is it spawning threads in response to events? |
|
#5
|
||||
|
||||
|
Re: Command Based JAVA - Basic Tutorial
Here's my understanding of the Command Based robot project. Please feel free to correct me where I'm wrong.
First an overview of the concept: There are two major classes which are provided that can be extended to contain the majority of the robot specific code, the Subsystem class and the Command class. Subsystems characterize mechanisms on your robot. So each subsystem (drivetrain, shooter, lift, etc) should extend the Subsystem class and implement any methods for the functionality that subsystem can perform. It abstracts hardware specific funcitons from the rest of the program. So the shooter may have a method setSpeed which takes a parameter in RPMs, but this alone wouldn't be enough to shoot a ball. You will likely need to interact with multiple subsystems to do that. This is where the Command class comes in. The purpose of the command class is to build more complex sets of functions, a procedure to follow to complete a task. For many commands this requires using methods across a number of subsystems. Groups of commands can be created to complete a number of steps in series or parallel (or a mix of both). Commands are then linked into operator interfaces (e.g. joystick buttons) or even executed from autonomous modes. You need to conform somewhat rigidly to the framework for everything to work, but this can have the advantage of helping you organize your thoughts. How it works: New instances of Commands are created from events (e.g. button press from operator). These instances are passed to a scheduler which maintains a list of all the active commands. Commands have a number of methods which allow the scheduler to step through their execution (initialize(), execute(), isFinished(), end()). Part of a command definition provides information as to which Subsystems are required for the particular command. This allows the scheduler to identify conflicting commands, and handle which ones get to execute. Basically whichever command was issued last will execute (if there was a subsystem dependency conflict). The command based robot project builds on top or the iterative robot project. Methods for each game mode (teleopPeriodic(), autonomousPeriodic()) are called repeatedly (every 20ms - with each driver station update). Calls to the scheduler's run() method are required within the teleop and auto periodic mode methods to allow the scheduler to process outstanding commands. I found this presentation to be particularly helpful. Start at slide 18. Once you understand the model it makes building up a fairly complex system quite painless. Throwing together auto mode actions become quite easy, as it simply becomes a new command which calls other existing commands that in many cases have already been tested and proven to work in teleop. Last edited by otherguy : 28-11-2012 at 02:13. Reason: added reference to slide # in linked presentation |
|
#6
|
||||
|
||||
|
Re: Command Based JAVA - Basic Tutorial
This sounds problematic, unless I'm misunderstanding what was intended.
|
|
#7
|
|||
|
|||
|
Re: Command Based JAVA - Basic Tutorial
Commands run "in parallel" unless they have a subsystem dependency conflict. Methods are provided by the Command class in order to allow a command to do something if it is "interrupted" by another command that requires the same subsystems.
See http://www.wbrobotics.com/javadoc/ed...l#interrupted() The Command class also lets you set a command as non-interruptible, but I'm not sure if the scheduler actually honors that or if it is for you to fetch with isInterruptible when making some decisions somewhere.... I've never actually tried it. Last edited by BigJ : 28-11-2012 at 09:38. |
|
#8
|
||||
|
||||
|
Re: Command Based JAVA - Basic Tutorial
Quote:
|
|
#9
|
|||
|
|||
|
Re: Command Based JAVA - Basic Tutorial
I haven't actually dived into the scheduler to look at it. I'm not sure if it threads or if it is basically splitting the IterativeRobot style command loops between the commands. We've never done anything particularly timing-intensive (yet
) so we never had to look. (that's why I added the quotation marks, hehe)EDIT: The cookbook says commands are accessed around every 20ms. It doesn't mention anything about priority, though. Last edited by BigJ : 28-11-2012 at 09:49. |
|
#10
|
||||
|
||||
|
Re: Command Based JAVA - Basic Tutorial
The command architecture is an interesting concept for robotics, but only because our processors are powerful enough to jump through the extra layers of abstraction without effecting the mechanical performance. I've experimented with sending high-level (marshalled) commands from a prompt to my quadrotor with some success. The architecture is essentially a queue for predicates and closures. The key to success on a larger system is managing compounding and/or non-deterministic behavior that causes the command queue to get gummed up.
As a reviewer's note, the command queue itself should have overriding interrupts -- ways to interrupt the current command with a higher priority command for the same subsystem. End-users under high pressure in an intense match are REALLY good at hitting the wrong button (e.g. to tell an arm to go down when they really wanted it to go up) and then changing their minds in under a few milliseconds. |
|
#11
|
|||
|
|||
|
Re: Command Based JAVA - Basic Tutorial
As long as your commands require the same subsystem a new command will interrupt the first and go. This lets you run a "default" joystick driving command at all times and interrupt it to do a separate controlled command with the drive subsystem for something like an autoscoring mechanism in a game like '11.
|
|
#12
|
||||
|
||||
|
Re: Command Based JAVA - Basic Tutorial
Quote:
|
|
#13
|
|||||
|
|||||
|
Re: Command Based JAVA - Basic Tutorial
A few questions on the command architecture (without reading the paper at the beginning of the document):
-Do subsystems get poked by run() also? Or does run() just poke all of the active commands? -Is the architecture designed for the subsystems to store the subsystem state, or for the commands to store subsystem state? I would assume the subsystems store their state, but if they don't get poked then the have to wait for a command in progress to do anything (or you have to manually poke them, or start a new thread). |
|
#14
|
||||
|
||||
|
Re: Command Based JAVA - Basic Tutorial
Quote:
Quote:
The state of a command sequence is kept track of by the commands and scheduler. A subsystem only knows how to interact with itself. It can turn a motor on/off, it can read the status of a sensor. Alone, it doesn't do you much good. The subsystem alone is not intended to be completing complex tasks. The command keeps track of state through it's methods (previously mentioned). The command has something it needs to do, in the execute() method. Then a check is performed to see if a terminating condition is met, in the isFinished() method. So the command itself has a notion of what needs to be done and when it should consider the task complete. Multiple commands can be linked together (series or parallel execution) in a Command Group. This allows more complex tasks to be built up from a simple set of commands, simply by calling the commands in the right order. For example if you wanted to aquire a ball from a made up robot with a drop down intake, a lift system which moved balls vertically,you may have the following subsystems and methods within them: Dropdown_Intake()The above subsystems and methods strictly set output values and read input values.raise()Elevator_Lift() You may then create the following commands: RaiseIntake()And then the following Command Group to aquire one ball: RaiseLiftUntilBallPresent()it could execute the following commands in sequenceand the group of commands could terminate when ElevatorLift.isBallPresent() returns true. Other command groups could then be created as necessary re-using some of the above commands for other teleop or autonomous functions. |
|
#15
|
||||||
|
||||||
|
Re: Command Based JAVA - Basic Tutorial
Quote:
I've been playing with the command based system, and our 2012 robot which was implemented in a huge, overly complicated, state machine in LabVIEW was able to be reduced to about 20 fairly simple commands without the need for additional state machines. You are correct that it would be more proper to call it an abort. However, interrupted is the term that the command based library uses. There is an optional method for a command to define that allows it to clean up before it is interrupted. Last edited by Joe Ross : 28-11-2012 at 12:35. |
![]() |
| Thread Tools | |
| Display Modes | Rate This Thread |
|
|