Need Help with Gyroscope

My team’s robot uses a gyroscope with our mecanum drive to create a field-centric robot (see quote below) and we are having a problem with the gyro accumulating a very big error. So, I programmed a reset button for the gyro, but our driver still had to hit the reset button every ten seconds, making it very difficult to drive. Does anyone have any tips or advice? Thanks in advance.

Please post your code. That may make it easier to help you.

will this link help?

https://vexforum.com/t/gyro-sensor-drift/20155/1

Try this code too. They try and filter out the drift.
https://vexforum.com/t/qcc2-gyro-and-pid-control-code/29292/1

I actually stopped updating that repo and am working on a new version here: https://bitbucket.org/VRCNERD/nerd_robotc

Anyone that was using my old code and had issues might be a lot happier with the stuff in this repo. Give it a shot and let me know how everything works!

Thank you all for the help. Here is my code with all of the non-relevant stuff taken out.


#pragma config(I2C_Usage, I2C1, i2cSensors)
#pragma config(Sensor, in1,    gyroscope,      sensorGyro)
#pragma config(Sensor, I2C_1,  MotorLF,        sensorQuadEncoderOnI2CPort,    , AutoAssign )
#pragma config(Sensor, I2C_2,  MotorLB,        sensorQuadEncoderOnI2CPort,    , AutoAssign )
#pragma config(Sensor, I2C_3,  MotorRB,        sensorQuadEncoderOnI2CPort,    , AutoAssign )
#pragma config(Sensor, I2C_4,  MotorRF,        sensorQuadEncoderOnI2CPort,    , AutoAssign )
#pragma config(Motor,  port2,           MotorLF,       tmotorVex393HighSpeed_MC29, openLoop, encoderPort, I2C_1)
#pragma config(Motor,  port3,           MotorLB,       tmotorVex393HighSpeed_MC29, openLoop, encoderPort, I2C_4)
#pragma config(Motor,  port8,           MotorRB,       tmotorVex393HighSpeed_MC29, openLoop, reversed, encoderPort, I2C_3)
#pragma config(Motor,  port9,           MotorRF,       tmotorVex393HighSpeed_MC29, openLoop, reversed, encoderPort, I2C_2)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

#pragma platform(VEX)

//Competition Control and Duration Settings
#pragma competitionControl(Competition)
#pragma autonomousDuration(15)
#pragma userControlDuration(105)

#include "Vex_Competition_Includes.c"   //Main competition background code...do not modify!
void pre_auton()
{
	// Set bStopTasksBetweenModes to false if you want to keep user created tasks running between
	// Autonomous and Tele-Op modes. You will need to manage all user created tasks if set to false.
	bStopTasksBetweenModes = true;

	// All activities that occur before the competition starts
	// Example: clearing encoders, setting servo positions, ...
}
task autonomous()
{
	// .....................................................................................
	// Insert user code here.
	// .....................................................................................

	AutonomousCodePlaceholderForTesting();  // Remove this function call once you have "real" code.
}
float
GyroGetAngle()
{
	return( SensorValue gyroscope ] / 10.0 );
}

//control the mecanum drive
//forward The forward power/speed (-127 to 127)
//turn The turning power/speed (-127 to 127)
//right The strafing power/speed (-127 to 127)
void
DriveSystemMecanumDrive( int forward, int turn, int right )
{
	long drive_l_front;
	long drive_l_back;
	long drive_r_front;
	long drive_r_back;

	// Set drive
	drive_l_front = forward + turn + right;
	drive_l_back  = forward + turn - right;

	drive_r_front = forward - turn - right;
	drive_r_back  = forward - turn + right;

	// normalize drive so max is 127 if any drive is over 127
	int max = abs(drive_l_front);
	if (abs(drive_l_back)  > max)
		max = abs(drive_l_back);
	if (abs(drive_r_back)  > max)
		max = abs(drive_r_back);
	if (abs(drive_r_front) > max)
		max = abs(drive_r_front);
	if (max>127) {
		drive_l_front = 127 * drive_l_front / max;
		drive_l_back  = 127 * drive_l_back  / max;
		drive_r_back  = 127 * drive_r_back  / max;
		drive_r_front = 127 * drive_r_front / max;
	}

	// Send to motors
	// left drive
	motor MotorLF ] = drive_l_front;
	motor MotorLB ] = drive_l_back;

	// right drive
	motor MotorRF ] = drive_r_front;
	motor MotorRB ] = drive_r_back;
}

//Driver control of mecanum drive system
void
DriveSystemMecanum()
{
	int forward, right, turn;
	int temp;
	float theta;

	// Get joystick values
	// deadband near center of joysticks
	forward = vexRT Ch3 ];
	if( abs( forward ) < 10 )
		forward = 0;

	right = vexRT Ch4 ];
	if( abs( right ) < 10 )
		right = 0;

	turn = vexRT Ch1 ];
	if( abs( turn ) < 10 )
		turn = 0;

	// Field centric control
	// Get gyro angle in radians
	theta = degreesToRadians( GyroGetAngle() );

	// rotate coordinate system
	temp  = forward * cos(theta) - right * sin(theta);
	right = forward * sin(theta) + right * cos(theta);
	forward = temp;

	// Send to drive
	DriveSystemMecanumDrive( forward, turn, right );
}
//----------------------------------------------------------------------------------------------------
task usercontrol()
{
	bLCDBacklight = true;// Turn on LCD Backlight
	string mainBattery, backupBattery;
	//Loop Forever
	while(1 == 1)
	{
		//+++++++++++++++++++++++++++++++++++++++++| Mecanum Drive |++++++++++++++++++++++++++++++++++++++++++
		// Init the gyro
		SensorValue gyroscope ] = sensorNone;
		wait1Msec(100);
		SensorValue gyroscope ] = sensorGyro;
		wait1Msec(1000);

		while(1)
		{
			DriveSystemMecanum();

			if(vexRT[Btn8R] == 1)//If button 8R is pressed
			{
				SensorValue gyroscope ] = 0;//reset gyroscope
			}

			wait1Msec(25);
		}
	}
}

I would recommend putting the Gyro initialization in the pre_auton section of code so it happens as soon as you turn on the Cortex. Otherwise you will not hit it until they switch you over to driver control mode. You want those 1.1 seconds to drive in that limited time frame.

Also look at the @jmmckinney code. Play with those NERD_Gyro files and see if it helps filter out the problems. He waits for 2 seconds in his initialization.

When moving the code to pre_auton, I also like a wait for a little bit before doing the gyro initialization as you tend to bump the robot a little when turning it on. Unless @Foster is running the match, the match will not start within a few seconds of you turning the robot on. You can always delay giving the thumbs up to the referee for a few seconds as well :slight_smile:

Thank you very much!