I’m having an issue with my PID control where no matter how high I set the P value the Robot does not turn far enough to the set angle. Currently I have the angle set at 90 degrees and what is happening is that the robot turns and then oscillates at around 20-40 degrees, all at the max speeds that I set in the output range (-0.52 to 0.52). Any idea what could be the issue? The gyro sensor that I’m using is the ADXRS450 gyro sensor.
package org.usfirst.frc.team3205.robot.commands;
import org.usfirst.frc.team3205.robot.Robot;
import org.usfirst.frc.team3205.robot.RobotMap;
import edu.wpi.first.wpilibj.ADXRS450_Gyro;
import edu.wpi.first.wpilibj.PIDController;
import edu.wpi.first.wpilibj.PIDOutput;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
/**
*
*/
public class autoAlign extends Command implements PIDOutput{
private PIDController controller;
private double endTime;
private double angle;
private double speed;
private double pidOut;
private long onTargetMillis;
private long startTimeMillis;
public autoAlign() {
// Use requires() here to declare subsystem dependencies
// eg. requires(chassis);
requires(Robot.driveTrain);
angle = 90;
}
// Called just before this Command runs the first time
protected void initialize() {
double kP = RobotMap.kP;
double kI = RobotMap.kI;
double kD = RobotMap.kD;
controller = new PIDController(kP, kI, kD, Robot.driveTrain.gyroSensor, this);
controller.setInputRange(20.0, 150.0);
controller.setOutputRange(-RobotMap.SPEED, RobotMap.SPEED);
controller.setAbsoluteTolerance(RobotMap.TOLERANCE);
controller.setContinuous();
controller.setSetpoint(angle);
controller.enable();
startTimeMillis = System.currentTimeMillis();
}
// Called repeatedly when this Command is scheduled to run
protected void execute() {
Robot.driveTrain.driveCertainAmounts(pidOut, -pidOut);
SmartDashboard.putBoolean("onTarget:", controller.onTarget());
SmartDashboard.putNumber("angle:", Robot.driveTrain.getAngle());
SmartDashboard.putData("pid:", controller);
}
// Make this return true when this Command no longer needs to run execute()
protected boolean isFinished() {
// if(!controller.onTarget()){
// onTargetMillis = 0;
// return false;
// }
// if(onTargetMillis == 0){
// onTargetMillis = System.currentTimeMillis();
// }
// return System.currentTimeMillis() > onTargetMillis + 100;
return controller.onTarget();
}
// Called once after isFinished returns true
protected void end() {
controller.disable();
Robot.driveTrain.stop();
}
// Called when another command which requires one or more of the same
// subsystems is scheduled to run
protected void interrupted() {
}
public void pidWrite(double output){
synchronized(this){
pidOut = output;
SmartDashboard.putNumber("pidOut:", pidOut);
}
}
}