Experiments · simulation · VEX AIM

AI writes the code, watches the run, tries again

A loop some classrooms are trying: an AI model writes the program for a VEX AIM robot, the robot runs it while a camera films from above, and the model sees what happened and writes the next version. We rebuilt the robot side in simulation, checked it against real runs, and scored 108 runs with MotionBench.

Watch

Simulated. The barrel game, the same model twice. Left: attempt 1, written from the start photo alone. Right: attempt 3, after two rounds of feedback.

Four games on the 18-inch kit field

  • One tag. Grab the ball, knock down an AprilTag sign with it. Don't ram the sign.
  • Two tags. Knock down two signs, grabbing the ball again after the first.
  • Two tags, two barrels. Two signs, each with a barrel beside it. Hit a barrel with the ball and the run fails.
  • Sort the barrels. Six barrels into the tiles of AprilTags 4 (orange) and 0 (blue), in 60 seconds.

Feedback can turn a failure around. Claude Opus scored 0 of 6 on the barrel game with its first program: it guessed which corner tag was which, and guessed wrong. After seeing the run, its next program read the tags first and scored 6 of 6 on every run.

How it works

  1. 1

    The model writes a program

    It gets the robot's Python API, the game's rules and a photo of the field from above, and writes a complete program for the AIM robot.

  2. 2

    The program runs, unchanged

    Exactly as on the real robot: through the robot's own Wi-Fi client library. Here a simulated AIM robot answers it instead of the real one, so a 60-second run takes a fraction of a second.

  3. 3

    The camera watches

    A frame from above every 2 seconds, plus the program's log and the robot's telemetry. The next attempt is written after seeing all of it. Three attempts, three runs each.

  4. 4

    MotionBench scores it

    Every run gets the game's own points and a MotionBench score against the task's goal, with rule breaks such as ramming a sign counted separately.

Checked against the real robot

Before trusting the simulator we gave it real work. The loop’s own recordings of the one-tag game hold four programs written by three AI models. We ran each program’s exact code in simulation 20 times, each time with different wheel slip and camera noise, and compared the outcome with what the real robot did. The pictures are the real camera’s last frame.

  • Real overhead camera, end of Model A · attempt 1: knocked the tag down with a kicked ball

    Model A · attempt 1

    Real robot
    Knocked the tag down with a kicked ball
    Simulation
    Same outcome in 18 of 20 runs
    Run time
    real 16.7 s · simulated 14.7 s
  • Real overhead camera, end of Model B · attempt 1: knocked the tag down with a kicked ball

    Model B · attempt 1

    Real robot
    Knocked the tag down with a kicked ball
    Simulation
    Same outcome in 20 of 20 runs
    Run time
    real 22.9 s · simulated 22.4 s
  • Real overhead camera, end of Model C · attempt 1: never found the tag

    Model C · attempt 1

    Real robot
    Never found the tag
    Simulation
    Same outcome in 20 of 20 runs
    Run time
    real 60.0 s · simulated 60.0 s
  • Real overhead camera, end of Model C · attempt 2: drove into the tag carrying the ball

    Model C · attempt 2

    Real robot
    Drove into the tag carrying the ball
    Simulation
    Same outcome in 20 of 20 runs
    Run time
    real 60.1 s · simulated 60.0 s

The models are not named: they were run by the people who built the loop. The recordings also set the simulator’s robot size, camera geometry, how a held ball looks to the camera, and the Wi-Fi delay per command. Tag IDs, pixel sizes and end positions in the simulated logs match the real ones to within a few pixels and 2 to 4 cm.

Three models, three attempts, four games

Average game points per attempt over three runs, with the single runs in brackets. Attempt 2 is written after seeing attempt 1’s code, logs, telemetry and camera frames; attempt 3 after attempt 2’s. Every model call was made by a fresh Claude agent shown only what the loop sends the model.

