← Back

03 — Neural Evolution / AI · Research

AV Simulation

Presenting the paper at ICORIS 2024

01 / 02 — Generation 20 on the track, with the sensors and checkpoints shown

Overview

An autonomous-vehicle training simulation built on NEAT (NeuroEvolution of Augmenting Topologies), a genetic algorithm that evolves both a neural network’s topology and its weights. Cars learn to drive 2D race tracks in a Pyglet simulation, and the work was published at ICORIS 2024.

The problem

Hand-designing a neural controller for driving — both its architecture and its weights — is hard and brittle. Evolutionary methods sidestep this by letting the network structure and its weights emerge together from selection pressure over generations. NEAT is well-suited because it grows the simplest effective topology incrementally and preserves diverse solutions via speciation, rather than fixing the architecture up front.

Building it

Each car is a 2D object equipped with distance sensors (rays cast around the vehicle). Those readings feed a neural network whose four outputs are accelerate, brake, turn left, and turn right. NEAT evolves a population of these networks across generations: the fitness function counts the checkpoints (track gates) a car passes, and a 30-second timer caps each generation so a single run can’t stall the simulation. The best car of each generation becomes the parent for the next, with crossover and mutation driving exploration.

How the cars learn to drive Every frame, each car's distance sensors feed a neural network whose shape and weights are evolved by NEAT, and its four outputs (accelerate, brake, turn left, turn right) drive the car. Every generation, a population of cars drives for up to 30 seconds, fitness counts the checkpoints each one passes, and the best car becomes the parent of the next generation through crossover and mutation. Inside one car · every frame car on a Pyglet track distance sensors evolving network acceleratebraketurn leftturn right four outputs drives the car Across generations · NEAT Population 20–80 cars, each withits own network Drive up to 30 secondsper generation Fitness checkpoints passed Next generation best car as parent,crossover, mutation repeat; best scores around generation 50
Each car's network turns sensor readings into controls; NEAT breeds better networks every generation.

I tested on three tracks of increasing difficulty and ran a hyperparameter study over population size and mutation rate, comparing the default setup against three tunings to see how each one converges.

Outcome

Tuning 2 (population 60, mutation rate 0.8) was the strongest overall, rising fastest in early generations. Its peak fitness on each track:

TrackCheckpointsDifficultyPeak fitness, Tuning 2
A33Easy84
B37Medium98
C46Hard100

How the four setups compared:

SetupPopulationMutation rateHow it did
Default400.6The baseline to compare against
Tuning 1200.5Did relatively well only on the easy track
Tuning 2600.8Strongest overall, fastest early progress
Tuning 3800.4Slow early, but caught up on the hardest track

Across all setups, the best scores landed around the 50th generation and didn’t improve meaningfully past the 100th. The work was published at the 2024 6th International Conference on Cybernetics and Intelligent System (ICORIS).

What I learned

The headline finding is that NEAT is genuinely sensitive to its hyperparameters — because it searches over topology and weights through random mutation, the right population/mutation balance matters more than it would for a fixed-length-chromosome GA, and the best setting shifts with track difficulty. That sensitivity is the main limitation to flag for future work, and it’s the throughline into the gradient-based RL I did later: NEAT discovers controller structure well, but careful tuning is the price of that flexibility.