Why "drive for 1 second" is the wrong way, and what to do instead.
From the VEX Library: every VEX IQ Smart Motor has a quadrature encoder inside that reports the direction, position, and speed of the motor shaft. This is the same data the built-in spinFor and driveFor commands use behind the scenes.
double turns = LeftMotor.position(turns); // 1.5 = one and a half full rotations
double deg = LeftMotor.position(degrees); // 540 for 1.5 turns
double rpm = LeftMotor.velocity(rpm); // current speed
If your code says "drive forward for 2 seconds at 50%", how far does the robot actually go?
So your autonomous routine works perfectly in practice and then fails at the competition because the battery is at 70% instead of 100%. That's why we use encoders.
The robot needs to know how many motor degrees correspond to one inch. Formula:
// Wheel circumference = pi * diameter
// For a 200 mm (about 7.87 in) wheel: circumference ≈ 24.75 inches per full motor turn
// degrees per inch = 360 / circumference_in_inches
const double WHEEL_DIAMETER_IN = 7.87;
const double WHEEL_CIRC_IN = 3.14159 * WHEEL_DIAMETER_IN;
const double DEG_PER_INCH = 360.0 / WHEEL_CIRC_IN;
void driveInches(double inches, int speedPct) {
double targetDeg = inches * DEG_PER_INCH;
LeftMotor.spinFor(forward, targetDeg, deg, false);
RightMotor.spinFor(forward, targetDeg, deg, true);
}
int main() {
driveInches(24, 50); // drive 24 inches at 50% speed
}
Dead reckoning = estimating your current position using only how far you've moved, with no outside reference. Sailors used it before GPS. VEX teams use it for simple autonomous routines: drive 24 inches, turn 90, drive 12 inches. It accumulates error every turn, by the end of a long routine, the robot can be way off.
Find the diameter of your wheels (look it up by part number, common IQ wheels are 200 mm and 100 mm). Write a driveInches() function and test it. Measure the actual distance with a tape measure across 5 runs. How much variation is there?
Write a function that drives the robot forward exactly 36 inches, measured by encoder, with no overshoot, even with a low battery.
Two programs with intentional errors. Spot the bug.
const double WHEEL_DIAM_IN = 7.87;
const double WHEEL_CIRC_IN = 3.14159 * WHEEL_DIAM_IN;
const double DEG_PER_INCH = WHEEL_CIRC_IN / 360.0;
void driveInches(double inches) {
double targetDeg = inches * DEG_PER_INCH;
LeftMotor.spinFor(forward, targetDeg, deg, false);
RightMotor.spinFor(forward, targetDeg, deg, true);
}
int main() {
driveInches(24);
}
driveInches twice in a row. The first call works. The second call doesn't move the robot at all. What's missing?void driveInches(double inches) {
double targetDeg = inches * DEG_PER_INCH;
while (LeftMotor.position(degrees) < targetDeg) {
LeftMotor.spin(forward, 50, percent);
RightMotor.spin(forward, 50, percent);
wait(20, msec);
}
LeftMotor.stop();
RightMotor.stop();
}
int main() {
driveInches(12);
driveInches(12);
}