I've done VEX Robotics for four years: from struggling to understand PID and having no design experience to coding autonomous programs that won the California State Championship and building robots that competed at the World Championship.
I learned how to use CAD in the 22-23 season, and I haven't stopped designing robots with CAD since. I primarily use OnShape, although I have experience with Fusion 360 and Inventor as well.
My first V5RC robot design, which included some innovative (but not entirely practical) features:
I independently learned and implemented key control theory algorithms over four years, starting with a malfunctioning time-based autonomous program. I stepped into the world of control theory in pursuit of perfecting robotic movement: days tuning PID controllers turned into weeks crafting odometry and MCL.
// Odometry: track robot position from wheel encoders
void updateOdometry() {
double dL = leftTracker.get_value();
double dR = rightTracker.get_value();
double dB = backTracker.get_value();
double dTheta = (dL - dR) / TRACK_WIDTH;
if (fabs(dTheta) < 1e-6) {
// Straight-line motion
globalX += dB * cos(heading);
globalY += dB * sin(heading);
} else {
// Arc motion — integrate curvature
double r = dB / dTheta;
globalX += r * (sin(heading + dTheta)
- sin(heading));
globalY -= r * (cos(heading + dTheta)
- cos(heading));
heading += dTheta;
}
}
// Resample particles weighted by sensor likelihood
void resampleParticles(
vector<Particle>& particles,
double sensorReading
) {
// Weight each particle by Gaussian likelihood
for (auto& p : particles) {
double expected = predictedSensor(p.x, p.y);
p.weight = gaussianLikelihood(
sensorReading, expected, SIGMA
);
}
normalizeWeights(particles);
// Low-variance resampling
particles = lowVarianceSampler(particles);
}
// Gaussian likelihood function
double gaussianLikelihood(
double z, double mu, double sigma
) {
double diff = z - mu;
return exp(-(diff*diff) / (2*sigma*sigma));
}