A Lane Keeping Assist System (LKAS) simulation built from first principles using classical computer vision and control theory. Designed as a portfolio project demonstrating perception-to-control pipeline fundamentals without relying on neural networks.
The system detects lane lines using classical computer vision and outputs real-time steering commands via a PID controller.
┌─────────────────────────────────────────────────────────────┐
│ Camera Frame │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ ╱ ╲ │ │
│ │ ╱ ROI (Trapezoid) ╲ │ │
│ │ ╱ ╲ │ │
│ │ ╱ ● Lane Center ╲ │ │
│ │ ╱ │ ╲ │ │
│ │ ╱ CTE ─┼── Vehicle Center ╲ │ │
│ │ ══════════════════════════════════════ │ │
│ │ Left Lane Right Lane │ │
│ └─────────────────────────────────────────────────────┘ │
│ HUD: CTE: -15.3 px | Steering: 2.1° | Lines: 12 │
└─────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────┐
│ PERCEPTION │
│ ┌──────────┐ ┌─────────┐ ┌────────────┐ ┌───────────┐ │
│ │ Frame │───▶│ Canny │───▶│ Hough │───▶│ Lane │ │
│ │ Input │ │ Edges │ │ Lines │ │ Center │ │
│ └──────────┘ └─────────┘ └────────────┘ └─────┬─────┘ │
└─────────────────────────────────────────────────────────┼────────┘
│ CTE
┌─────────────────────────────────────────────────────────┼────────┐
│ CONTROL ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ PID Controller │ │
│ │ steering = Kp·error + Ki·∫error·dt + Kd·d(error)/dt │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┬────────┘
│ Steering
┌─────────────────────────────────────────────────────────┼────────┐
│ SIMULATION ▼ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Bicycle Model │ │
│ │ ω = (v/L)·tan(δ), ẋ = v·cos(θ), ẏ = v·sin(θ) │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
- Canny Edge Detection with configurable thresholds
- ROI Masking - Trapezoidal region focusing on road ahead
- Probabilistic Hough Transform for line segment detection
- Slope Filtering - Removes horizontal noise (shadows, crosswalks)
- Lane Classification - Separates left/right lanes by position and slope
- Temporal Filtering - Exponential moving average for stability
- Full PID Implementation - Proportional, Integral, Derivative terms
- Anti-Windup Protection - Clamped integral accumulator
- Output Saturation - Realistic steering angle limits
- Runtime Tuning - Adjustable gains without recompilation
- Bicycle Model Dynamics - Accurate low-speed vehicle kinematics
- Steering Rate Limiting - Can't turn instantly (realistic actuator)
- Steering Angle Limits - Physical wheel constraints
- Telemetry Logging - CSV output for analysis
- Detected lane lines (color-coded left/right)
- ROI overlay
- Lane center and vehicle center markers
- CTE visualization line
- Real-time HUD with steering indicator
- FPS counter
- C++17 compatible compiler (GCC 7+, Clang 5+, MSVC 2017+)
- CMake 3.12+
- OpenCV 4.0+ (with development headers)
macOS (Homebrew):
brew install opencvUbuntu/Debian:
sudo apt-get install libopencv-devWindows:
Download from OpenCV.org and set OpenCV_DIR environment variable.
mkdir build && cd build
cmake ..
make -j$(nproc)./MiniPilot./MiniPilot --video path/to/driving_video.mp4./MiniPilot --video input.mp4 --save output.avi --kp 0.003 --ki 0.0001 --kd 0.002| Argument | Description | Default |
|---|---|---|
--video <path> |
Input video file | (synthetic mode) |
--camera <id> |
Camera device ID | 0 |
--no-viz |
Disable visualization | false |
--save <path> |
Save output video | (no save) |
--kp <value> |
PID proportional gain | 0.8 |
--ki <value> |
PID integral gain | 0.015 |
--kd <value> |
PID derivative gain | 0.35 |
--help |
Show help | - |
- ESC or q: Quit
- Space: Pause/Resume
miniPilot/
├── CMakeLists.txt # Build configuration
├── include/
│ ├── Config.h # Configuration structs
│ ├── LaneDetector.h # Lane detection interface
│ └── PIDController.h # PID controller interface
├── src/
│ ├── main.cpp # Entry point & simulation loop
│ ├── LaneDetector.cpp # CV pipeline implementation
│ └── PIDController.cpp # Control implementation
├── README.md # This file
└── .gitignore
All parameters are configurable via Config.h:
LaneDetectorConfig config;
config.canny_low_threshold = 50; // Edge detection sensitivity
config.canny_high_threshold = 150;
config.hough_threshold = 50; // Line detection sensitivity
config.temporal_alpha = 0.3; // Smoothing (0=max smooth, 1=no smooth)The system generates telemetry.csv with per-frame data:
frame,cte,steering_deg,vehicle_x,vehicle_y,heading_deg
0,-12.5,1.2,0.00,0.00,0.00
1,-11.8,1.1,0.33,0.01,0.02
...With --save, generates annotated video showing:
- Detected lane lines
- ROI overlay
- Real-time telemetry HUD
The signed distance from the vehicle center to the lane center:
- Positive CTE: Vehicle is left of center → steer right
- Negative CTE: Vehicle is right of center → steer left
| Parameter | Effect |
|---|---|
| Kp (Proportional) | Immediate response to error. Too high = oscillation |
| Ki (Integral) | Eliminates steady-state error. Too high = overshoot |
| Kd (Derivative) | Dampens oscillation. Too high = noise sensitivity |
Recommended starting point: Kp=0.002, Ki=0.0001, Kd=0.001
Simplified vehicle dynamics assuming:
- Front-wheel steering
- No slip (low speed)
- Constant velocity
Angular velocity: ω = (v / L) × tan(δ)
Position update: x += v × cos(θ) × dt
y += v × sin(θ) × dt
Where: v = velocity, L = wheelbase, δ = steering angle, θ = heading
- Curved lane detection (polynomial fitting)
- Kalman filter for lane tracking
- Model Predictive Control (MPC)
- Lane departure warning
- Multi-lane detection
- Night/rain robustness
MIT License - Free for educational and portfolio use.
Built as a portfolio project demonstrating classical computer vision and control theory fundamentals.
