Programming an Arcade Drive

How would you go about programming a class as a custom arcade drive for your robot?

What type of formulas would you need to use?

http://www.chiefdelphi.com/media/papers/2661

Is the puedo-code on the referenced page written in python and if so do you know what the java equivalent might be

What does the pronoun “that” refer to in the above sentence

Sorry,

I was referring to the puedo-code found on the page that was previously referenced

There are 8 documents. Which document are you referring to.

To tell you the truth i cant make sense of any of the psuedo-code files

Do you want help making sense of them? If so, tell me what doesn’t make sense to you, and I will try to explain.

In your original post, you said you wanted the “formulas” so you could program a “custom arcade drive”.

If, however, all you want is canned Java code that already works, you can find it in the WPILibrary.

Basic arcade drive in Java:

(Everything in red can be renamed.)


throttle = joystick.getY();
turnValue = joystick.getX();

leftMtr = throttle + turnValue;
rightMtr = throttle - turnValue;

public double getArcadeLeftMotor() {
        return leftMtr;
    }

public double getArcadeRightMotor() {
        return rightMtr;            
    }

plug in getArcadeLeftMotor() and getArcadeLeftMotor() as the left and right channels in a JoystickDrive object

And that’s all you need for a very basic arcade drive. You need to experimentally determine what values the joystick outputs at each position using print statements or a software such as Xpadder and adjust what it’s doing accordingly. This setup is determinant on the Y axis “up” being a positive value and the X axis “left” being a negative value.

But the basic code is a bit lacking. At high speeds the robot is going to tend to keep going more and it won’t turn so well. It also results in situations where you get bad clipping because of the addition and subtaction. So we make the algorithm a bit more complex…


throttle = joystick.getY();
turnValue = joystick.getX();

leftMtr = throttle + turnValue;
rightMtr = throttle - turnValue;

public double getArcadeLeftMotor() {
        return leftMtr + skim(rightMtr);
    }

    public double getArcadeRightMotor() {
        return rightMtr + skim(leftMtr);            
    }

public double skim(double v) {
    if (v > 1.0) {
        return -((v - 1.0) * RobotMap.TURNING_GAIN);
    } else if (v < -1.0) {
        return -((v + 1.0) * RobotMap.TURNING_GAIN);
    } return 0; 
    }

What this does is take the excess off if it results in a number greater than 1.0 or less than -1.0 and subtract it from the other side of the robot, after applying a multiplier of less than one to reduce it. You can then experiment with the multiplier to find something that feels better than the original code. A multiplier of 0 is equivalent to the original code.

You can use whatever algorithm you want to smooth it out. skim() is just an example, and some teams have found better algorithms entirely. Play around with it until you find something that works well. Good luck.

1 Like

Could you please further explain the function and purpose of the skim method. Im relatively new to learning how to program an arcade drive

The joystick value is a decimal from 0 to 1, and the robot drive method cuts everything off at one. That means you lose some sensitivity to turning at higher speeds because .75 throttle + .45 turn is going to result in 1.2, which gets cut back down to 1.0.

Skim takes whatever was left on the end (in this case .2), multiplies it by another value, (say .5), and then subtracts it from the other side of the drivetrain.

So instead of .75 throttle and .45 turn giving you full throttle on one side and .3 on the other, it gives you full throttle on one side and .2 on the other. So it’s more accurate to the driver’s input.

The trick is finding an algorithm that has a comfortable response curve.

Ok thanks that makes sense now

*Here’s a contour map of the “skim” method with gain=0.5.

Here’s a contour map of the linear interpolation method with a=0.5 and b=1.0

Notice that the contour maps are identical all around the perimeter, but differ in how they get there. The linear one tries to provide linear response to the joystick in both X and Y directions. How that plays out in actual use is an open question. I’d like to hear back from teams who have tried the linear interpolation arcade.

*