Accessing Joystick Axes in Command-Based Robot

Hello all,

This is my first time programming in the command-based template, and I’ve made it pretty far until I’ve hit a dead wall - I can’t send joystick control to the motors. As the motors are controlled in the subsystem class, and the joysticks are instantiated in the OI class, how can they communicate to each other? I’m just trying to do a basic “if button is pressed, send stick1 y-axis to motor output” with a drive command, drivetrain class, and joystick variable.

Any help is appreciated, thank you very much!

If you make they Joystick public, then you should be able to access the joystick and it;s methods by calling OI.[JoystickName].[MethodName]

That way in the subsystem, you can access the joysticks.

so to do that, does your command have to have a require line for oi?
like this? :


Requires(Robot::driveTrain);
Requires(Robot::oi);

EDIT: nevermind, I got it. You have to call it from Robot, and it acts as a pointer. Thanks!

There are pretty comprehensive guides for the command based projects on screen steps live.

Particularly: http://wpilib.screenstepslive.com/s/4485/m/13810/l/241904-running-commands-on-joystick-input

My problem with those is they only have a format for very basic things, like press this button and have this happen. For ex., one of the reasons we didn’t do command based last year was we wanted an override if something went wrong, to be connected to two buttons(you had to press both to be able to override), and I had no idea how to do that in command based, while in iterative and simple it was a breeze.

Those tutorials also don’t have anything about axes, and I hate using WPILib provided drive code.

OK, I think you’re almost there… One more tiny leap.

Try:
Creating a command.
Inside the execute function, get the value from the axis on the joystick.
Link the command you made to a button in the OI class.

If you want to require two buttons be pressed, just have one button kick off the command, then inside the command, check the state of the second button before you affect your outputs (motors/solenoids).

Our team usually creates “driveWithJoystick” commands for all our subsystems. We set these commands as the default commands for the subsystems, so they aren’t executed on the press of a button, they are always running. Then we make commands that are more automated/complex. Those get linked to buttons. If the automatic commands aren’t working, the option to control things manually is still available.

Command base is different, but I think once you get used to it, you’ll like it.

If that’s not clear enough, let me know and I’ll try to provide some sudo code.

EDIT:: I typed this out not realizing this was in the C++ forum, not Java, but it should be basically the same process, just with C++ syntax, etc. Sorry for the confusion!

Here’s how we do it:

in your OI class, create a couple public methods for accessing axes (I’m assuming you have created a Joystick object, named controller here):


public double getLeftStick() {
    return controller.getRawAxis(1); //look up what the actual axis number is
}

and another one for the right axis.

In your subsystem class, you should have methods for controlling each motor given a value. These methods will be called by commands, so you don’t need to get the axis value here. These methods simply describe the kinds of things the subsystem is able to do. For example:


public void driveLeftMotor(double speed) {
    motor1.set(speed);
}

And probably another almost identical method for driveRightMotor

Now, in the current version of the command-based robot template, the instance of OI, and the instances of each subsystem are created in the main Robot.java class. So make sure an instance of your subsystem is created here.

Almost there, now we just need a Command that actually calls these methods with the joystick axis values as parameters. Make a new Command class. Make sure it “requires(Robot.your_subsystem_instance)” (again, make sure Robot creates an instance, and you will need to import Robot.java).

Then edit execute() to:


public void execute() {
    your_subsystem_name.driveLeftMotor(Robot.oi.getLeftStick());
    your_subsystem_name.driveRightMotor(Robot.oi.getRightStick());
}

Now just set the default command in the subsystem class to be this new command and you’re all set!

**NOTE, if your motors are pointing in opposite directions, they will spin in opposite directions when given the same input from the joystick. You might need to change ONE of the subsystem methods to read:


motor1.set(-speed) //just reverse the direction by adding a -

Thank you guys so much, that helped a lot! I finally got it working the way I wanted it to.

Yeah our team normally has it so that the trigger has to be pulled to drive the robot, just for safety’s sake.

and I had no idea that you could just put a ‘-’ in front, I always wrote it as -1.0*speed xD