Command based Java programming for new Programers

I am a programmer on team 6121, we lost our lead programmer last year and he did not teach anybody. We have the code from the last couple of years and it is super hard to follow. We have made a basic drive train but we are struggling to go any further. We are looking for any help you can give. We are struggling with programming another subsystem and command just to spin one motor. Whatever resources you all have would be very helpful.

1 Like

Yeah Command Based Java is kind of hard to learn at first but it gets easier! I would recommend going on youtube and watching all of the BetaWolves tutorials on Command Based Java , he does a great job of emphasizing the uses and importance of all the different classes. He also talks about how to make commands and subsystems.

2 Likes

For any new programmers, I recommend only a very basic understanding of java. Such an education can easily be acquired on codeacademy. WPILIB screensteps is the place to learn how java applies to frc. https://wpilib.screenstepslive.com/s/4485

I would recommend reading the documentation for the new command-based library here: https://docs.wpilib.org/en/latest/docs/software/commandbased/index.html

This website is also the official site for WPILib documentation in 2020.

6 Likes

Here are a couple of presentations we’ve given over several years. If you have any questions please feel free to reach out.

http://team2363.org/2016/11/command-based-java-for-frc/

Here is another good presentation from 319:

3 Likes

We have already watched them and that is how we got our drive train.

all of us have a good basic understanding of java two of us have taken AP computer science

A recent topic which asked essentially the same question and has some good links:

1 Like

Definitely look here rather than ScreenSteps, which is being phased out this year.

2 Likes

so here is what i have so far and i was wondering what was wrong with my intake subsystem. i can not seem to have a command require it and i did declare it in robot

https://github.com/EliteTV/Frc-pre-season/tree/master/src/main/java/frc/robot

When it comes to robotics, not only should you know Java, but you really need to know object oriented java to understand what is happening.

I’ll assuming the old code you are looking at is from 2017 and currently on your github. Here are some issue I see with it, and why you don’t understand it.

While the robot is command based, the core of it isn’t Command Based. It’s like a spaghetti taco. While it is still technically a taco (because of its outer shell/structure) many would say its a complete different food entirely. A similar thing appears to be happening with some of the naming conventions and commits, someone has gone through the motions without knowing how or why to do them properly. (I personally enjoy the “bleh” commit)

Command Based Java typically has 3 “sections” of code: The Subsystems, The Commands, and The “Robot” code (not to be confused with just the robot file). Each of these sections leads itself to a particular function, and is most useful if used for that function. To understand how this is structured this way, lets take a step back at the basics.

Not Command Based Coding

The most basic starting point is the robot.java file. Here, a multitude of task occur that allow your robot to function. The basic goal?

  1. Declare a motor object (Give the object a place to live)
  2. Instantiate a motor object (Create an object at the location created above)
  3. Call a set Command for the motor. (Make the motor do something!)

This might look something like this:

Talon motor0; //Declaration
motor0 = new Talon(); //Instantiation
motor0.set(1.0); //Make it move!

Congratulations, you have a motor moving. Now, you will still have to figure out in what methods you want to put these commands to make it work, that’s your challenge (and possible something I can cover if you want me to, but I diverge). Next Steps? Make more motors!

You can repeat those steps for other motors, and then for a joystick, using getter methods from the joystick object to allow you to put actual control into motors as oppose to just 100% power. You may start to notice that while we could do this for all the functions of the robot, it would soon become cumbersome to work with.

Subsystems
Subsystems are a way to organize all of that code from above. If you have 4 motors that are part of a drivetrain, you can put them all together in a class, and then call methods for them together.
image
As shown above, there are 4 motors in this drive subsystem. A method setPower() sets the left side of the drive to one power and the right side to another. You can create additional methods and objects within this class, which allow them to be create all together and encourages encapsulation. In robot.java, you can create the subsystem as a single object and then call methods from there.
Methods in the subsystem are often relatively simple, and routes are commonly left to commands (discussed next).

Commands
Commands are the next step in a command-based program. Commands call methods within the subsystem to make create a certain sequence of actions. Sometimes, basic commands can see repetitive and unnecessary, but this often they shine when multiple subsystems are needed.
There are 6 methods in most commands. Some methods are left blank, they are:

  1. The Constructor - The most important part of the constructor is the requires() method, which is used to declare subsystem dependencies. Multiple commands can run at once, but only one command per subsystem. This prevents multi-threading issues.
  2. initialize() - Runs once at the beginning of the command.
  3. execute() - Runs over and over until the command ends
  4. isFinished() - checks to see if the command is finished, if you return true, it is. (Note, the command can also end if interrupted or the whileheld() button method is used)
  5. end() - Runs once at the end of the command.
  6. interrupt() - Runs if another command starts that needs a subsystem that this method is using. The other command “interrupts” this method. Note, the newly started command does not run the interrupt method, only the old one.

(Please Ignore the errors, I wrote it quickly and didn’t make a Joystick properly.


You can see this is a very simple command. However, we could imagine a command that:
Requires a shooter and drivetrain
Initialize() a shooter power to 0.7
Execute() code to drive a robot towards a vision target
IsFinished() when the robot reaches the target
End() with shooting the ball and then stopping the shooter wheels

Some of our more experienced folks might see the possible bugs that could occur in the above system, but the general idea of Commands are explained.

Each subsystem also has a method called initDefaultCommand(). This lets you create a default command that will run if no other command is running.

Part 2, coming to a theater near you
The above is the basic structure, but with another college exam coming up tonight (nothing like two in one day), I’m off to study before I finish the rest. Remember kids, school comes first! If anyone has any questions or comments about the above, feel free to ask. Also, the above is a very condensed version of what I typically teach over multiple 3 hour meetings, so feel free to point out if I missed something that leads to a misconception. Chow!

4 Likes

You named both the Subsystem class and Command class Intake, and then confused them elsewhere in your code.

In your Robot class you are importing import frc.robot.commands.Intake; which is the command, which means that a few lines down, public static Intake intake = new Intake(); is a Command, not a Subsystem. Change the import statement to import frc.robot.subsystems.Intake; and the requires() statement should work in the command.

I’d recommend renaming one or both of the classes though to limit confusion. A general practice used in many workplaces is to try not to use words that can be verbs, as nouns, even if grammatically correct.

Thank you and i will do that in the future

An alternate solution which might be easier is to make sure that your verbs are clearly verbs, as the great majority of nouns can be used as other parts of speech. Even such obvious nouns as sandwich, pencil, knife, and floor can be used as verbs.

And in case it isn’t clear, the subsystem should have a noun name, and the command a verb name. When an action/command only applies to a given system, I have sometimes included the system as part of the name. In this example, you might rename Intake the command to be something more like pushIntake or pullIntake or moveIntake.

1 Like

Some teams, including mine, always end a subsystem class name with the word subsystem, so an it would be a intakeSubsystem, drivetrainSubsystem, etc…

These are old and true the Command Base Model is getting a major overhaul for 2020 but the basic flow and concepts still apply. These are from Brad Miller and WPI six ~15 min videos RobotBuilder 6
We too have presentations Slides and Youtube recodings of basicly the Robotbuilder 6 preformed at JUMPSTART the past few year on the Granite City Gearheads youtube channel.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.