How to use gyroscope to drive straight?

I’ve seen mentions of people saying they could use gyroscopes to help them drive straight, I’d like to ask how.

I’m thinking about it and have no idea where to start. I assume a PID loop, but how do you mesh that in with the going forward PID?

Could we have more details?
Are you in IQ or EDR?
What language do you currently program in.

Odometry is a essentially a sensor that tells you global coordinate
Bezier curve is a 2d parametric function
In what ways are they related to autocorrection, or even interrelated in the first place?

1 Like

Caution Tape has a video on this, it is for IQ, but it should be almost the same.


In odometery, you should use a version of spline, bezier, or some other interpolation to blend your waypoints or set desired curves.

EDR using V5.

C++ in vexcode v5 pro, but I could switch to PROS if it’s that much better

A gyroscope tells you what angle your robot is facing at any given time. By measuring the angle that the robot starts at, and then reading the angle multiple times while it is driving forward, you can detect if the robot is changing angles. If so, you can calculate how far off it is and apply a correction to the robot’s speed. For example, if you determine that the robot is turning towards the right, you can apply a correction by increasing the speed of the right side or slowing down the left side.

I recommend trying to come up with an implementation of this and experimenting with it for a while. This is a great learning experience.

Two things to note:

  1. If your robot is consistently not driving straight, check your build. You don’t want to compensate for a faulty build with software. If this is just meant to add some extra precision, then this is a good idea.
  2. Even though this will help keep your robot mostly straight, it is still a correction algorithm, meaning the robot will have turned a little bit already before the algorithm can detect that and correct it. This will inevitably lead to error. This can be solved with odometry (position tracking) as many others have mentioned, but it’s up to you to decide if this ends up being a major obstacle for your team.

I don’t think anyone adequately answered your question. The answer is that you can combine the 2 PID loops through addition

leftControl = forwardPID + pointingPID
rightControl = forwardPID - pointingPID

Each of the PID loops are computed normally, 1 with distance to target and another trying to keep the gyro reading fixed.


Heres a hint: atan2 is your friend if you decide to add in an accelerometer to do a complementary filter

: )

1 Like

actually if all you want is to move straight, then there is no need for odometry.
Just a simple PID using the gyro reading (which will show you the angle or direction you are facing) will do.

Edit: oops… just noticed @tabor473 has answered you.


This video covers how to do so, except you replace the encoder difference (right encoder - left encoder) with the gyroscope reading for turning.

I would like to emphasize that PID is more beneficial for a system that cannot drift substantially (like an arm or lift). Basically, it would be better to use motion profiling whenever coding the drivetrain because it helps reduce whiplash, which can offset the robot. I wish I can provide you with more insight about motion profiling but at the moment it is still vague to me how to code it

1 Like

Motion profiling itself is easy to understand for straight line movement. It’s a relatively simple constraint problem. One inputs the robots desired distance and it’s maximum velocity and acceleration for the movement. Under constant acceleration, distance traveled is easy to compute, as is distance at constant velocity. So this either gives a triangle - e.g the robot never reaches maximum velocity- or a trapezoid when one looks at velocity over time. Distance travelled is simply the area of the triangle/trapezoid. Some motion profilers will account for “jerk” ( change in acceleration over time) to round out the transition from acceleration to constant speed or deceleration. Area under this curve requires either calculus or numerical approximations, but the principle is the same.

Where motion profiling gets intimidating is non-linear movement. This is where “splines” and “Bézier curves” enter the lexicon. These are basically ways to draw a curved line, meeting turning radius constraints, thru a series of waypoints, comes to play. These are solved problems with open source implementations, that are likely good enough or better than what ones first attempt would be


There are other factors that will/might give rise to the drift, including precision of the sensors used.

And even when used in lifting system, if the arm moves up and down long enough or continuously enough times, there will still be “drift”.

But in the VRC context, I am assuming OP is trying to use gyro during the auton and to make the robot going straight towards a fixed direction.

That means the distance moved shouldn’t be long enough for the drift to be significant. So once again, PID will be good enough for this purpose.

But you are not wrong to say that motion profiling will improve the accuracy of motion.

But end of the day, whether it is odometry or speed profiling, it is superior to just a standard PID simply because more sensors are used, and more sources of data are being input to the system.
Another way to look at it is that triangulation of data will always be better than just solely relying on one encoder or gyro.

1 Like

Thank you for answering :slight_smile:

Could I use the same PID for turns by changing the pointing PID target to some other degrees?


Excellent question, in theory yes. In practice I end up wanting my point straight PID gains to be slightly different than normal turn in place PID. I usually start them the same but tweak them both separately as needed.

Potentially helpful to make point, (API unimportant as this is code from 5 years ago)

angle PID when driving straight

pos_PID_InitController(&anglePID, &angleChange, 0.5, 0.25, 0); //P, I ,D

angle PID when turning in place

pos_PID_InitController(&anglePID, &angleChange, 0.61, 0.12, 0.07); //P, I ,D gains

Just grabbed examples from

In this example we wanted a stronger integral term when driving straight, so that the system could “learn” or “adapt” more dramatically if a side was consistently driving a little slower. Also it seems we didn’t want any D damping on the angle correction loop for some reason.


When I set the turning goal to something else, would the forward PID interfere?

Like if I say I want to turn 90 degrees using the gyro, then the wheels will start moving, but the forward PID will see that as an error and try to correct the wheels back to 0

How would I fix that problem? (Is it even a problem?)

1 Like

Its not really a problem.

  1. Don’t use the PID controller unless you want it. Call a drive straight function that uses both PID controllers when you want to drive straight, call a turn function that only uses one when you want to turn.
  2. The traditional way to make the forward PID error with encoders is goal - (leftEncoder - rightEncoder)/2. The average of both sides. This also nicely means rotating in place does not effect it, because the average is unchanged when they spin away from eachother.
1 Like