No amount of beautiful code can save a robot that's been built poorly. Read this first.
You can write the cleanest PID controller around. You can build perfect odometry. None of it matters if your robot's frame bends on every turn, your wires pop out in the middle of a match, or your wheels are mounted crooked. The robot is a physical machine first, and your code can only work as well as the machine underneath it.
Five things to get right before you ever touch the autonomous code.
The frame your robot is built on is called the chassis. In VEX IQ it's made of plastic beams and plates snapped together with connector pins. If it bends or twists a little while the robot drives, the wheels shift out of place. Even a tiny shift can make the robot turn the wrong amount during an autonomous run.
Later, on bigger robots like VEX V5 or FRC, the frame is metal and held together with screws and bolts. Then "tighten every screw" becomes the version of this check.
If a wheel is mounted even slightly crooked, the robot drifts to one side instead of driving straight. Your code then has to fight that drift the whole match. Look straight down at each wheel from above. If it is not lined up with the rest of the robot, fix it.
The most common reason a good autonomous fails at a competition is a cable that wiggled loose. Keep wires away from spinning parts, hold them down with rubber bands or zip ties, and leave a little slack so a small tug doesn't pull the plug out.
A robot that is heavy up top tips and wobbles when it turns quickly. When the robot wobbles, it keeps drifting after the motors stop, so it never lands where your code expects. Put the heavy parts (like the battery) down low and spread out, not stacked up high.
When two gears touch, their teeth need to fit together with the right amount of space. Squeezed too tightly, they grind and the motor struggles. Spaced too far apart, the teeth slip past each other and the robot loses track of how far it has moved. Spin them by hand: they should turn smoothly without grinding and without skipping.
A PID controller corrects for predictable error. It cannot correct for a chassis that flexes randomly, or a wheel that grips less on one side, or a connector that disconnects mid-match. Those are physics problems, not code problems.
Teams with great builders write shorter autonomous routines because the robot does what they expect on the first try. Teams with poor builds write enormous routines full of correction logic to compensate. Guess which one wins more matches.
An autonomous routine is only useful if it works 4 out of 5 times. A great routine that works once is luck. A boring routine that works every time is a strategy. Build quality is what makes routines repeatable.
A useful rule: if the robot fails the same way every time, it's probably code. If the robot fails differently each time, it's probably build (loose wire, slipping gear, flexing chassis). Diagnose this before you go down a debugging rabbit hole.