Gyro Issues

We are a rookie team that is trying to setup our drive system to drive straight by utilizing a gyro. We are having an issue with our gyro (ADXRS450) that came in the KoP. When we call getAngle() while our robot is stationary the angle constantly increases. We have tried gyro.reset() when the robot is initialized and the accumulators do reset to zero. However, they start to climb instantly (without touching the robot). Is this something that is supposed to happen or could we have something incorrectly set?

Below is our code:

package org.usfirst.frc.team6484.robot;

import edu.wpi.first.wpilibj.ADXRS450_Gyro;
import edu.wpi.first.wpilibj.AnalogGyro;
import edu.wpi.first.wpilibj.IterativeRobot;
import edu.wpi.first.wpilibj.Joystick;
import edu.wpi.first.wpilibj.RobotDrive;
import edu.wpi.first.wpilibj.Timer;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;

/**
 * This is a sample program to demonstrate how to use a gyro sensor to make a
 * robot drive straight. This program uses a joystick to drive forwards and
 * backwards while the gyro is used for direction keeping.
 */
public class Robot extends IterativeRobot {
	private static final double kAngleSetpoint = 0.0;
	private static final double kP = 0.005; // propotional turning constant

	// gyro calibration constant, may need to be adjusted;
	// gyro value of 360 is set to correspond to one full revolution
	private static final double kVoltsPerDegreePerSecond = 0.0128;

	private static final int kLeftMotorFrontPort = 0;
	private static final int kLeftMotorBackPort = 1;
	private static final int kRightMotorFrontPort = 2;
	private static final int kRightMotorBackPort = 3;
	private static final int kGyroPort = 1;
	private static final int kJoystickPort = 0;

	private RobotDrive myRobot = new RobotDrive(kLeftMotorFrontPort, kLeftMotorBackPort, kRightMotorFrontPort, kRightMotorBackPort);
	private ADXRS450_Gyro gyro = new ADXRS450_Gyro();
	private Joystick joystick = new Joystick(kJoystickPort);

	@Override
	public void robotInit() {
		gyro.reset();
//		gyro.calibrate();

	}
	
	/**
	 * The motor speed is set from the joystick while the RobotDrive turning
	 * value is assigned from the error between the setpoint and the gyro angle.
	 */
	@Override
	public void teleopInit(){
	}

	@Override
	public void teleopPeriodic() {
		double turningValue = (kAngleSetpoint - gyro.getAngle()) * kP;
		double compensation = Math.copySign(turningValue, joystick.getY());
		myRobot.arcadeDrive(joystick.getY(), compensation);
	}
}

At what rate does it increase? Some drift is expected.

*Here are some possibly useful links I found with a quick search:

Does turning the robot have any effect the on the angle from the gyro?
Is the drift rate high? It won’t be zero, but it should be well below 1 degree per minute. We haven’t used this particular gyro before, but could there be an issue with the SPI port?

You can re-calibrating, not just resetting. Be sure to not move the robot during the re-calibration period. That’s a sure way to get high drift.

I suggest that you measure the output voltage of the gyro. We had several of the previous generation of gyro give “at rest” voltages that were nowhere near the expected value of 2.5V. (As I recall, it was much closer to 5.0V). If the output is not exactly 2.5V, but reasonably close, you should be able to make adjustments in software.

It wouldn’t be useful to measure the output voltage of an SPI gyro.

It looks like our drift issue was caused by calling reset() inside TeleopInit(). We initially got about 2 degrees of drift in one minute. Once we removed the reset() we only saw a small drift.

We then tested our gyro by manually turning the bot 90, 180, 270, 360, etc. and we received the correct values. However, now we feel our calculations are not correct since we are still turning instead of driving straight.

If you look at our code above. We have only changed it by commenting out the reset() within the TeleopInit. We are only checking our Y value of our controller and setting our target direction to zero degrees. Any incite would be much appreciated.

Try the following code changes:

To robotInit():


	@Override
	public void robotInit() {
		gyro.reset();
//		gyro.calibrate();

                // Allow kP to be changed on the fly in the smart dashboard
               SmartDashboard.putNumber("kP", kP);
	}

To teleopPeriodic():


	public void teleopPeriodic() {
                double err = (kAngleSetpoint - gyro.getAngle());
		double turningValue = err * SmartDashboard.getNumber("kP", kP);
		double compensation = Math.copySign(turningValue, joystick.getY());

                SmartDashboard.putNumber("compensation", compensation);
                SmartDashboard.putNumber("err", err);
		myRobot.arcadeDrive(joystick.getY(), compensation);
	}

The above changes should allow you to adjust your “kP” value on the fly, show you how much error is being detected and show the corresponding compensation. If you go to edit mode on your smart dashboard you can change the err and compensation output to line plots to see it over time as you drive.

Sometimes just seeing the values being produced can lead to some insight.

Hope that helps,
Paul

Using Paul’s suggestion, we monitored the kP value. We then did some tweaking and came up with a value of 0.007.

We now have a straight-driving robot!

Thank you all for your help!
Shawn