Help creating a simple arcade drive in the new 2020 command based Framework (Java)

Hi fellow FRC partners, I am currently trying to program a simple arcade drive using the new command base framework (2020) and I got halfway through porting our 2019 code java to the new framework and I can’t seem to figure out the RobotContainer part. I know some will ask “have you read the WPILB’S documentation and examples” and the answer is “YES” well at least to the extent that could understand it. We are fairly new (rookie team) to programming in Java and the more I read, the more confused I become. I’ve searched some posts here, but most of it is written in technical jargon that I cannot understand it.

So far, I have created a subsystem for my drivetrain, a command for it but I am stuck to the part of setting up the Joystick and I dont’know how to set it up to the command. I have four motors controlled by Talon SRx (set up as master and slave ) and would like to use the generic controller (Logitech) that came with te rookie tote. All the Youtube videos cover the 2019 command-based framework which has worked for me but I don’t know how to port it to the 2020 version. Can any one tell me a simple way to implement this arcade drive so we can get started or anyone would have a simple of arcade drive example using the new 2020 Java command-based framework?

Any help would be much appreciated!
RobotContainerCommand

To pass functions as arguments, your ArcadeDriveCommand() constructor should look like this:

p̶r̶i̶v̶a̶t̶e̶ ̶A̶l̶a̶b̶D̶r̶i̶v̶e̶B̶a̶s̶e̶ ̶m̶_̶d̶r̶i̶v̶e̶b̶a̶s̶e̶;
p̶r̶i̶v̶a̶t̶e̶ ̶d̶o̶u̶b̶l̶e̶ ̶l̶e̶f̶t̶O̶u̶t̶p̶u̶t̶,̶ ̶r̶i̶g̶h̶t̶O̶u̶t̶p̶u̶t̶;

A̶r̶c̶a̶d̶e̶D̶r̶i̶v̶e̶C̶o̶m̶m̶a̶n̶d̶(̶A̶l̶a̶b̶D̶r̶i̶v̶e̶B̶a̶s̶e̶ ̶d̶r̶i̶v̶e̶b̶a̶s̶e̶,̶ ̶D̶o̶u̶b̶l̶e̶S̶u̶p̶p̶l̶i̶e̶r̶ ̶l̶e̶f̶t̶V̶a̶l̶u̶e̶,̶ ̶D̶o̶u̶b̶l̶e̶S̶u̶p̶p̶l̶i̶e̶r̶ ̶r̶i̶g̶h̶t̶V̶a̶l̶u̶e̶) {
    l̶e̶f̶t̶O̶u̶t̶p̶u̶t̶ ̶=̶ ̶l̶e̶f̶t̶V̶a̶l̶u̶e̶.̶g̶e̶t̶A̶s̶D̶o̶u̶b̶l̶e̶(̶)̶;
    r̶i̶g̶h̶t̶O̶u̶t̶p̶u̶t̶ ̶=̶ ̶l̶e̶f̶t̶V̶a̶l̶u̶e̶.̶g̶e̶t̶A̶s̶D̶o̶u̶b̶l̶e̶(̶)̶;

    m̶_̶d̶r̶i̶v̶e̶b̶a̶s̶e̶ ̶=̶ ̶d̶r̶i̶v̶e̶b̶a̶s̶e̶;
    a̶d̶d̶R̶e̶q̶u̶i̶r̶e̶m̶e̶n̶t̶s̶(̶d̶r̶i̶v̶e̶b̶a̶s̶e̶)̶;
}

EDIT: See gixxy’s post below as to why this won’t work and for a better example.

Also, you set up the default command incorrectly, it should look like this:

alabDriveBase.setDefaultCommand(new ArcadeDriveCommand(alabDriveBase, 
    () -> m_joystick.getX(), 
    () -> m_joystick.getY());

Thank you Jdao, I will try to explain the code that you have provided here as a way to teach myself. So from what I understand, I need to pass in the constructor a variable holding the value of my command (m_drivebase;) , but are the variable ( double leftOutput, rightOutput;) used for?


I don’t understand much of this portion of the code
ArcadeDriveCommand(AlabDriveBase drivebase, DoubleSupplier leftValue, DoubleSupplier rightValue) {
leftOutput = leftValue.getAsDouble();
rightOutput = leftValue.getAsDouble();

What is the DoubleSupplier argument that is passed to the ArcadeDriveCommand

Lastly, once the constructor setup, how do I call the joystick to read the axes and bind it to my ArcadeDriveCommand?

Like I said my knowledge of Java is very limited so, please bear with me.

You just answered the Joystick question, Got it!

So when you pass a function into another function like this () -> m_joystick.getX() or this m_joystick::getX() that is called a lambda expression where you are passing the function call itself and not what the function is outputting. Since you passed a function as an argument, a function can return anything from a double, int, string, class, etc., so Java uses a DoubleSupplier class to help act as an intermediary so you can specify what function outputs the constructor can accept.

Since we generated the leftOutput and rightOutput variables in the AraceDriveCommand class, and assign them the return value of the DoubleSuppliers, we can use the values in the execution portion of the command like this:

@Override
public void execute() {
    m_drivebase.setMotorOutputs(leftOutput, rightOutput)
}

For a full example of how to structure code using the 2020 Command Base, I would recommend looking at this example from the WPILib GitHub.

This is probably incorrect for most commands. As by executing the getAsDouble() in the constructor rather than storing it, you are only going to get a single value, not an updating one, as is the intention. As written, you example is no better than not using lambdas/Suppliers.

What you PROBABLY want to do is store the DoubleSupplier object itself, and then use the .getAsDouble() method in the initialize(), execute(), ect. methods of your command.

Like so:

private AlabDriveBase m_drivebase;
private DoubleSupplier leftOutput, rightOutput;

ArcadeDriveCommand(AlabDriveBase drivebase, DoubleSupplier leftValue, DoubleSupplier rightValue) {
    leftOutput = leftValue;
    rightOutput = leftValue;

    m_drivebase = drivebase;
    addRequirements(drivebase);
}

public void execute() {
  m_drivebase.setMotorOutputs(leftOutput.getAsDouble(), rightOutput.getAsDouble());
}
1 Like

Thanks a lot, it is starting to get more clear. I will definetely look at all of this more carefully tomorrow morning when my brain is not as fuzzy. They told me that we would not get much sleep during build season, and I am finding out why, so much to do, so much to learn! The funny thing is there seem to be someone always ready to help someone out on this forum and I am very happy that you took the time trying to teach me. (do you get any sleep?) Anyways, I will go investigate the Github page that you recommended and in the mean time I wish you goodnight! Thank you on behalf of team 8067 Alpha Lab (Montreal, Québec, Canada)

As for the () -> m_joystick.getX() and DoubleSupplier syntax, what is happening is that you are wrapping your joystick method inside a second ‘anonymous’ function (often called lambda functions in CS), which you can then pass a reference to into your Command object. This allows you to call that joystick method later inside the Command without having to pass the whole Joystick Object, or going outside the Command class (to the RobotContainer) to grab it.

One of my students called it “smuggling methods” between objects, and I kinda liked that comparison as well.

Got it, I’ll remember this smuggling method!

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