Xboxcontroller joystick tankdrive

Trying to create a tankdrive in the Container. Having troubles getting left stick to control left side and right stick controlling right. Here’s the code for the container:

// Copyright © FIRST and other WPILib contributors.

// Open Source Software; you can modify and/or share it under the terms of

// the WPILib BSD license file in the root directory of this project.

package frc.robot;

import edu.wpi.first.wpilibj.GenericHID;

import edu.wpi.first.wpilibj.Joystick;

import edu.wpi.first.wpilibj.XboxController;

import edu.wpi.first.wpilibj.GenericHID.Hand;

import frc.robot.subsystems.*;

import edu.wpi.first.wpilibj2.command.Command;

import edu.wpi.first.wpilibj2.command.RunCommand;

import static frc.robot.Constants.*;

/**

  • This class is where the bulk of the robot should be declared. Since Command-based is a

  • “declarative” paradigm, very little robot logic should actually be handled in the {@link Robot}

  • periodic methods (other than the scheduler calls). Instead, the structure of the robot (including

  • subsystems, commands, and button mappings) should be declared here.

*/

public class RobotContainer {

XboxController xbox = new XboxController(kXboxPort);

//XboxController leftStickYController = leftJoystick(kLeft);

//XboxController rightStickYController = rightJoystick(kRight);

Joystick leftJoystick = new Joystick(kLeft);

Joystick rightJoystick = new Joystick(kRight);

// The robot’s subsystems and commands are defined here…

private final Drive drive = new Drive();

/** The container for the robot. Contains subsystems, OI devices, and commands. */

public RobotContainer() {

// Configure the button bindings

configureButtonBindings();

drive.setDefaultCommand(

  new RunCommand(

  () -> drive.tankDrive(xbox.getY(kLeft)),

  () -> drive.tankDrive(xbox.getY(kRight)),         

  ) 

  )

;

}

/**

  • Use this method to define your button->command mappings. Buttons can be

  • created by instantiating a {@link GenericHID} or one of its subclasses

  • ({@link edu.wpi.first.wpilibj.Joystick} or {@link XboxController}), and then

  • passing it to a {@link edu.wpi.first.wpilibj2.command.button.JoystickButton}.

*/

private void configureButtonBindings() {}

/**

  • Use this to pass the autonomous command to the main {@link Robot} class.

  • @return the command to run in autonomous

*/

public Command getAutonomousCommand() {

return null;

}

}

Are you driving with an XBox controller or two joysticks? You have both created in your code; the RunCommand is using the XBox controller (e.g. xbox.getY()), not the two joysticks (e.g. leftJoystick.getY() and rightJoystick.getY()).

The call to tankDrive doesn’t look correct, typically it would take two arguments, e.g. drive.tankDrive(leftJoystick.getY(), rightJoystick.getY()), but you’re only passing one. Does this code compile? I’m wondering what your Drive.tankDrive() function looks like.

1 Like

Driving with an XBox controller. It is throwing an error. Here’s my Drive code:

package frc.robot.subsystems;

import edu.wpi.first.wpilibj2.command.SubsystemBase;

import frc.robot.Constants;

import edu.wpi.first.wpilibj.SpeedControllerGroup;

import edu.wpi.first.wpilibj.XboxController;

import edu.wpi.first.wpilibj.drive.DifferentialDrive;

import com.ctre.phoenix.motorcontrol.can.WPI_TalonSRX;

import com.ctre.phoenix.motorcontrol.can.TalonSRX;

import com.ctre.phoenix.motorcontrol.ControlMode;

import static frc.robot.Constants.*;

/**

*/

