# Gyroscope drive straight

I am trying to create a drive straight program with a gyroscope instead of encoders because we do not have the space for them(i know there are solutions to that but this is also just learning for the gyro) but am running into the problem that this
while(SensorValue[gyro] < degree) earns an error. the solution so far is to change it to a while(abs(SensorValue[gyro]) < degree) and while this works for turns it does not help for driving straight. sample code would be appreciated!

Iâm on my phone so I canât provide any sample code, but what I do is just have my regular driving code add the value of the gyroscope to the left side motors and subtract the value from the right side motors. So, when the drive starts to veer off to the left, the gyroscope value is positive, and the left side motors increase in value and the right side motors decrease, veering it back to where it was before. Same thing applies vice versa. Basically,

motor[leftSide] = (whatever code you have) + SensorValue[gyro] * C;
motor[rightSide] = (whatever code you have) - SensorValue[gyro] * C;

C is a constant that multiplies the value of the gyroscope. That you will have to adjust based on how your drive oscillates, but Iâve tried it anywhere from 0.1 to 1 and itâs done me good.

Are you using the gyroscope to keep your robot straight while driving forward, or are you trying to use the gyroscope to measure the distance you traveled? The latter is impossible (you need encoders to measure the distance you drive forward. @Mystellianne 's answer is sufficient for the first usage, however.

If you have nowhere to put encoders on your drive, consider using a passive tracking wheel with an encoder on it. This can go in the middle of your chassis, on the back of your robot that does not go over the bar of the 10-point zone.

Just curious, what do you do to keep the movement perfectly linear? This was one of the few times Iâve just whipped up my own custom solution instead of researching other ones, and I never bothered to look for other solutions because this has worked to near-perfect success (consistent 84 point skills without using the fence to reposition at all).

I have my turning PID constantly running and adding its values to the drive PID. Then, some arithmetic is done if the resultant value is over 127 to make the larger value of the left and right side 127, with the other the proper amount slower. (So a difference of 30 would remain a difference of 30.) I donât know how you can do that long of a programming skills without recalibrating; we have three gyros, and even the best one drifts too much for that. If anyone has any tips on keeping gyros from drifting, that would be great. I get some weird issues with mine.

While I donât take the time to align myself on the fence, I do align myself on the ten point bar every single time I put down a mobile goal. Whenever you back out of scoring in the 20 pt zone, you can be assured you are at a 45* angle relative to the rest of the field. In addition, every time I place one in the 10 pt zone, I drive forwards slightly (maybe a power of like 20) so that my drive fully aligned itself with the bar, while not going fast enough to actually drive over it. Also, is your drive chained? Mine isnât, but my routine would be a whole lot more accurate if it was.

Also, I only use one gyro. I reset it before every turn and just use what i mentioned above as my assurance for absolute positioning.

Have a look at my gyro filtering code here . You can use it to calibrate each gyro and get more responsive measurements with less drift than the standard ROBOTC (or PROS) filtering. My functions only return the angular rate measured from the gyro, you have to sum it over time yourself like this (assuming gyro is plugged in to analog port 1 on cortex):

``````
#include "NERD_Gyro.c"

Gyro gyro;
gyroInit(gyro, in1, false);
float gyroAngle = 0;

long time = nPgmTime;

while (1) {
float deltaTime = (nPgmTime - time) / 1000.0;

if (deltaTime != 0) {
gyroAngle += gyroGetRate(gyro) * deltaTime;
}

delay(1);
}
}

while (1) {
//use gyro or do other things
}
}

``````

I measured the difference between my code and ROBOTCâs filtering for gyros, and I actually found that ROBOTCâs wonât drift at all if the robot sat still, but would tend to have a less accurate angle measurement after a turn or move, whereas mine would drift something like +/-0.2 degrees over a few minutes but gave great results for turns or other moves.

My Programming Skills run realigns with the bar as well, and my drive is chained together.

One other thing that a lot of teams donât do is run their programming routines at a lower motor power. This increases accuracy by a lot. All of my driving is done at a power of 84, and my turning at 64. Granted this is still pretty fast considering my robot is on a 6 motor turbo drive, but running at a reduced speed made it a loooot more accurate.

Now that Iâm going for 94 instead of 84, I wouldnât even bump up the power, but instead I want to incorporate more swing turns to save a lot of driving distance. My 3 cone autons already do this but it will be a little harder to implement on such a long routine.

This is actually very easy to accomplish.

First, start by establishing a âspeedâ value that you get from whatever youâre using to reach your target. Either use PID, or use bang bang (if current encoder value < target --> motors 127) and set the end speed to the âspeedâ variable.
Then, use a secondary PID Loop for correcting based on the gyro. This is done like so:

``````
SensorValue[gyro] = 0;
int error = 0 - SensorValue[gyro];
float kP = 0.2; // random-ish starter value, tune this. The higher this value is, the greater affect the gyro correction have on your robot, the lower it is the lower the affect.

motor[left] = speed - (error * kP);
motor[right] = speed + (error * kP);

``````
1 Like

@jmmckinney I was talking to one of my mentors the other day about measuring velocity with encoders or angular velocity with the gyro, somewhat similar to your code, and he said the speed of the clock varies with battery voltage, so it doesnât actually return consistent values for time. Do you know anything about this?

@ZProgrammer The short answer is that this is incorrect, the CPU voltage should never vary in a properly functioning cortex.