We’re missing something…we had no trouble doing the drive train, but we’re struggling with just getting a button to respond on an Xbox controller. Does anyone have a sample piece of code that just turns on a motor with a single button push. I would post our code but its so messed up at the moment I think it would do more harm than good.
Here is an example of a wpilib Command that interacts with our DriveTrain class:
package frc.robot.commands.drivetrain;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import frc.robot.Robot;
public class TurnWithoutPID extends Command {
private double goalAngle = 0.0;
private boolean isDone = false;
private double speed;
private double tolerance = 3;
private double currentAngle;
public TurnWithoutPID(double speed, double givenAngle) {
// Use requires() here to declare subsystem dependencies
// eg. requires(chassis);
requires(Robot.drivetrain);
goalAngle = givenAngle;
this.speed = speed;
isDone = false;
}
// Called just before this Command runs the first time
protected void initialize() {
Robot.drivetrain.resetAHRSGyro();
isDone = false;
//Robot.drivetrain.setAHRSAdjustment(80.0);
}
// Called repeatedly when this Command is scheduled to run
protected void execute() {
currentAngle = Robot.drivetrain.getAHRSGyroAngle();
SmartDashboard.putNumber("Gyro: ", currentAngle);
if(Math.abs(goalAngle - currentAngle) < tolerance) { //if within tolerance
Robot.drivetrain.arcadeDrive(0, 0);
isDone = true;
} else if(currentAngle < goalAngle) { //If left of target angle
Robot.drivetrain.arcadeDrive(0, speed); //turn clockwise
} else if(currentAngle > goalAngle){ //If right of target angle
Robot.drivetrain.arcadeDrive(0, -speed); //turn counterclockwise
}
}
// Make this return true when this Command no longer needs to run execute()
protected boolean isFinished() {
return isDone;
}
// Called once after isFinished returns true
protected void end() {
Robot.drivetrain.setAHRSAdjustment(0.0);
}
// Called when another command which requires one or more of the same
// subsystems is scheduled to run
protected void interrupted() {
Robot.drivetrain.arcadeDrive(0, 0);
isDone = true;
}
}
Here is the code that assigns that command to a button:
public class OI {
/*
* This class describes the controller interface the drive team will use. Here we will keep track of the
* available buttons that exist on each gamepad. When a new gamepad button is assigned a command, it
* needs to be taken off the available button list, and added to the taken list. That way we eliminate
* the duplication of buttons as we move.
*
* Gamepad 0 -- Driver remote
* Inputs Available -- A, B, X, Y, LB, RB, LT, RT
* Inputs Taken -- LY - Transitional Speed arcade drive
* RX - Yaw Speed arcade drive
*
* Gamepad 1 -- Partner remote
* Inputs Available -- A, B, X, Y, LB, RB, LT, RT, L Axis, R Axis
*/
public F310 gamepad;
public F310 gamepad2;
JoystickButton driver_x;
public OI() {
gamepad = new F310(RobotMap.GAMEPAD_PORT);
gamepad2 = new F310(RobotMap.GAMEPAD2_PORT);
driver_x = new JoystickButton(F310.X); // We integers mapped in a different class
driver_x.whenPressed(new TurnWithoutPID(90)); // Turn 90 degrees to the right when we press the button
}
public double getGainOI() {
return F310.getGain();
}
}
And just in case you were wondering about the F310 stuff:
package frc.robot.oi;
import edu.wpi.first.wpilibj.Joystick;
// Custom Gamepad class
public class F310 extends Joystick {
private static final int numAxes = 6;
private static final int numButtons = 10;
// Constants to represent the raw button number with a human readable word
public static final int A = 1;
public static final int B = 2;
public static final int X = 3;
public static final int Y = 4;
public static final int LB = 5; //top button
public static final int RB = 6; //top button
public static final int START = 8;
public static final int BACK = 7;
public static final int L_AXIS = 8;
public static final int R_AXIS = 9;
//Same as above for axis
public static final int LX = 0; //0
public static final int RX = 4; //4
public static final int LY = 1; //1
public static final int RY = 5; //5
public static final int LT = 2; //2
public static final int RT = 3; //3
private double[] scalar = new double[numAxes];
private static double gain = 0.5;
public F310(int port) {
//needed to call super constructor in order for F310 to extend Joystick
super(port);
}
public static double getGain() {
return gain;
}
public static void setGain(double g) {
gain = g;
}
//call enum Buttons
public boolean getButton(int buttons) {
if(buttons < 0 || buttons >= numButtons) return false;
return this.getRawButton(buttons);
}
//calls enum Axis
public double getAxis(int axis) {
if(axis < 0 || axis >= numAxes) return 0.0;
double x = this.getRawAxis(axis);
return gain * Math.pow(x, 3) + (1 - gain) * x;
}
//scales and axis by calling an axis and gives it a value
public void setScalar(int axis, double value) {
if(axis < 0 || axis >= numAxes) return;
scalar[axis] = value;
}
}