public class Drive extends SubsystemBase {

WPI_TalonSRX leftTalon1, leftTalon2, rightTalon1, rightTalon2;

SpeedControllerGroup leftGroup, rightGroup;

DifferentialDrive drivetrain;

/** Creates a new Drive. */

public Drive() {

leftTalon1  = new WPI_TalonSRX(Constants.Left_Motor_1);

leftTalon2 = new WPI_TalonSRX(Constants.Left_Motor_2);



rightTalon1  = new WPI_TalonSRX(Constants.Right_Motor_1);

rightTalon2 = new WPI_TalonSRX(Constants.Right_Motor_2);



SpeedControllerGroup leftGroup = new SpeedControllerGroup(leftTalon1,leftTalon2);

SpeedControllerGroup rightGroup = new SpeedControllerGroup(rightTalon1,rightTalon2);

drivetrain = new DifferentialDrive(leftGroup, rightGroup);

drivetrain.setRightSideInverted(true);

}

public void tankDrive(double leftGroup, double rightGroup){

drivetrain.tankDrive(leftGroup, rightGroup);

}

//public void curvatureDrive(double power, double turn) {

// drivetrain.curvatureDrive(power, turn, true);

//}

@Override

public void periodic() {

// This method will be called once per scheduler run

}

public Object tankDrive(XboxController xbox) {

return null;

}

}

You’re going to want your command to look something like this then:

drive.setDefaultCommand(
  new RunCommand(
    () -> drive.tankDrive(xbox.getY(kLeft), xbox.getY(kRight))
  ));
1 Like

You don’t need the two additional XboxController construction calls at the top–all you need is the one XboxController variable named “xbox”.

How can I resolve the second getY?

Click on getY then click on the light bulb that appears. You should have an option to fix it there. If not it should be getY(GenericHID.Hand.kRight)

Could you show us the error in this line?
It’s probably an import as jdaming said, but it can also be just a vs code “bug”. So, if it’s not a import problem, you can try reload your vs code.

got it fixed! it was in my constants

1 Like

Got an error when I deployed the code, but the build was successful.

  • Robots should not quit, but yours did!

  • at edu.wpi.first.wpilibj2.command.Subsystem.setDefaultCommand(Subsystem.java:49)

  • at frc.robot.RobotContainer.(RobotContainer.java:41)

  • at frc.robot.Robot.robotInit(Robot.java:30)

  • The startCompetition() method (or methods called by it) should have handled the exception above.

from: edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:352)

  • at edu.wpi.first.wpilibj.TimedRobot.startCompetition(TimedRobot.java:94)

  • at edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:335)

  • at edu.wpi.first.wpilibj.RobotBase.startRobot(RobotBase.java:407)

  • at frc.robot.Main.main(Main.java:23)

  • Warning at edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:350): Robots should not quit, but yours did!

  • Error at edu.wpi.first.wpilibj.RobotBase.runRobot(RobotBase.java:352): The startCompetition() method (or methods called by it) should have handled the exception above.

Usually when I receive this error, is because I’m trying to use the same port to another device. Could you check that?

public static final int Left_Motor_1 = 0;

public static final int Left_Motor_2  = 1;

public static final int Right_Motor_1 = 2;

public static final int Right_Motor_2  = 3;

public static final int kXboxPort = 0;

public static final int kLeft = 1;

public static final int kRight = 5;

So, was a little confused with the axis coding on driver station

Are you using this constants here? I don’t think that’s the problem to your error, but that seems like a problem as well
() -> drive.tankDrive(xbox.getY(kLeft), xbox.getY(kRight))

Well, on driverstation, left y axis is on 1 and right y axis is on 5 for the controller

I see, but if you see the getY() method needs a Hand enum… using like that, you could try to use the method getRawAxis(kRight) or getY(GenericHID.Hand.kRight) like jdaming said.

Are you using 2 joysticks to control the robot or just a xbox controller?

The two sticks on the xbox controller. I’m a noob at all of this.

Ok, so I’ll try to explain to you more or less how it works

But since you’re using just one XboxController, this means you just need to use one in the code as well. If you were using two joysticks or two XboxControllers to control the robot, you need to use more.

XboxController xbox = new XboxController(your_port_on_drivestation);

(FRC Driver Station Powered by NI LabVIEW — FIRST Robotics Competition documentation) Here is how you can see the port your Xbox is connected.

Than, with the xbox object, you can access it methods. So, since you want to use both axis Y right and left, you need to use the method getY(Hand.kLeft) and getY(Hand.kLeft).
Just another example, the xbox object that you created has a lot of methods, so let’s say that at some point you would like to use the button A, there is a method to get the value of it, the getAButton method.

Okay, cool. For Hand as an Enum, I would need to fix that in Container, right?