package org.usfirst.frc.team2465.robot; import com.kauailabs.navx.frc.AHRS; import edu.wpi.first.wpilibj.DriverStation; import edu.wpi.first.wpilibj.PIDController; import edu.wpi.first.wpilibj.PIDOutput; import edu.wpi.first.wpilibj.SPI; import edu.wpi.first.wpilibj.SampleRobot; import edu.wpi.first.wpilibj.RobotDrive; import edu.wpi.first.wpilibj.Joystick; import edu.wpi.first.wpilibj.Timer; import edu.wpi.first.wpilibj.livewindow.LiveWindow; /** * This is a demo program showing the use of the navX MXP to implement * a "rotate to angle" feature. * * This example will automatically rotate the robot to one of four * angles (0, 90, 180 and 270 degrees). * * This rotation can occur when the robot is still, but can also occur * when the robot is driving. When using field-oriented control, this * will cause the robot to drive in a straight line, in whathever direction * is selected. * * This example also includes a feature allowing the driver to "reset" * the "yaw" angle. When the reset occurs, the new gyro angle will be * 0 degrees. This can be useful in cases when the gyro drifts, which * doesn't typically happen during a FRC match, but can occur during * long practice sessions. * * Note that the PID Controller coefficients defined below will need to * be tuned for your drive system. */ public class Robot extends SampleRobot implements PIDOutput { AHRS ahrs; RobotDrive myRobot; Joystick stick; PIDController turnController; double rotateToAngleRate; /* The following PID Controller coefficients will need to be tuned */ /* to match the dynamics of your drive system. Note that the */ /* SmartDashboard in Test mode has support for helping you tune */ /* controllers by displaying a form where you can enter new P, I, */ /* and D constants and test the mechanism. */ static final double kP = 0.03; static final double kI = 0.00; static final double kD = 0.00; static final double kF = 0.00; static final double kToleranceDegrees = 2.0f; // Channels for the wheels final static int frontLeftChannel = 2; final static int rearLeftChannel = 3; final static int frontRightChannel = 1; final static int rearRightChannel = 0; public Robot() { myRobot = new RobotDrive(frontLeftChannel, rearLeftChannel, frontRightChannel, rearRightChannel); myRobot.setExpiration(0.1); stick = new Joystick(0); try { /* Communicate w/navX MXP via the MXP SPI Bus. */ /* Alternatively: I2C.Port.kMXP, SerialPort.Port.kMXP or SerialPort.Port.kUSB */ /* See http://navx-mxp.kauailabs.com/guidance/selecting-an-interface/ for details. */ ahrs = new AHRS(SPI.Port.kMXP); } catch (RuntimeException ex ) { DriverStation.reportError("Error instantiating navX MXP: " + ex.getMessage(), true); } turnController = new PIDController(kP, kI, kD, kF, ahrs, this); turnController.setInputRange(-180.0f, 180.0f); turnController.setOutputRange(-1.0, 1.0); turnController.setAbsoluteTolerance(kToleranceDegrees); turnController.setContinuous(true); /* Add the PID Controller to the Test-mode dashboard, allowing manual */ /* tuning of the Turn Controller's P, I and D coefficients. */ /* Typically, only the P value needs to be modified. */ LiveWindow.addActuator("DriveSystem", "RotateController", turnController); } /** * Drive left & right motors for 2 seconds then stop */ public void autonomous() { myRobot.setSafetyEnabled(false); myRobot.drive(0.0, 0.0); // stop robot Timer.delay(2.0); // for 2 seconds myRobot.drive(0.0, 0.0); // stop robot } /** * Runs the motors with onnidirectional drive steering. * * Implements Field-centric drive control. * * Also implements "rotate to angle", where the angle * being rotated to is defined by one of four buttons. * * Note that this "rotate to angle" approach can also * be used while driving to implement "straight-line * driving". */ public void operatorControl() { myRobot.setSafetyEnabled(true); while (isOperatorControl() && isEnabled()) { boolean rotateToAngle = false; if ( stick.getRawButton(1)) { ahrs.reset(); } if ( stick.getRawButton(2)) { turnController.setSetpoint(0.0f); rotateToAngle = true; } else if ( stick.getRawButton(3)) { turnController.setSetpoint(90.0f); rotateToAngle = true; } else if ( stick.getRawButton(4)) { turnController.setSetpoint(179.9f); rotateToAngle = true; } else if ( stick.getRawButton(5)) { turnController.setSetpoint(-90.0f); rotateToAngle = true; } double currentRotationRate; if ( rotateToAngle ) { turnController.enable(); currentRotationRate = rotateToAngleRate; } else { turnController.disable(); currentRotationRate = stick.getTwist(); } try { /* Use the joystick X axis for lateral movement, */ /* Y axis for forward movement, and the current */ /* calculated rotation rate (or joystick Z axis), */ /* depending upon whether "rotate to angle" is active. */ myRobot.mecanumDrive_Cartesian(stick.getX(), stick.getY(), currentRotationRate, ahrs.getAngle()); } catch( RuntimeException ex ) { DriverStation.reportError("Error communicating with drive system: " + ex.getMessage(), true); } Timer.delay(0.005); // wait for a motor update time } } /** * Runs during test mode */ public void test() { } @Override /* This function is invoked periodically by the PID Controller, */ /* based upon navX MXP yaw angle input and PID Coefficients. */ public void pidWrite(double output) { rotateToAngleRate = output; } }