Lesson 4: Getting Joystick Input
Making a motor spin is great, but we need to be able to link the
speed of the motor with a joystick on a controller. For this, we can use the
Joystick
class.
First, let's declare our Joystick:
and instantiate it in the robotInit()
method:
The Joystick
constructor takes one parameter: the port the
gamepad is mapped to in the Driver Station software. Normally we start counting
at 0, so I have assigned my gamepad to port 0.
Getting the actual input from the joystick can be a little tricky. This is
due to the Joystick
class not giving human names to all of the
axes and buttons. Each axis and button on the controller has a special ID. Here
are two tables of all the IDs for a Logitech F310 Gamepad, which is the most
widely used controller:
Axis | ID |
---|---|
Left Stick X | 0 |
Left Stick Y | 1 |
Right Stick X | 4 |
Right Stick Y | 5 |
Left Trigger | 2 |
Right Trigger | 3 |
Button | ID |
---|---|
Button A | 1 |
Button B | 2 |
Button X | 3 |
Button Y | 4 |
Left Bumper | 5 |
Right Bumper | 6 |
Back | 7 |
Start | 8 |
Left Stick | 9 |
Right Stick | 10 |
Whew! You may have noticed that the D-pad is missing. We will get to that later. Lets put these IDs into practice. Check out the following code:
See if you can figure out what is happening here. The value of
isPressed
will be true
if the A button is pressed,
and false
if it is not pressed. The value of
axisValue
depends on where the Y axis on the left stick is being
pushed. Axis values run from -1 to 1, just like motor controllers do. When the
Axis is in the center, getRawAxis()
will return 0. This way, we can
feed joystick input directly into the set()
method of a motor
controller. Let's revisit the motor controller code we made in the last
lesson:
Without looking at the next code block, see if you can update this code to use the left and right sticks to control the motors. This is called tank drive.
So, remember how I said you can feed joystick input directly into a motor controller? Here is what it would look like to control the left motor with the Y axis on the left stick:
Can you complete the tank drive code now? Here is my completed tank drive code:
Remember: you may need to add negatives for motors that are mounted backwards.
I said I would save the D-pad for later... well it's later. The WPI Java
Library considers the D-pad to be a "POV." The Logitech F310 only has one POV,
so the ID of the D-pad is 0. If we had a controller with more POVs, their IDs
would be 1, then 2, and so on. In order to get input from the D-pad, we use the
getPOV()
method.
What? How do I use that? Well, getPOV()
returns the angle of the
POV in degrees, or -1 if the POV is not pressed. This can be challenging if we
are trying to use the D-pad as a simple button. We can interpret this angle to
see what button on the D-pad is pressed. Here are some examples:
0° is located at the top of the D-pad, and the angles rotate clockwise like this:
Exercises
- When the A button is pressed, spin a motor. Stop the motor when the button is released.
- Create a tank drive. Then, add a gearing system: when the A button is pressed, the motors should only be able to run at 50% capacity. When the A button is released, the motors should run at 100% capacity. To make this exercise more challenging, add more gears. Hint: multiply the speed
You may be thinking to yourself: this Joystick
class is dumb!
How am I going to remember all of those IDs? And why does the D-pad have to be
so weird? Well, I think the exact same thing. That's why I recommend using Code
Red's Robot Library. If you are using the Robot Library, go ahead and read the
next section. Otherwise, go on to the next lesson.
Using Code Red's Robot Library
Our Robot Library has a very expansive package for getting gamepad
input. We are not going to worry about the finer details of this package in
this lesson, but I do want to cover the basics as using our library is arguably
easier than using the Joystick
class.
Our library has a HID
class which manages all the controller
input. Here is how you can create a HID
object.
Just as in the Joystick
class, the constructor takes an integer
representing the port that the gamepad is mapped to in the Driver Station
software.
In order to hide the arbitrary numbers of the Joystick
class, we
made several classes that assign human names to these numbers. We have classes
for a few different kinds of controllers, including:
- Logitech F310
- Logitech Rumblepad 2
- Saitech Joystick
Here is how you use the LogitechF310
class to get axis/button
input:
In the last code snippet, isPressed
is true
if the
A button is pressed and false
if it is not pressed. Also,
axisValue
depends on where the Y axis on the left stick is
currently at. This also works for the D-pad:
You should know what that does. For your reference, here is a list of all the button/axis names in our library:
Axes:
- STICK_LEFT_X
- STICK_LEFT_Y
- TRIGGER_LEFT_AXIS
- TRIGGER_RIGHT_AXIS
- STICK_RIGHT_X
- STICK_RIGHT_Y
- DPAD_X
- DPAD_Y
Buttons:
- A
- B
- X
- Y
- BUMPER_LEFT
- BUMPER_RIGHT
- BACK
- START
- STICK_LEFT
- STICK_RIGHT
Alright, that is enough for now. As I have already mentioned, this is not a
comprehensive list of features of our HID
class, and we will cover
this more later.