Gyro Sensor Problem

I’m not sure if this is a common problem, but our gyro seems to be constantly drifting. I read the “Gyro Sensor Drift” thread but in their case they only encountered drifting of about 50 units, but our sensor is just constantly drifting in one direction. I left it on for about 2 minutes sitting still and it drifted all the way to upwards of 3000. I have not even added much code either. I have the gyro plugged into analog port 7 and just have this:

SensorScale(gyro) = 400;
SensorFullCount[gyro] = 3600;

and in the debugger window the sensor readings just constantly change. Another peculiar thing is that when the sensor is unplugged, the debugger window still has the values drifting upward, but at a slower pace. Any thoughts?

Yes. I’ve experienced this, and found a solution…

The drift is slower than the robot can possibly turn. Therefore, you can run a task in the background to keep track of turns that are really slow. This could be considered the error, and subtracted from the gyro reading…

//Andrew

What we did to help with this was clear the sensor every time we ran the robot. It can add to the time it takes for your robot to start up, but it has greatly helped with ours, and kept it from being too crazy:

//Completely clear out any previous sensor readings by setting the port to "sensorNone"
SensorType[in8] = sensorNone;
wait1Msec(1000);
//Reconfigure Analog Port 8 as a Gyro sensor and allow time for ROBOTC to calibrate it
SensorType[in8] = sensorGyro;
wait1Msec(2000);

We found this idea in the ROBOTC Blog: http://www.robotc.net/blog/2011/10/13/programming-the-vex-gyro-in-robotc/

~Jordan

Yes, I have cleared the sensor every time we run it. Honestly, the sensor is drifting far too fast to counteract it with any programming. It drifts like 100 per 10 seconds. Is this normal?

Hmmm… It’s close to how fast mine would drift, but that is faster. Here’s a sample of code I used to fix the problem:

#pragma config(UART_Usage, UART2, VEX_2x16_LCD, baudRate1200, IOPins, None, None)
#pragma config(Sensor, in7,    gyro,                sensorGyro)
#pragma config(Motor,  port4,           rightDrive,    tmotorNormal, openLoop, reversed)
#pragma config(Motor,  port7,           leftDrive,     tmotorNormal, openLoop)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

//Globals
int gyroValue;

task gyroMonitor(){
  int lastGyro = SensorValue[gyro];
  int gyroError = 0;
  while(true){
    //If the gyro is reporting a *very* slow turn, ignore it.
    if (abs(lastGyro - SensorValue[gyro]) < 5) //Increase the 5 if the sensor drifts faster...
      gyroError += lastGyro - SensorValue[gyro];

    lastGyro = SensorValue[gyro];

    gyroValue = SensorValue[gyro] + gyroError;
    wait1Msec(100);
  }
}

task main(){
  /////////////////Gyro calibration///////////////
	SensorType[gyro] = sensorNone;
	wait1Msec(500);
	//Reconfigure Analog Port 8 as a Gyro sensor and allow time for ROBOTC to calibrate it
	SensorType[gyro] = sensorGyro;
	wait1Msec(2000);

	StartTask(gyroMonitor);

	//Specify the number of degrees for the robot to turn (1 degree = 10, or 900 = 90 degrees)
	int degrees10 = 900;
	int targetPower = 0;

	while(true){
	  targetPower = 0.20 * (degrees10 - gyroValue);
	  motor[rightDrive] = (targetPower < 95) ? targetPower : 95;
	  motor[leftDrive] = (targetPower < 95) ? -targetPower : -95;
	  wait1Msec(10);
	}
}

1 deg per second is not normal. Drift occurs due to noise on the A-D input, how long are the wires to the gyro? Do the wires pass any noise generating components? ie. motors. You could try calculating your own bias in this way.

    int     realBias;
    long    cumBias;
    int     i;

    // Cause the gyro to reinitialize (a theory anyway)
    SensorType[GyroInput] = sensorNone;

    // Wait 1/2 sec
    wait10Msec(50);

    // improved bias setting
    cumBias=0;
    for(i=0;i<2000;i++)
        {
        cumBias = cumBias + SensorValue[GyroInput];
        wait1Msec(1);
        }
    realBias = cumBias / 2000;
    
    // Gyro should be motionless here
    SensorType[GyroInput] = sensorGyro;
    
    // Now put the bias back to the correct value we found in the initialization
    SensorBias[GyroInput] = realBias;

and then compare with the bias RobotC is calculating, in my case there is not much difference.

Why are you using a SensorScale of 400? default is 130 and should work correctly.

I will definitely try your code for removing error, but the wire is passing through where all other wires go. It is also sort of near motors.

I doubt the code will help that much, I would try the gyro on a short 6" cable mounted near to the cortex.

Anyone know what deadband is used on the accumulator?

For a 12-bit ADC, I would put in something like 3-4 counts, maybe a few more if I was having issues.

If there is no deadband, I would not consider 1deg/sec drift unreasonable.

Remember that heading can also be calculated from a pair of drive encoders, and you can combine the driftless encoder heading with the higher resolution gyro heading to get a much better heading.

No, in RobotC it’s hidden. I don’t know what the sampling frequency is either.

I see about 0.1 deg per second just sitting on my desk.

That is what I normally had before I added the clearing code. Now many times it will stay at 0, or between 1 and -1. Just before I added the sensor clearing code to our program, the Gyro was scrolling through values very quickly. It got to 3600 in a couple seconds or so. That was when I knew I needed to clear the sensor every time. :stuck_out_tongue: I haven’t had any problems at all with it since.

~Jordan

when you say clear every time you just mean every time you run the code?

Yes, however we do “clear” it every time we do a new drive “routine”. (Simply set it back to 0, and count from there, not completely re-calibrating the sensor.)

~Jordan