Software for our team's competition robot — tank-drive control, a conveyor and descorer mechanism, and autonomous routines, written in both C++ and Python so the same logic could be validated two ways. First-time team, qualified to UK Nationals.
The robot runs a tank-drive base — left and right joystick axes map straight to left and right motor groups — plus a conveyor belt for scoring and two pneumatic mechanisms: a descorer and a match loader, each controlled by a digital output pin. Quick-turn buttons let the driver snap 90° without manually working the stick, which mattered more than I expected once matches got fast.
void user_control() {
Drivetrain.setDriveVelocity(100, percent);
while (true) {
// Tank drive - Axis3 = left stick, Axis2 = right stick
int leftSpeed = Controller.Axis3.position();
int rightSpeed = Controller.Axis2.position();
left_motor_a.setVelocity(leftSpeed, percent);
left_motor_a.spin(reverse);
right_motor_a.setVelocity(rightSpeed, percent);
right_motor_a.spin(reverse);
// Conveyor belt control
if (Controller.ButtonR1.pressing()) {
conveyor.spin(forward); // pick up / place into high tube
} else if (Controller.ButtonR2.pressing()) {
conveyor.spin(reverse); // place into lower tube
} else {
conveyor.stop();
}
// Quick turns
if (Controller.ButtonLeft.pressing()) {
Drivetrain.turnFor(right, 90, degrees);
}
}
}
Simplified from c++/main.cpp — the full version also handles the descorer and match loader pneumatics.
VEXcode V5 supports both languages on the same hardware, and writing the control logic twice turned out to be a genuinely useful exercise rather than busywork — it forced me to separate "what the robot should do" from "how this particular language expresses it." The Python version below does the same job as the C++ above, including its own random-seed initialisation for autonomous routines:
from vex import *
import urandom
brain = Brain()
left_drive_smart = MotorGroup(left_motor_a, left_motor_b)
right_drive_smart = MotorGroup(right_motor_a, right_motor_b)
drivetrain = DriveTrain(left_drive_smart, right_drive_smart, 319.19, 295, 40, MM, 1)
def initializeRandomSeed():
"""make random actually random"""
wait(100, MSEC)
# seed from battery voltage + current + system clock —
# the brain has no true hardware RNG to draw from
random = brain.battery.voltage(MV) + brain.battery.current(CurrentUnits.AMP) * 100 + brain.timer.system_high_res()
urandom.seed(int(random))
initializeRandomSeed()
From python/Controller.py — solving a problem I didn't expect: making "random" mean something on hardware with no dedicated entropy source.
We qualified for UK Nationals on our first attempt as a team — a genuine high point — but Nationals itself didn't go how we wanted. Batteries misbehaved, matches got replayed, and we didn't make Worlds. The takeaways were more valuable than the result:
The complete season logbook…
Open full PDF ↗