Tank Drive Controls

Hello, I have a code for a tank drive but I am not sure on how exactly I can write a code to control it. My team is using an Xbox controller in which moving both joysticks at once moves the bot forward or backward, and moving them in opposite directions makes it turn. Any help is appreciated.

What type of motors and motor controllers are you using, and how are they connected to the roborio (PWM or CAN)? Have you read any of the docs and docs.wpilib.org? Which language do you want to use?

The general answer for Java is that you should create a XboxController object and a DifferentialDrive object and call the tankDrive method of the DifferentialDrive object with the output from the y-axis of each joystick of the controller as arguments. This should go inside teleopPeriodic, assuming you’re not using command based programming.

If you have code already, you should upload it to GitHub and link it.

1 Like

We are using Spark Motors as it is just an example bot; the new members have been assigned with coding it. We are using Java and the motors are connected to the roborio via CAN wires.

public class tankdrive extends SubsystemBase {
private static final int deviceNumber = 0;
/** Creates a new tankdrive. */

Spark left1;
Spark left2;

Spark right1;
Spark right2;

Joystick joy;

public tankdrive() {
left1 = new Spark(deviceNumber);
left2 = new Spark(deviceNumber);

right1 = new Spark(deviceNumber);
right2 = new Spark(deviceNumber);


public void drive(double leftValve, double rightValve){

left1.set(ControlMode.PercentOutput, leftValve);
left2.set(ControlMode.PercentOutput, leftValve);

right1.set(ControlMode.PercentOutput, -rightValve);
right2.set(ControlMode.PercentOutput, -rightValve);
//defining motor speed


public void teleopPeriodic() {

This is what I have so far. I’m getting an error under left1.set(joy.getRawAxis()); and I’m not really sure where to go from here but I will definitely look into your tips, thank you for the reply.

So I read up on the WPILib documents for DifferentialDrive and I came up with this:

public tankdrive() {
left1 = new Spark(deviceNumber);
left2 = new Spark(deviceNumber);

right1 = new Spark(deviceNumber);
right2 = new Spark(deviceNumber);

MotorControllerGroup left = new MotorControllerGroup(left1, left2);
MotorControllerGroup right = new MotorControllerGroup(right1, right2);

DifferentialDrive drive = new DifferentialDrive(left, right);

public void teleopPeriodic() {
myDrive.tankDrive(-leftStick.getY(), -rightStick.getY());

However I still have some errors popping up in the code

Couple quick issues pop out to me that I would recommend you take a closer look at. I can fix it, but since this is a project for new members I figure pointing in the correct direction would be more help.

  1. Look at using an XboxController instead of a Joystick in code. It will look something like XboxController controller = new XboxController(number from DriverStation Controller Input);
  2. instead of joy.getRawAxis(), using the XboxController, you can use controller.getLeftY() see this example here for a PWM SparkMax example code: allwpilib/Robot.java at main · wpilibsuite/allwpilib · GitHub - note that this exact code will not work for you, as you are using different motor controllers.
  3. I don’t see where during the robotInit that the motor controllers are created. I strongly recommend initializing all motor controllers during robotInit
  4. Looks like you are creating a drive method, would it not make sense to use that in teleopPeriodic instead of directly setting a motor?
    5.I don’t remember Sparks being able to use CAN, are you using a Spark or SparkMax? They are different.

Another issue that may arise after it stops having code errors is the motors spinning in the same direction. You will likely have to invert some motors. For the short term, I recommend only running 1 motor on each side, or else you risk breaking the gearbox/motor

Spark is not a type of motor, it is a motor controller. “Spark” could refer to two models of motor controller: the original sparks or the SparkMAX. Could you clarify which one you are using? I will assume the SparkMAX because that’s the only one with CAN control.

In order to control the SparkMAX over CAN, you have to download RevLib and use the class CANSparkMAX. The WPILib classes are for PWM control. You can find instructions to install RevLib at REVLib Information - SPARK MAX and there are code examples here: SPARK MAX Code Examples - SPARK MAX.

Another problem with your code is that every motor in the code has the same ID. You have to set the CAN id of each motor the hardware client and use that id to refer to that motor so that the roborio knows which controller is which.

The type of motor connected to the SparkMAX is also relevant to this question.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.