Add preliminary articles for commands V3#21
Conversation
| --- | ||
| import Aside from '../../../components/Aside.astro'; | ||
|
|
||
| # What is a Command? |
There was a problem hiding this comment.
I think it needs some explanation of what command based programming is to make the transition between intro to Java and FRC programming smoother. I also think that knowing what is Command Based programming as a concept, even if it's in simple terms, is important.
This introduction could also mention what WPILib is since it's sort of mentioned in #9 but it's never correctly explained.
There was a problem hiding this comment.
It would probably be better to direct them to the WPILib docs on commands / subsystems and say 'familiarize yourself with commands and subsystems before continuing with this section'.
In this section you can refer back to it, but you're likely going to need to reiterate everything that's already said in those docs in order to provide the necessary context for teaching this lesson.
There was a problem hiding this comment.
I didn't do that because when I first read wpilib's command docs as a freshman, they pretty much threw everything at you all at once instead of starting with the basics.
Maybe V3 docs would be different, im down to moving some of the stuff covered here to the wpilib docs instead and redirecting people.
| as raising an arm joint or complex as an autonomous program. Think of them as powered-up | ||
| methods that can handle the requirements for controlling a robot over long periods of time. | ||
|
|
||
| # What's wrong with methods? |
There was a problem hiding this comment.
What about "Why not use methods?" because I think that's the question most new programmers might think. also "what's wrong" could sound like methods aren't supposed to be used in FRC programming
| ``` | ||
| Here, the problem is with the while loop. While it's running, we are only setting the voltage of the motor; | ||
| not listening to button presses, logging data, and running other background tasks. To function properly, WPILib | ||
| requires many of these background tasks to be run periodically(at a 0.02 second or smaller interval). |
There was a problem hiding this comment.
What about
many of these background tasks to be run periodically, which means they run at 0.02 seconds or at a smaller interval
| Functionally, commands are superpowered methods that gives you a special statement that runs | ||
| these background tasks within a while loop: `coroutine.yield()`. | ||
| ```java | ||
| System.out.println("Hello World!"); |
There was a problem hiding this comment.
System.out.println isn't used for print outs in FRC but I think this is a good spot to introduce and use Driverstation.reportWarning()
| The following allows you to start a command asynchronously: | ||
|
|
||
| ```java | ||
| Command runMotor = ...; // see previous example |
There was a problem hiding this comment.
I would just put the previous code there instead so viewers don't have to keep scrolling up to reference it. In addition, you could put a comment like //code from previous example on top so viewers know where the code is coming from if that's helpful
| will run before the `runMotor` command completes. | ||
|
|
||
| But the vast majority of the time, you want a command to run when a button is pressed or held down. | ||
| To do this, we use a `CommandGamepad` instead of a `Gamepad`, like so: |
There was a problem hiding this comment.
At this point, they don't know what a Gamepad is so it's probably not worth mentioning
There was a problem hiding this comment.
Wouldn't they have to know it due to section 1a being about coding a kitbot?
|
|
||
| In this case, the `runMotor` command will run once the left trigger is pressed. | ||
| If it is desired to cancel the runMotor command once the left trigger is released, | ||
| the `onTrue` statement can be replaced with `whileTrue`: |
There was a problem hiding this comment.
I would explain more on why that is the case
There was a problem hiding this comment.
Trigger binding functions could use their own section with the nice graphs from that one site
|
|
||
| # An overview of Mechanisms | ||
|
|
||
| A `Mechanism`, on the surface level, is a part of the robot, like a double-jointed arm or a shooter. |
There was a problem hiding this comment.
It also might help to briefly explain the connection between Commands and Mechanisms. Could be as simple as explaining how Mechanism use Commands to move a part of the robot. Like spinning a motor on a shooter to shot a ball.
There was a problem hiding this comment.
I think a mechanism is any part of the robot you want to control separately from any other mechanism. Mechanisms run a single command at a time. If you want to run two separate commands, you need two mechanisms. Sometimes this corresponds to subsystem-level components, but they really should be thought of as two separate ways of grouping the robot. The mapping of real world mechanisms to command mechanisms is not always 1:1
| # An overview of Mechanisms | ||
|
|
||
| A `Mechanism`, on the surface level, is a part of the robot, like a double-jointed arm or a shooter. | ||
| If you've used commands V2 before, they're the exact same thing as subsystems (and in that case, feel free |
There was a problem hiding this comment.
Might be worth putting that in a note rather than in a paragraph
| # What's wrong with methods? | ||
|
|
||
| Let's say you're writing a method that prints "hello world!" to the console, | ||
| then sets a motor to 5 volts indefinitely. Your first instinct might be to do this: | ||
| ```java | ||
| public void printHiAndRunMotor() { | ||
| System.out.println("Hello World!"); | ||
| while (true) { | ||
| motor.setVoltage(5.0); | ||
| } | ||
| } | ||
| ``` | ||
| Here, the problem is with the while loop. While it's running, we are only setting the voltage of the motor; | ||
| not listening to button presses, logging data, and running other background tasks. To function properly, WPILib | ||
| requires many of these background tasks to be run periodically(at a 0.02 second or smaller interval). |
There was a problem hiding this comment.
I think this is a poor example of explaining the benefits of command-based, since it's solved in iterative robots.
I don't think the comparison between commands and methods necessarily needs to happen. Commands at their heart are methods, the power of the paradigm is the declarative nature and deferred execution.
| Functionally, commands are superpowered methods that gives you a special statement that runs | ||
| these background tasks within a while loop: `coroutine.yield()`. |
There was a problem hiding this comment.
Likewise, they're much more than just this.
There was a problem hiding this comment.
I mean, are they? The only other feature that a command itself introduces is scoped triggers. If anything, its trigger declarations themselves that are declarative, not commands.
You might have a better idea of how to phrase this, though.
There was a problem hiding this comment.
If you don't use a while loop, you still have a command.
They also have lifecycles, can be chained together into compositions, and are the way you define what code a subsystem execute. I think that last one is really at the heart of what a command is.
|
|
||
| <Aside type="note"> | ||
| Because `coroutine.yield()` can't be called outside of commands, it is highly discouraged | ||
| to use while loops outside of commands unless if you know what you're doing. |
There was a problem hiding this comment.
Don't include unless ~if~ you know what you're doing. The teams that do already know this
|
|
||
| # Running Commands | ||
|
|
||
| The following allows you to start a command asynchronously: |
There was a problem hiding this comment.
I did clarify it in the following sentence (in this case...), but i'll try and clarify this. Thanks!
| without waiting for it to finish. In this case, the `println("Hello!")` statement | ||
| will run before the `runMotor` command completes. | ||
|
|
||
| But the vast majority of the time, you want a command to run when a button is pressed or held down. |
There was a problem hiding this comment.
This should probably go in a new section of triggers or scheduling commands
| # Defining a Mechanism | ||
|
|
||
| Mechanisms are represented as classes in java, inside their own separate files. | ||
| Note that a mechanism class slightly deviates from a traditional class with the `implements Mechanism` keyword at the end. |
There was a problem hiding this comment.
I wouldn't try and suggest that a 'traditional' class can't implement interfaces. Just say that Mechanisms must implement the interface, and maybe explain that that means they tell other parts of the code that they are guaranteed to have certain functionality that is required of mechanisms
|
|
||
| # Defining commands that require a mechanism | ||
|
|
||
| In general, commands that require a mechanism should be defined inside of that mechanism's class. |
There was a problem hiding this comment.
Avoid 'In general' or other suggestive phrases. One of the harder parts is teaching things like 'where should commands be defined', and other code structure decisions.
| Then, in the `Robot.java` file, you would simply define an instance of each mechanism like so: | ||
| ```java | ||
| public class Robot { | ||
| private final Shooter shooter = new Shooter(); |
There was a problem hiding this comment.
This is gonna make it hard to access in command compositions that don't exist in this class. Make it public or package private imo
| private final TalonFX motor = new TalonFX(4); | ||
|
|
||
| public Shooter() { | ||
| Command shoot = |
| However, this poses a problem: the `shoot` command isn't accessible to the Robot class, | ||
| since it only exists inside of the constructor of the Shooter class. To remedy this, we | ||
| can instead make a method that creates an instance of the `shoot` command: |
There was a problem hiding this comment.
Oh. Don't make an example just to say 'btw this is a bad example'
There was a problem hiding this comment.
This is missing the explanation that this needs to be a method rather than a variable, especially since previous examples stored commands in variables
Co-authored-by: Adriana <adrianammassie@gmail.com> Co-authored-by: Tim Winters <twinters007@gmail.com>
No description provided.