Skip to content

Basic Drive Systems

Kenzie Togami edited this page Nov 30, 2018 · 1 revision

Basic Drive Systems

This tutorial assumes you've already completed Coding Your First Robot.

Our goal for this tutorial is to improve upon the previous one by adding the ability to drive a joystick. We'll cover Tank Drive first, due to its simplicity, and then move on to the more complicated Arcade Drive.

As always, if at any point you have questions or need help, ask in #sw_general on Slack!

Adding Joysticks

The first thing we will need to drive with joysticks is the joystick objects. In the Robot class, rename the current joystick field to joystick1, and make a copy named joystick2:

    private Joystick joystick1;
    private Joystick joystick2;

Then initialize them in robotInit:

// robotInit() { ...

    joystick1 = new Joystick(0);
    joystick2 = new Joystick(1);

// ... }

Tank Drive

Tank Drive is a very simple drive system. It takes the value from the Y axis on a joystick, and runs the motors at that speed. For example, if you put both the left and right joystick all the way forward, the motors will run at 100% speed.

For simplicity, we'll keep everything inside teleopPeriodic for now. In a real robot, you would write the code for Tank/Arcade Drive in another method since it's easier to read.

Start by deleting everything in teleopPeriodic. We'll be completely rewriting it.

Now, we want to extract the Y axis value from the two joysticks so we can pass it to the DriveTrain, as the specification for Tank Drive states. We can do this by creating two double variables. I'll show you how to create the first, and then you should create a second for joystick2's Y value:

// teleopPeriodic() { ...

        double y1 = joystick1.getY();
        // Write y2 here!

// ... }

Then we can call DriveTrain#setPower with our two double values:

// teleopPeriodic() { ...

    driveTrain.setPower(y1, y2);

// ... }

That's all for Tank Drive!

Arcade Drive

Arcade Drive is a little more complicated than Tank Drive, but not by much. It uses the X axis to determine how far left or right the robot should be turning, and the Y axis to determine how fast it is going forwards or backwards.

We'll write Arcade Drive in another method since it's more complicated. I've added comments to help explain everything going on here.

    // We use "private" since we only need this in Robot
    // setArcade takes two arguments/parameters, "rotate" and "power"
    // "rotate" is how much we want to be turning left or right
    // "power" is how fast we're going forwards or backwards
    private void setArcade(double rotate, double power) {
        // These three variables are calculated so we don't need to repeat
        // them in the following code.
        double max = Math.max(Math.abs(rotate), Math.abs(power));
        double diff = power - rotate;
        double sum = power + rotate;

        // We declare "left" and "right" here so that we can use them
        // outside of the `if` statements. If you don't know why we need it,
        // ask!
        double left;
        double right;
        if (power > 0) {
            // In this case we are going forwards, since power > 0.

            if (rotate > 0) {
                // This means turning right, since rotate > 0
                // If you think about the X axis on a joystick, the right side
                // is where the positive values are.

                // We use max for left, since we want all the power there.
                left = max;
                // And we use the smaller value for right, so we turn right.
                right = diff;
            } else {
                // Since the other case was right, this is left/forwards.

                // We use smaller value for left, since we want to turn left.
                left = sum;
                // And we use the max for right, so all of the power is there.
                right = max;
            }
        } else {
            // In this case, we are going backwards, since power < 0.
            if (rotate > 0) {
                // We want to turn right, but we're going backwards, so
                // the smaller value goes to "left".
                left = sum;
                // Right gets maximum power, but backwards, because power < 0.
                right = -max;
            } else {
                // We want to turn left, but we're going backwards, so
                // the smaller value goes to "right".
                right = diff;
                // Left gets maximum power, but backwards, because power < 0.
                left = -max;
            }
        }
        // Finally, we set the power to the motors.
        driveTrain.setPower(left, right);
    }

This is pretty complicated, so please ask on Slack if this doesn't make sense to you!

After adding that method, all we need to do to implement Arcade Drive is to pass the joystick axis values in teleopPeriodic. Change the first double variable so it gets joystick1's X value, instead of Y. Rename it to x1, so it matches the style of naming we're using. Then, simply write setArcade(x1, y2) to call the setArcade method you wrote above.

Once you've finished that, you will have a working Arcade Drive! Ask one of the mentors to help you with deploying it to the robot and testing it out.

Notes

The full code for this project is available at Tutorial-BasicDriveSystems.

Previous Tutorial | Next Tutorial

Clone this wiki locally