← All projects

FIRST Tech Challenge

6,090 lines of code I wrote 417 SKID, Swerve RoboticsMay 2023 – May 2025Java, Android

I was on FIRST Tech Challenge team 417 SKID from May 2023 to May 2025, and captain in my second year. I ran every meeting, with an agenda for each member, set the project timelines that got us ready for competition, and oversaw both CAD and programming. I was most hands-on with software, mentoring our programmers and making sure each of them knew exactly what they were working on. I led the robot's early development (decision matrices, prototypes and the first CAD), our outreach, and our preparation for competition, from the engineering portfolio to presenting to the judges. The thing I'm proudest of is helping a teammate who had been on the edge of the team find projects he loved, by working with him directly, pairing him with an older mentor and asking for his ideas in meetings.

Entries

Progress log

Reworking SKIDADDLE's control

Code

Skills: Motion planningJava

Over winter break I took SKIDADDLE apart into pieces that each do one job. Controllers now only ask for accelerations: one along the path, one back onto it, one for heading, each with a weight and a priority. A scheduler runs whichever are active, and a default controller brings the robot to a stop when none are. A new allocator turns the requests into motor space and hands out each motor's remaining headroom, highest priority first and shared by weight within a priority, so correcting off the path can come before speeding along it without any motor going past its limits. The look-ahead, before the most expensive part of the loop, became a precompute: when a path is made, one backward pass finds the fastest speed the robot can enter each turn at, so the loop only reads it.

Diagram: once per path, a path generator feeds precomputed speed limits; every loop, controllers send requests to a scheduler, which feeds an allocator that drives the wheels
The follower after the rework.

Planning in motor space means a turn's sideways acceleration comes out of the same wheel budget as speeding up and slowing down. Road Runner limits acceleration only along the path, so on a tight hairpin at the same limits its plan asks for more grip than the wheels have, falls behind and overshoots the end. With its limit lowered to 30 in/s² it stays within 9 in; SKIDADDLE stays within 4.5 in and stops 0.7 s sooner. It isn't ahead everywhere: on sharp corners Road Runner with the lower limit tracks tighter, and the rework doesn't correct sideways error yet, so it can stop a few inches off the end point.

Four runs around the same hairpin. Road Runner at the shared 50 in/s² limit falls behind in the curve and overshoots the end by 22 in. With its limit lowered to 30 it strays 9.1 in and stops after 7.2 s. Pedro Pathing strays 8.1 in and stops after 7.2 s. SKIDADDLE strays 4.5 in, stops after 6.5 s, and ends 3.1 in from the end point
Simulated: one mecanum robot model and the same speed and acceleration limits for all three. Road Runner 1.0.1 and Pedro Pathing 3.0.2 run from their source; SKIDADDLE's plan is followed with feedforward and a position term.

SKIDADDLE: a path follower that plans with physics

Code

Skills: Motion planningJavaOpen source

SKIDADDLE is a path-following library for FTC robots, written in Java, that I built to fix inefficiencies in Road Runner, the usual FTC path library, and get better paths. It plans with a physics model of the robot, and I derived all of its math by hand, myself, without AI or earlier work to build on. A path, a cubic Bézier for autonomous or a Hermite spline built on the fly in tele-op, is flattened into straight segments by adaptive De Casteljau subdivision, and a curve whose turns would need more than the robot's acceleration is relaxed until they don't. Every loop it splits the robot's velocity into a convergent part, toward the goal, and a transverse part, everything else. It first spends its acceleration budget cancelling the transverse part, then speeds up the convergent part, so from any starting position or velocity the robot converges on the path. A look-ahead over the stopping distance sets the fastest speed for each corner, and the robot switches segments when its braking distance says it must. Heading is a separate controller, and the result goes through PIDF and feedforward to the four wheels. A simulator draws the field and graphs every step.

SKIDADDLE's own simulator following a cubic Bézier path, in real time.
Line chart over the run: blue speed rises, follows the green speed limit through the turns and falls to zero at the end; the red acceleration sits at its cap and drops whenever the speed reaches the limit
The simulator's graph of the same run: speed (blue) tracking the look-ahead's speed limit (green), acceleration (red) mostly at its cap.

Live View: camera video sent as text

Code

Skills: Java

FTC rules ban streaming camera images to the driver station during a match, but telemetry text is allowed, so Live View sends the robot's camera feed as text. Each frame is shrunk and converted to the Lab colour space on the robot, then drawn with Braille characters as pixels: each character is a 2×4 block of dots, and Floyd–Steinberg dithering decides which dots are on, so shading survives with only on and off. To keep the message small, colour is added only for the game pieces: runs of characters that match the yellow, red or blue samples are wrapped in a colour tag, and only the 100 longest runs are kept. The text goes out as HTML telemetry ten times a second. It gave our drivers a view of what the robot could see during matches, within the rules.

Live View on the driver station: every frame is text.

Two robots, so software never waits

Skills: Technical leadership

As captain I set up a new way to build our robot: two robots developed in parallel. While the CAD was being finished, we assembled the drive trains. Software then got the first robot, a bare drive train, to test on, while mechanical integrated the first feature, such as the lift, on the second. Once that feature passed our definition of done, the teams traded: software integrated the feature and kept developing, and mechanical moved on to the next feature, like the arm, on the other robot, and the trading continued all season. Software was always testing on a competition-ready robot while mechanical kept building, our drivers got more practice before the robot was feature complete, and we would have had a robot ready for competition even if mechanical badly missed a deadline.

Timeline in two rows, software and mechanical: after the CAD and drive trains, software tests on robot A while mechanical builds the lift on robot B; at each definition of done the two teams trade robots, so software takes the robot with the newest feature and mechanical builds the next feature on the other
The hand-off: at each definition of done, the two teams trade robots.