← All projects

Reinforcement learning · 2022

LiDAR-Based Autonomous Driving

A pure-C autonomous-driving simulation organized as prioritized periodic tasks on a non-real-time Linux system.

Minimal illustration of an autonomous car sensing a racing track with three LiDAR rays beside a compact Q-learning state matrix.

01

Overview

The main purpose of this university project, documented in its technical report, was to reproduce the organization and scheduling concerns of a real-time application through multiple prioritized periodic tasks. The software ran on a standard, non-real-time Linux system, so it did not claim hard real-time guarantees. Instead, explicit task priorities, periods, relative deadlines, absolute-time activation, shared-resource protocols, and deadline-miss counters made scheduling behaviour observable while the autonomous-driving simulation supplied a realistic concurrent workload.

A defining constraint was that the complete application—including the reinforcement-learning algorithm—was implemented directly in pure C. The Q-learning and Q-velocity matrices, epsilon-greedy policy, reward calculation, state encoding, task utilities, timing functions, vehicle model, collision logic, telemetry, and persistence were all written from scratch without an external AI, robotics, numerical, or vehicle-dynamics library. Apart from the standard C and POSIX system facilities, Allegro was the only external dependency, and its role was limited to window management, bitmap access, and rendering.

Environmental perception uses a deliberately compact LiDAR model. One forward ray and two rays angled at ±45° measure the distance to the track boundary, up to 100 m, by scanning pixel colours in the rendered map. The lateral difference and forward range are quantized into seven levels each, reducing three raw measurements to 49 discrete states. Collision detection follows a similar graphical approach by testing the edges of the car footprint against the black boundary pixels.

An epsilon-greedy Q-learning agent maps those states to driving actions. In steering-only mode, speed remains fixed and the policy chooses one of 17 steering angles from −40° to +40°. In the more ambitious steering-and-acceleration mode, a second quality matrix learns longitudinal commands alongside steering. The reward combines a strong crash penalty with smaller terms for survival time, distance covered, steering smoothness, valid acceleration, and proximity to the track centre. Learned matrices can be saved, loaded, and reused in inference mode.

The simulated car follows the rear-axle kinematic bicycle model shown in the report. Its reference point lies at the rear axle; L is the axle distance, v is longitudinal speed, θ is vehicle heading, and δ is the commanded front-wheel steering angle. The instantaneous turning radius is R = L / tan(δ), producing the implemented yaw rate θ̇ = v tan(δ) / L.

Top-down four-wheel car with two blue equivalent bicycle-model wheels: a fixed rear wheel at the rear-axle centre and a front wheel rotated by steering angle delta, with heading, wheelbase, turn radius, and instantaneous centre of rotation marked.
The four white wheels show the physical vehicle; the two blue wheels show its bicycle-model reduction. Diagram from Algorithms for Automated Driving, licensed under CC BY 4.0.

The bicycle representation collapses each physical axle into one equivalent wheel at its centre. The rear blue wheel remains aligned with the vehicle body and is the position reference. The front blue wheel is rotated by the steering command δ. Both wheels are mathematical abstractions: together they replace the four contact patches while preserving the geometry needed to calculate curvature and heading change.

Every 20 ms, the old velocity advances x, y, and heading; acceleration then produces the velocity for the next step. The C implementation uses = v cos(θ), = v sin(θ), and θ̇ = v tan(δ) / L. Speed is clamped between zero and the configured maximum, reverse motion is disabled to simplify learning, and heading is wrapped into [0, 2π). This deterministic model couples steering, speed, pose, LiDAR measurements, and the next reinforcement-learning state.

Around the model, the multi-task configuration separates rendering, keyboard commands, LiDAR updates, and agent/model updates into periodic pthread tasks. The implementation requests explicit SCHED_RR priorities: commands run at priority 40, sensing and agent updates at priority 10, and rendering at priority 5. Shared vehicle, sensor, velocity, and Q-learning data are guarded by mutexes configured with priority inheritance. A single-task mode combines the loop for faster debugging and training, while multi-task mode exposes scheduling interactions and deadline misses directly in the interface.

The report records the strongest results in steering-only mode: useful behaviour emerged after roughly 8,000 episodes, with training at 5 m/s and successful tests up to approximately 15 m/s. Joint steering and acceleration learning did not converge as completely; pre-training steering before enabling acceleration improved it, but also highlighted the limits of the tabular state representation and reward design. That contrast was an important result of the project, showing both where a compact Q-learning controller works and where the problem needs a richer state or learning strategy.

02

My contribution

  • Implemented the entire application and reinforcement-learning algorithm directly in C, without an external AI, numerical, vehicle-dynamics, or task framework; Allegro was used only for graphics.
  • Built the complete 2D simulator, including the track environment, telemetry interface, collision detection, and rear-axle kinematic bicycle model.
  • Implemented a simplified LiDAR with front and ±45° rays, pixel-based range measurement, and a compact 49-state representation for learning.
  • Developed the epsilon-greedy Q-learning module, reward function, Q-matrix persistence, training/inference workflow, and separate steering and acceleration policies from scratch.
  • Decomposed the application into periodic pthread tasks with explicit priorities, periods, deadlines, round-robin scheduling, and deadline-miss monitoring.
  • Protected shared vehicle, sensor, velocity, and learning state using priority-inheritance mutexes and evaluated both single-task and multi-task execution.

03

System architecture

The pure-C simulation closes the loop between a pixel-based track, three LiDAR measurements, a compact state encoder, a custom epsilon-greedy Q-learning implementation, and a kinematic bicycle model. Periodic POSIX tasks emulate a prioritized real-time application while executing on a standard, non-real-time Linux system.

Closed learning loop from a track bitmap through three-beam LiDAR, a 49-state encoder, Q-learning, vehicle controls, and a bicycle model, coordinated by four periodic POSIX tasks.
Portfolio-styled reconstruction of the learning loop and task organization documented in the report. Allegro was the only external application dependency and was used for graphics.

04

Technical details

Pure-C learning stack

State encoding, epsilon-greedy action selection, Q and Q-velocity updates, rewards, persistence, telemetry, task utilities, and vehicle dynamics were implemented from scratch in C. Allegro handled rendering only.

Real-time-inspired execution

Sensor, agent, and command tasks run every 20 ms and display updates every 25 ms under prioritized SCHED_RR threads. The ordinary Linux host does not provide hard real-time guarantees, so deadline misses are measured explicitly.

Perception and actions

Three rays measure up to 100 m by walking through track pixels. Their quantized state selects steering from −40° to +40°; an optional second policy selects acceleration.

Dynamics and reward

A 20 ms rear-axle bicycle-model update advances position, heading, and speed. Rewards combine collision, progress, centre keeping, steering smoothness, and acceleration validity.

05

Technologies

  • Pure C
  • POSIX Threads
  • Custom Q-Learning
  • Allegro Graphics
  • SCHED_RR
  • Real-Time Systems
  • Linux

06

Media

Animated interface showing the learned agent steering around a two-dimensional circuit using three visible LiDAR beams, with telemetry, deadline counters, and Q values beside the track.
Steering-only inference after training. The animated interface shows the car, its three LiDAR rays, live telemetry, task deadline counters, and the current Q-value distribution.