Repository
Virtual-Self-Driving-Car-AI-using-Kivy-and-Reinforcement-Learning
π Virtual Self-Driving Car AI A self-driving car simulation using Deep Q-Learning and Kivy β the agent learns to navigate a 2D map while avoiding user-drawn obstacles in real time. Β· License MIT Β· Install via pip Β· Maintenance unknown
- License
- MIT
- Component
- Detail
- Network
- input(5) β fc(30, ReLU) β output(3)
- Replay buffer
- 100,000 transitions, batch size 100
Specs
- ComponentDetail
- Networkinput(5) β fc(30, ReLU) β output(3)
- Replay buffer100,000 transitions, batch size 100
- OptimizerAdam, lr = 0.001
- LossSmooth L1 (Huber)
- Ξ³ (discount)0.9
- ExplorationSoftmax with temperature T=100
- InputDescription
- signal1Sand density around front sensor (20Γ20 px window)
- signal2Sand density around left sensor (+30Β°)
- signal3Sand density around right sensor (β30Β°)
- orientationAngle between velocity and goal direction β [-1, 1]
- -orientationNegated orientation (symmetry signal)
- ActionRotation
- 00Β° (straight)
- 1+20Β° (left)
- 2β20Β° (right)
- ConditionReward
- On sandβ1.0
- On road, moving awayβ0.2
- On road, approaching goal+0.1
- Hitting map edgeβ1.0
- TechnologyPurpose
- π§ PyTorch
- πΌοΈKivy
- π’NumPy
- πMatplotlib
- πPython 3.8+
- Original (broken)Fixed
- from torch.autograd import VariableRemoved β raw tensors used directly
- Variable(state, volatile=True)torch.no_grad() context manager
- F.softmax(x * 100) (no dim)F.softmax(x * 100, dim=1)
- probs.multinomial()probs.multinomial(num_samples=1)
- action.data[0, 0] (returns tensor)action.item() (returns Python int)
- retain_variables=Trueretain_graph=True
- Variable(torch.cat(x, 0))torch.cat(x, 0)
- torch.Tensor(input_size) (uninitialized)torch.zeros(input_size)
- torch.Tensor([val])torch.tensor([val], dtype=...)
- Hardcoded 'last_brain.pth' pathos.path.join(os.path.dirname(__file__), ...)
- Sensor reads with no bounds checking_read_sensor() helper with clamped indices
README
π Virtual Self-Driving Car AI
A self-driving car simulation using Deep Q-Learning and Kivy β the agent learns to navigate a 2D map while avoiding user-drawn obstacles in real time.


What It Does
A small car navigates a 2D canvas, learning in real time to drive between two goal points (top-left β bottom-right). Draw "sand" obstacles on the map with your mouse β the car learns to avoid them using reinforcement learning. The brain can be saved and loaded between sessions.
Architecture
Deep Q-Network (DQN)
| Component | Detail |
|---|---|
| Network | input(5) β fc(30, ReLU) β output(3) |
| Replay buffer | 100,000 transitions, batch size 100 |
| Optimizer | Adam, lr = 0.001 |
| Loss | Smooth L1 (Huber) |
| Ξ³ (discount) | 0.9 |
| Exploration | Softmax with temperature T=100 |
State Space (5 inputs)
| Input | Description |
|---|---|
signal1 |
Sand density around front sensor (20Γ20 px window) |
signal2 |
Sand density around left sensor (+30Β°) |
signal3 |
Sand density around right sensor (β30Β°) |
orientation |
Angle between velocity and goal direction β [-1, 1] |
-orientation |
Negated orientation (symmetry signal) |
Action Space
| Action | Rotation |
|---|---|
| 0 | 0Β° (straight) |
| 1 | +20Β° (left) |
| 2 | β20Β° (right) |
Rewards
| Condition | Reward |
|---|---|
| On sand | β1.0 |
| On road, moving away | β0.2 |
| On road, approaching goal | +0.1 |
| Hitting map edge | β1.0 |
Goal flips to the opposite corner when the car gets within 100 px.
Project Structure
Self_Driving_Car/
βββ ai.py # DQN agent: network, replay memory, training loop
βββ map_commented.py # Kivy app: car physics, sensors, game loop, rewards
βββ car.kv # Kivy layout: car and sensor widget definitions
π Tech Stack
| Technology | Purpose | |
|---|---|---|
| π§ | PyTorch | Deep Q-Network |
| πΌοΈ | Kivy | 2D simulation GUI |
| π’ | NumPy | Sensor signal processing |
| π | Matplotlib | Score plotting |
| π | Python 3.8+ | Runtime |
Getting Started
Install dependencies
pip install kivy torch numpy matplotlib
Run
cd Self_Driving_Car
python map_commented.py
Controls
- Draw obstacles β click and drag to paint sand
- Clear β remove all sand
- Save β save brain to
last_brain.pth+ plot scores - Load β restore a previously saved brain
Modernization Changelog
Fixes applied to bring the codebase up to date with current PyTorch (2.x):
| Original (broken) | Fixed |
|---|---|
from torch.autograd import Variable |
Removed β raw tensors used directly |
Variable(state, volatile=True) |
torch.no_grad() context manager |
F.softmax(x * 100) (no dim) |
F.softmax(x * 100, dim=1) |
probs.multinomial() |
probs.multinomial(num_samples=1) |
action.data[0, 0] (returns tensor) |
action.item() (returns Python int) |
retain_variables=True |
retain_graph=True |
Variable(torch.cat(x, 0)) |
torch.cat(x, 0) |
torch.Tensor(input_size) (uninitialized) |
torch.zeros(input_size) |
torch.Tensor([val]) |
torch.tensor([val], dtype=...) |
Hardcoded 'last_brain.pth' path |
os.path.join(os.path.dirname(__file__), ...) |
| Sensor reads with no bounds checking | _read_sensor() helper with clamped indices |
| Sand painting with negative indices | Clamped to valid array range |
β οΈ Known Issues
- The simulation relies on global state, making it fragile for extension but functional as a learning project.
- No GPU support configured β runs on CPU only (sufficient for this network size).
- Button positions are hardcoded relative to initial widget size and may overlap on small windows.
License
MIT β Kaustabh Ganguly, 2018