ollien
02-02-2016, 18:27
This year, my team is trying to get our robot to drive straight using a PID controller and a NavX rather than having our driver correct for it manually. However, whenever I do this, the robot seems to shake left and right. I've tried raising/lowering the P value to get the robot to oscillate around the 0 degree mark, but once it gets to the point, it starts to shake rather violently. Changing the D value seems to make next to no difference, and if anything the robot seemed to shake more violently.
From some googling, it seems that the cause is a P value that is too high, but I can't seem to find a P value where the robot doesn't either shake, brown out, or not have enough power to move. I've posted the relevant pieces of my code below. Can someone help me out? Thanks so much.
public class Robot extends IterativeRobot implements PIDOutput {
double turnCompensation = 0;
final double kP = 0.01;
final double kI = 0.00;
final double kD = 0.00;
final double kF = 0.00;
CANTalon frontLeft = new CANTalon(2);
CANTalon backLeft = new CANTalon(3);
CANTalon frontRight = new CANTalon(4);
CANTalon backRight = new CANTalon(5);
Joystick joystick = new Joystick(0);
Compressor compressor = new Compressor();
int toggleDirection = -1;
RobotDrive robotDrive = new RobotDrive(frontLeft, backLeft, frontRight, backRight);
AHRS gyro = new AHRS(SPI.Port.kMXP);
PIDController straightController = new PIDController(kP, kI, kD, kF, gyro, this);
private double getLeftStick(){
return joystick.getRawAxis(1);
}
private double getRightStick(){
return joystick.getRawAxis(5);
}
private double getCorrectedRightStick(){
double correctedValue = getRightStick() * 2;
return correctedValue < 1 ? correctedValue : 1;
}
private double getCorrectedLeftStick(){
double correctedValue = getLeftStick() * 2;
return correctedValue < 1 ? correctedValue : 1;
}
//...
public void robotInit(){
compressor.start();
straightController.setInputRange(0, 360);
straightController.setOutputRange(-1.0, 1.0);
straightController.setAbsoluteTolerance(3);
straightController.setContinuous(true);
straightController.enable();
SmartDashboard.putData("DrivePID", straightController);
robotDrive.setSafetyEnabled(true);
}
@Override
public void autonomousInit(){
//...
}
//Called periodically during auto
//Use quick operations, must be done in less than 20ms.
@Override
public void autonomousPeriodic(){
//...
}
@Override
public void teleopInit(){
gyro.reset();
straightController.setSetpoint(0);
frontLeft.enableBrakeMode(false);
frontRight.enableBrakeMode(false);
backLeft.enableBrakeMode(false);
backRight.enableBrakeMode(false);
}
@Override
public void teleopPeriodic(){
SmartDashboard.putNumber("gyroValue", gyro.getAngle());
if (joystick.getRawButton(8)){
toggleDirection = 1;
}
else {
toggleDirection = -1;
}
robotDrive.arcadeDrive(getCorrectedLeftStick() * toggleDirection, turnCompensation);
}
@Override
public void disabledInit(){
straightController.disable();
}
@Override
public void pidWrite(double output) {
turnCompensation = output;
}
}
From some googling, it seems that the cause is a P value that is too high, but I can't seem to find a P value where the robot doesn't either shake, brown out, or not have enough power to move. I've posted the relevant pieces of my code below. Can someone help me out? Thanks so much.
public class Robot extends IterativeRobot implements PIDOutput {
double turnCompensation = 0;
final double kP = 0.01;
final double kI = 0.00;
final double kD = 0.00;
final double kF = 0.00;
CANTalon frontLeft = new CANTalon(2);
CANTalon backLeft = new CANTalon(3);
CANTalon frontRight = new CANTalon(4);
CANTalon backRight = new CANTalon(5);
Joystick joystick = new Joystick(0);
Compressor compressor = new Compressor();
int toggleDirection = -1;
RobotDrive robotDrive = new RobotDrive(frontLeft, backLeft, frontRight, backRight);
AHRS gyro = new AHRS(SPI.Port.kMXP);
PIDController straightController = new PIDController(kP, kI, kD, kF, gyro, this);
private double getLeftStick(){
return joystick.getRawAxis(1);
}
private double getRightStick(){
return joystick.getRawAxis(5);
}
private double getCorrectedRightStick(){
double correctedValue = getRightStick() * 2;
return correctedValue < 1 ? correctedValue : 1;
}
private double getCorrectedLeftStick(){
double correctedValue = getLeftStick() * 2;
return correctedValue < 1 ? correctedValue : 1;
}
//...
public void robotInit(){
compressor.start();
straightController.setInputRange(0, 360);
straightController.setOutputRange(-1.0, 1.0);
straightController.setAbsoluteTolerance(3);
straightController.setContinuous(true);
straightController.enable();
SmartDashboard.putData("DrivePID", straightController);
robotDrive.setSafetyEnabled(true);
}
@Override
public void autonomousInit(){
//...
}
//Called periodically during auto
//Use quick operations, must be done in less than 20ms.
@Override
public void autonomousPeriodic(){
//...
}
@Override
public void teleopInit(){
gyro.reset();
straightController.setSetpoint(0);
frontLeft.enableBrakeMode(false);
frontRight.enableBrakeMode(false);
backLeft.enableBrakeMode(false);
backRight.enableBrakeMode(false);
}
@Override
public void teleopPeriodic(){
SmartDashboard.putNumber("gyroValue", gyro.getAngle());
if (joystick.getRawButton(8)){
toggleDirection = 1;
}
else {
toggleDirection = -1;
}
robotDrive.arcadeDrive(getCorrectedLeftStick() * toggleDirection, turnCompensation);
}
@Override
public void disabledInit(){
straightController.disable();
}
@Override
public void pidWrite(double output) {
turnCompensation = output;
}
}