The-Charge / PlyBot2017

Other
0 stars 0 forks source link

Try a PIDCommand to control TurnNDegressAbsolute #39

Closed abcurrie closed 6 years ago

abcurrie commented 7 years ago

There is a new command this year call PIDCommand that uses a PIDController to run a subsystem. This might be a better way to control the the turning of the robot. The measurement and setpoint should probably be in yaw units, -180 to 180, and the output should be in MSC unit, -1 to 1. Things to look at are "continuous" setting and "limits".

abcurrie commented 7 years ago

code to look at:

package org.usfirst.frc.team2465.robot;

import com.kauailabs.navx.frc.AHRS;

import edu.wpi.first.wpilibj.SampleRobot; import edu.wpi.first.wpilibj.RobotDrive; import edu.wpi.first.wpilibj.SPI; import edu.wpi.first.wpilibj.DriverStation; import edu.wpi.first.wpilibj.Joystick; import edu.wpi.first.wpilibj.PIDController; import edu.wpi.first.wpilibj.PIDOutput; import edu.wpi.first.wpilibj.Timer; import edu.wpi.first.wpilibj.livewindow.LiveWindow;

/**

public class Robot extends SampleRobot implements PIDOutput { RobotDrive myRobot; // class that handles basic drive operations Joystick leftStick; // set to ID 1 in DriverStation Joystick rightStick; // set to ID 2 in DriverStation AHRS ahrs;

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;    

static final double kTargetAngleDegrees = 90.0f;

public Robot() {
    myRobot = new RobotDrive(0, 1);
    myRobot.setExpiration(0.1);
    leftStick = new Joystick(0);
    rightStick = new Joystick(1);
    try {
        /***********************************************************************
         * navX-MXP:
         * - Communication via RoboRIO MXP (SPI, I2C, TTL UART) and USB.            
         * - See http://navx-mxp.kauailabs.com/guidance/selecting-an-interface.
         * 
         * navX-Micro:
         * - Communication via I2C (RoboRIO MXP or Onboard) and USB.
         * - See http://navx-micro.kauailabs.com/guidance/selecting-an-interface.
         * 
         * Multiple navX-model devices on a single robot are supported.
         ************************************************************************/
        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);
    turnController.disable();

    /* 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);        
}

/**
 * Runs the motors with tank steering.
 */
public void operatorControl() {
    myRobot.setSafetyEnabled(true);
    while (isOperatorControl() && isEnabled()) {
        if ( leftStick.getRawButton(0)) {
            /* While this button is held down, rotate to target angle.  
             * Since a Tank drive system cannot move forward simultaneously 
             * while rotating, all joystick input is ignored until this
             * button is released.
             */
            if (!turnController.isEnabled()) {
                turnController.setSetpoint(kTargetAngleDegrees);
                rotateToAngleRate = 0; // This value will be updated in the pidWrite() method.
                turnController.enable();
            }
            double leftStickValue = rotateToAngleRate;
            double rightStickValue = rotateToAngleRate;
            myRobot.tankDrive(leftStickValue,  rightStickValue);
        } else if ( leftStick.getRawButton(1)) {
            /* "Zero" the yaw (whatever direction the sensor is 
             * pointing now will become the new "Zero" degrees.
             */
            ahrs.zeroYaw();
        } else if ( leftStick.getRawButton(2)) {
            /* While this button is held down, the robot is in
             * "drive straight" mode.  Whatever direction the robot
             * was heading when "drive straight" mode was entered
             * will be maintained.  The average speed of both 
             * joysticks is the magnitude of motion.
             */
            if(!turnController.isEnabled()) {
                // Acquire current yaw angle, using this as the target angle.
                turnController.setSetpoint(ahrs.getYaw());
                rotateToAngleRate = 0; // This value will be updated in the pidWrite() method.
                turnController.enable();
            }
            double magnitude = (leftStick.getY() + rightStick.getY()) / 2;
            double leftStickValue = magnitude + rotateToAngleRate;
            double rightStickValue = magnitude - rotateToAngleRate;
            myRobot.tankDrive(leftStickValue,  rightStickValue);
        } else {
            /* If the turn controller had been enabled, disable it now.
            if(turnController.isEnabled()) {
                turnController.disable();
            }
            /* Standard tank drive, no driver assistance. */
            myRobot.tankDrive(leftStick, rightStick);
        }
        Timer.delay(0.005);     // wait for a motor update time
    }
}

@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;
}

}