Help setting up two joystick tank drive in Command Based

Why do you say that? I almost always have some default command, like a “hold current position” for PID subsystems, or even just a “stop all motors” command. I find it’s easier to reason about what a subsystem is doing if I know there’s always exactly one command running. (modulo command group issues)

As for my two cents, I will shamelessly plug HYPERLib. That makes it easy to make a “drive command” right in the subsystem like this:

/** 
 * Method which returns a command that drives using the joysticks.
 */
public Command userDriveCmd() {
    return QuickCommand.continuous(() -> {
        drive.tankDrive(Robot.m_oi.flightStick1.getY(),
                        Robot.m_oi.flightStick2.getY());
    });
}

Then set it as default with setDefaultCommand(userDriveCmd()). The continuous method takes a function to run during execute, and makes a command which runs indefinitely.

If you don’t like the tight coupling you get from referencing the joysticks in the drive subsystem, you can make a “generic drive command” which takes DoubleSupplier’s for the left and right parameters. Then you can pass different parameters to turn it into a “drive with joysticks” command, or a “drive at a constant rate command”, or even a “track vision targets” command. This is closer in spirit to what Kenny suggested, but imo is cleaner:

public Command driveCmd(DoubleSupplier left, DoubleSupplier right) {
    return QuickCommand.continuous(() -> {
        drive.tankDrive(left.getAsDouble(), right.getAsDouble());
    });
}

Then to get a “drive with joysticks” command, you pass in Robot.m_oi.flightStick1::getY and Robot.m_oi.flightStick2::getY.