Problem
The capstone simulates an autonomous truck on the Mauá campus inside CARLA, a heavy simulator that only runs on a machine with a GPU. The committee, the fair and the partner needed to see the result without installing anything.
My role
I built every part: the Python navigation (perception, sensor fusion and control), the map pipeline, the telemetry dashboards and the published 3D model.
Solution
- 3D campus model built from the real topographic survey: a 21-part glTF mesh, 28 buildings matched to the buildings sheet, a 784 m ring road with 4 speed bumps and 8 crosswalks, and 411 of the 1,743 surveyed trees.
- Autonomous truck with a deterministic speed profile: it brakes on speed bumps (8 km/h), slows at crosswalks (12 km/h) and stops for 3 s when a pedestrian is there.
- Operations UI: KPIs, lap timeline, search with camera fly-to, camera modes and a presentation mode to leave running on a TV.
How it was built
- Simulation: Python on CARLA 0.9.16, perception with YOLO, LiDAR and cameras, GNSS + IMU fusion with a Kalman filter, Pure Pursuit control and SQLite telemetry.
- Map: survey DXF converted to OpenDRIVE (34 roads, 4 junctions, 1.56 km) by a pipeline with automatic validation.
- Web: Next.js static export and React Three Fiber; meshopt compression brings the model to 0.4 MB and the whole site to 2.9 MB.
- Tests: Playwright drives 5 laps in a row checking that no wheel leaves the road, and a test confirms the site works offline. The simulation has 362 offline tests.
Results
The model opens in any browser, phones included, and went live on GitHub Pages for the committee and the fair. The same simulation data feeds the 3D dashboard live and in replay.
Next steps
Validate the new map round live, calibrate the speed-bump detector with real LiDAR data and measure the web dashboard overhead on the simulation (target: under 5% FPS).
Code
// passes de frenagem (para tras) e aceleracao (para frente),
// duas voltas para fechar o ciclo
for (let r = 0; r < 2; r++)
for (let k = 2 * n - 1; k >= 0; k--) {
const i = k % n;
const j = (i + 1) % n;
v[i] = Math.min(v[i], Math.sqrt(v[j] * v[j] + 2 * A_FREIO * ds));
}
for (let r = 0; r < 2; r++)
for (let k = 0; k < 2 * n; k++) {
const i = (k + 1) % n;
const h = k % n;
v[i] = Math.min(v[i], Math.sqrt(v[h] * v[h] + 2 * A_ACEL * ds));
}Stack
- Python
- CARLA
- YOLO
- OpenDRIVE
- Next.js
- React Three Fiber
- Playwright