GameModelAttempt 1Attempt 2Attempt 3
One tag · 1 ptClaude Opus0 (0, 0, 0) rammed 3×1 (1, 1, 1)1 (1, 1, 1)
Claude Sonnet0 (0, 0, 0) rammed 3×0 (0, 0, 0) rammed 3×0 (0, 0, 0) rammed 3×
Claude Haiku0 (0, 0, 0) rammed 3×0 (0, 0, 0) rammed 3×0 (0, 0, 0) rammed 2×
Two tags · 2 ptsClaude Opus1.3 (1, 2, 1) rammed 2×2 (2, 2, 2)2 (2, 2, 2)
Claude Sonnet2 (2, 2, 2)2 (2, 2, 2)2 (2, 2, 2)
Claude Haiku0 (0, 0, 0) rammed 3×1.3 (1, 1, 2) rammed 1×1.3 (1, 1, 2) rammed 1×
Two tags, two barrels · 2 ptsClaude Opus1.7 (2, 2, 1)0 (0, 0, 0) failed 3×1.3 (0, 2, 2) failed 1×
Claude Sonnet0 (0, 0, 0) failed 3×1.3 (2, 1, 1)1.7 (1, 2, 2)
Claude Haiku0 (0, 0, 0) failed 3×1 (0, 1, 2) failed 1×0 (0, 0, 0) failed 3×
Sort the barrels · 6 ptsClaude Opus0 (0, 0, 0)6 (6, 6, 6)6 (6, 6, 6)
Claude Sonnet2.7 (3, 3, 2)5 (5, 5, 5)5 (6, 6, 3)
Claude Haiku1 (1, 1, 1)2 (2, 2, 2)3 (2, 3, 4)

“Failed”: a barrel was hit, which zeroes the run under the game’s rules. “Rammed”: the robot knocked a sign over itself, which doesn’t count. MotionBench boards for each game, with goal shares, ranges and the MotionBench Index, are in the replays.

What the loop caught

  • Feedback works when the failure is visible

    In the barrel game, Opus went from 0 to 6 of 6 once it saw its barrels land in the wrong corners. In the one-tag game its first program rammed the sign on every run; after watching that, the next one kicked the ball instead and scored every time.

  • Some mistakes never get fixed

    Sonnet and Haiku rammed the sign in the one-tag game on 9 and 8 of 9 runs and never scored: the same mistake one of the real models made on the real robot. Three attempts weren’t enough to unlearn it.

  • The model never sees its score

    In the barrel-guard game Opus’s second program knocked both signs down on every run, but the ball grazed a barrel, so all 3 runs failed. Reading the frames, the model thought it had won. The loop only shows what happened, not how it was judged; adding the score to the feedback is the obvious fix.

  • Minutes become seconds

    On the real field one attempt with three runs took about 10 minutes: the model writing (3 min), and for each run a field reset (94 s) and the run itself (43 s). Simulated runs take 0.27 s, so only the model’s time is left: about 3 minutes, and the 12 experiments here ran side by side, not one after another.

Replay every run

Open the replays

All 108 simulated runs (62 minutes of robot time, 29 seconds to compute), drawn on the field: pick a game, model, attempt and run, scrub through it next to the program’s own log, and read the program and the feedback it was written from. The page also has the MotionBench board for each game.

The games are MotionBench tasks you can run yourself: MB-AIM-TAG1@0.1, MB-AIM-TAG2@0.1, MB-AIM-TAG2B@0.1, MB-AIM-SORT18@0.1 (task details).

What this can and can’t tell you

  • It’s a simulation. It tells you which version of the code to try on the robot first, not how the robot will do. Only the one-tag game has been checked against real runs so far; the other three fields were measured from their start photos.
  • Every model call was made by a Claude agent shown exactly what the loop sends a model. An agent can choose to look at fewer of the up to 50 camera frames than an API call would receive.
  • Three runs per attempt and one experiment per model and game is a small sample. Read the results as what happened here, not as a ranking of models.
  • The ball’s friction, kick strength and when a sign falls are our estimates, as is which corner tag is which in the barrel game.

How the simulator runs programs written for the AIM Wi-Fi client, and how the games are defined: docs/games.md. The new goal for knock-down games: RFC-0003.