Разработка AI-системы помощи водителю (ADAS)
ADAS (Advanced Driver Assistance Systems) — это уровень L1–L2 автономности: система помогает водителю, но не заменяет его. Конкретные функции: предупреждение о выезде с полосы (LDW), экстренное торможение (AEB), адаптивный круиз-контроль (ACC), мониторинг слепых зон (BSW). Каждая из них — отдельная CV-задача со своими требованиями к latency и точности.
Ключевые функции и реализация
import cv2
import numpy as np
from ultralytics import YOLO
import torch
class ADASSystem:
def __init__(self, config: dict):
self.lane_detector = self._load_lane_model(config)
self.object_detector = YOLO(config['object_model']) # YOLOv8n для скорости
self.depth_estimator = self._load_depth_model(config)
self.camera_matrix = np.array(config['camera_intrinsics'])
self.focal_length = self.camera_matrix[0, 0]
self.baseline = config.get('stereo_baseline', None)
# Пороги для предупреждений
self.ttc_warning = 2.5 # секунды — предупреждение
self.ttc_critical = 1.5 # секунды — AEB
self.lane_offset_threshold = 0.3 # метра
def lane_departure_warning(self, frame: np.ndarray,
vehicle_speed: float) -> dict:
"""
Детекция полосы: классика — UFLD (Ultra-Fast Lane Detection)
или CLRNet для сложных условий (пересечения, плохая разметка).
"""
lanes = self.lane_detector(frame)
if len(lanes) < 2:
return {'warning': False, 'reason': 'no_lanes'}
# Центр автомобиля относительно полосы
frame_center = frame.shape[1] // 2
lane_center = (lanes[0][-1][0] + lanes[1][-1][0]) // 2
offset_px = frame_center - lane_center
# Перевод пикселей в метры через гомографию
offset_m = offset_px * (3.5 / abs(lanes[1][-1][0] - lanes[0][-1][0]))
warning = abs(offset_m) > self.lane_offset_threshold
return {
'warning': warning,
'offset_meters': offset_m,
'lane_width': abs(lanes[1][-1][0] - lanes[0][-1][0])
}
def collision_warning(self, frame: np.ndarray,
ego_speed: float) -> dict:
detections = self.object_detector(frame, conf=0.5,
classes=[0, 2, 3, 5, 7])
depth_map = self.depth_estimator(frame)
warnings = []
for box in detections[0].boxes:
x1, y1, x2, y2 = map(int, box.xyxy[0])
cx = (x1 + x2) // 2
# Дистанция из depth map (стерео или монокулярная)
roi_depth = depth_map[y1:y2, x1:x2]
distance = float(np.percentile(roi_depth, 10)) # ближняя часть объекта
# TTC при текущей скорости
if distance > 0 and ego_speed > 0:
ttc = distance / ego_speed # упрощённо, без учёта скорости объекта
else:
ttc = float('inf')
if ttc < self.ttc_critical:
action = 'AEB'
elif ttc < self.ttc_warning:
action = 'WARNING'
else:
continue
warnings.append({
'class': self.object_detector.model.names[int(box.cls)],
'distance_m': distance,
'ttc_sec': ttc,
'action': action
})
return {'warnings': sorted(warnings, key=lambda x: x['ttc_sec'])}
Производительность: почему latency важнее точности
На скорости 100 км/ч автомобиль проезжает 27,8 метра в секунду. Задержка системы 100ms = 2,78 метра «вслепую». Поэтому для ADAS:
| Функция | Макс. latency | Рекомендуемая модель |
|---|---|---|
| AEB (экстренное торможение) | < 30ms | YOLOv8n + TensorRT INT8 |
| LDW (предупреждение о полосе) | < 50ms | CLRNet или UFLD |
| BSW (слепые зоны) | < 100ms | YOLOv8s |
| ACC (круиз-контроль) | < 100ms | Глубина + детекция |
| Дорожные знаки | < 200ms | EfficientDet-D2 |
YOLOv8n с TensorRT FP16 на NVIDIA Orin: 3–5ms на кадр. На Qualcomm SA8295P (Snapdragon Ride): 8–12ms через QNN SDK.
Монокулярная оценка глубины
Если стерео камеры нет — используем MonoDepth2 или DPT (Dense Prediction Transformer). Точность хуже стерео, но достаточна для предупреждений:
from transformers import AutoImageProcessor, AutoModelForDepthEstimation
class MonocularDepth:
def __init__(self):
self.processor = AutoImageProcessor.from_pretrained(
"LiheYoung/depth-anything-large-hf"
)
self.model = AutoModelForDepthEstimation.from_pretrained(
"LiheYoung/depth-anything-large-hf"
)
@torch.no_grad()
def estimate(self, image: np.ndarray) -> np.ndarray:
inputs = self.processor(images=image, return_tensors="pt")
outputs = self.model(**inputs)
depth = outputs.predicted_depth.squeeze().numpy()
# Масштабируем в метры через калибровочный коэффициент
return depth
Depth Anything v2 Large даёт AbsRel = 0.076 на KITTI — достаточно для определения дистанции до ±10% при 10–30 метрах.
Сертификация и стандарты
ADAS-системы для серийных автомобилей требуют соответствия:
- ISO 26262 (Functional Safety, ASIL-B/C для AEB)
- ISO/SAE 21434 (Cybersecurity)
- UNECE R79/R130 (регуляторные требования для LDW и AEB)
Для внутрицехового или carport применения (не public road) требования мягче — используем automotive grade без полной ISO 26262 сертификации.
| Тип проекта | Срок |
|---|---|
| Прототип одной функции (LDW или AEB) | 6–10 недель |
| Комплекс L2 ADAS (4–6 функций) | 4–7 месяцев |
| Automotive-grade с ISO 26262 | 12–24 месяца |







