Ayaan Goswami
Let's talk
All projects

Robotics / 2023 to now

VEX Robotics: 285C Discobots Chaos

Lead programmer for a Houston team that qualified for the 2026 VEX Robotics World Championship.

Push Back code V5 template

Crystal Peak, Hollow Knight

Role
Programming lead, build team, drive team
Team
285C Discobots Chaos, Carnegie Vanguard High School
Status
Qualified for the 2026 World Championship; now on the Override season
Stack
C++, PROS, LemLib, LVGL

The team

285C, Discobots Chaos, is a VEX V5 team from Carnegie Vanguard High School in Houston. I've done VEX for three seasons. In the 2025-26 Push Back season I led programming and was also on the build and drive teams.

We qualified for the 2026 VEX Robotics World Championship through a skills rolldown after the Texas Region 3 Championship. It was the first time a CVHS team had qualified in over five years, and all three 285 sister teams qualified together.

The season

EventDateRankFurthest round
Katy Holiday ClassicNov 202534thDid not qualify
Den WarsFeb 20264thSemifinals
New Year New Drive (GORTS)Feb 202622ndSemifinals
Texas Region 3 ChampionshipFeb 20266thQuarterfinals

Our combined skills score went from 100 to 102 to 137 points across the last three events. At States we went 7 and 2 in qualifications and scored 80 autonomous points, the most of any team at the event.

The robot

285C's Push Back robot: a black aluminum frame with red sprockets, a chain-driven conveyor angled up the front, and omni wheels.
The Push Back robot, after the post-States rebuild of the conveyor.

A six-motor, six-wheel tank drive geared 3:4, so 600 RPM motors give 450 RPM at the wheels, with 3.25-inch omni wheels on the outside and traction wheels in the middle for lateral stability. A two-motor intake on a dual chain feeds a conveyor that can score in the long goal or, with a piston pulling the conveyor floor down, the middle goal. Pneumatics run a scraper for match loads and a wing for descoring. After a collision at Den Wars bent the frame and stopped one side from moving, we added cross-bracing; after Regionals we angled the front of the drivetrain so blocks get guided into the intake instead of deflected.

The code

Everything runs on PROS with LemLib for odometry and PID. Position comes from the IMU plus a vertical tracking wheel on a rotation sensor. Both PID loops use only P and D terms, since nothing caused the kind of persistent offset that integral correction is for. Lateral slew is on because the robot's center of gravity is high enough to tip if it accelerates too hard. Driver control uses a steering curve with a small deadband and an exponential gain, so slow movements are fine-grained but full speed is still there. The brain screen runs an LVGL autonomous selector over seven match routines and one skills routine.

Motion chaining

The part I'm proudest of. LemLib can chain one motion into the next without stopping, but each motion needs two hand-tuned values: how early to exit, and what speed to hold on the way out. Tuning those for every motion in every routine was slow and fragile, so I wrote a CustomChassis class that derives both from the distance of each motion.

Fig. 2. Same path, two ways to drive it

Stop and go0.00 s
Chained0.00 s

This simulation needs JavaScript. The idea: instead of stopping at every waypoint, the robot leaves each motion early at half its peak speed and carries that speed into the next one.

A simplified simulation with made-up but realistic acceleration limits, not telemetry from our robot. Turns are modeled as in-place rotations when stopping and as blended arcs when chaining.

Here d is the distance of the motion and k is a fixed fraction, around 15 to 20 percent for drives. Turns work the same way with angular distance and a tighter window, since overshooting a heading throws off everything after it. The full reasoning is in this post.

The template

Every season starts with the same boilerplate: lifecycle callbacks, drivetrain and odometry setup, an autonomous selector. I pulled ours out into a public template with the code split into small single-purpose files, so we can start the next game from a working skeleton instead of rewriting it.