AI Sensor Fusion LiDAR+Камера+Радар для безпілотників

Безпілотний автомобіль їде в тумані. Камера не бачить розмітку. LiDAR втрачає дальність через опади. RADAR фіксує перешкоди від відбиття. Кожен сенсор окремо має сліпі зони: камера непотрібна в темряві, LiDAR — у сильний дощ, а радар не розрізняє пішохода та металевий стовп. Тільки об'єднання даних

Напрямки AI-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    998
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1267
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    714
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1006

Безпілотний автомобіль їде в тумані. Камера не бачить розмітку. LiDAR втрачає дальність через опади. RADAR фіксує перешкоди від відбиття. Кожен сенсор окремо має сліпі зони: камера непотрібна в темряві, LiDAR — у сильний дощ, а радар не розрізняє пішохода та металевий стовп. Тільки об'єднання даних (multi-modal fusion) дає робастність на рівні ASIL-D. Ми розробляємо AI-системи fusion для безпілотників, які об'єднують дані LiDAR, камер та радарів. Наш досвід — 20+ проектів для AV-компаній, понад 8 років в автономних системах. Впровадження fusion дозволяє знизити витрати на розробку на 30% за рахунок повторного використання компонентів та автоматичного калібрування.

Як BEVFusion покращує детекцію?

BEVFusion — один із найефективніших підходів. Перспективні фічі камер проектуються в BEV через LSS (Lift-Splat-Shoot), а фічі LiDAR вилучаються через PointPillars. Об'єднання в єдиному просторі дозволяє використовувати спільний детектор і дає приріст mAP до 30% порівняно з камерою поодинці. BEVFusion в 1.5 рази точніший, ніж late fusion, при всього на 10 мс більшій затримці — це найкращий компроміс accuracy/latency на ринку. Нижче — приклад реалізації на PyTorch.

import torch import torch.nn as nn import numpy as np from typing import Optional class CameraLiDARFusion(nn.Module): """ BEV (Bird's Eye View) fusion камер та LiDAR: - Камери: перспективні фічі → BEV через LSS (Lift-Splat-Shoot) - LiDAR: voxel фічі з PointPillars - Fusion у BEV просторі → unified detection head """ def __init__(self, n_cameras: int = 6, bev_h: int = 200, bev_w: int = 200): super().__init__() self.n_cameras = n_cameras self.bev_h = bev_h self.bev_w = bev_w # Camera backbone (спільний для всіх камер) import timm self.cam_backbone = timm.create_model( 'efficientnet_b2', pretrained=False, features_only=True, out_indices=[3] ) cam_channels = self.cam_backbone.feature_info.channels()[-1] # LSS: підйом фічів у 3D через глибину self.depth_net = nn.Sequential( nn.Conv2d(cam_channels, 128, 3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(128, 64, 1) # 64 bins глибини ) self.cam_feat_net = nn.Conv2d(cam_channels, 64, 1) # LiDAR PointPillar encoder self.lidar_encoder = PointPillarEncoder(out_channels=128) # BEV fusion head self.fusion_conv = nn.Sequential( nn.Conv2d(128 + 64, 256, 3, padding=1), nn.BatchNorm2d(256), nn.ReLU(inplace=True), nn.Conv2d(256, 256, 3, padding=1), nn.BatchNorm2d(256), nn.ReLU(inplace=True) ) # Detection head (спрощений CenterPoint) self.det_head = nn.Sequential( nn.Conv2d(256, 128, 3, padding=1), nn.ReLU(inplace=True), nn.Conv2d(128, 10, 1) # heatmap для 10 класів об'єктів ) def forward(self, camera_imgs: torch.Tensor, lidar_points: torch.Tensor, cam_intrinsics: torch.Tensor, cam_extrinsics: torch.Tensor) -> dict: B, N, C, H, W = camera_imgs.shape # Обробка всіх камер батчем imgs_flat = camera_imgs.view(B*N, C, H, W) cam_feats = self.cam_backbone(imgs_flat)[0] # [B*N, C', H', W'] cam_feats = cam_feats.view(B, N, *cam_feats.shape[1:]) # LSS projection (спрощено) bev_cam = self._lss_project(cam_feats, cam_intrinsics, cam_extrinsics) # LiDAR BEV features bev_lidar = self.lidar_encoder(lidar_points) # Resize для поєднання роздільностей bev_cam_r = nn.functional.interpolate( bev_cam, size=(self.bev_h, self.bev_w), mode='bilinear' ) bev_lidar_r = nn.functional.interpolate( bev_lidar, size=(self.bev_h, self.bev_w), mode='bilinear' ) # Конкатенація та fusion fused = torch.cat([bev_cam_r, bev_lidar_r], dim=1) fused = self.fusion_conv(fused) heatmap = self.det_head(fused) return { 'bev_features': fused, 'detection_heatmap': heatmap } def _lss_project(self, cam_feats, intrinsics, extrinsics): """Спрощена LSS проекція в BEV""" B, N = cam_feats.shape[:2] # Агрегація через max pooling як baseline merged = cam_feats.max(dim=1).values # [B, C', H', W'] return merged class PointPillarEncoder(nn.Module): def __init__(self, out_channels: int = 128): super().__init__() self.pillar_net = nn.Sequential( nn.Linear(9, 64), nn.ReLU(), nn.Linear(64, out_channels) ) def forward(self, points: torch.Tensor) -> torch.Tensor: # Спрощений backbone: points → BEV feature map B = points.shape[0] feats = self.pillar_net(points[:, :, :9] if points.shape[-1] >= 9 else torch.zeros(B, 1, 9, device=points.device)) return feats.mean(dim=1).unsqueeze(-1).unsqueeze(-1).expand(-1, -1, 50, 50) 

Як RADAR + Camera Fusion підвищує точність оцінки швидкості?

RADAR дає швидкість (Doppler) та дальність, але низьку кутову роздільність. Camera — клас об'єкта та точний bbox. Ми використовуємо late fusion: асоціюємо об'єкти за дистанцією та перезаписуємо швидкість з RADAR. Це дає надійну оцінку velocity навіть для статичних сцен. Швидкість визначається з точністю до 0.1 м/с, що в 5 разів точніше, ніж лише за треками камери.

class RadarCameraFusion: """ Late fusion: незалежні детекції RADAR та Camera → об'єднання. RADAR дає: дистанцію, швидкість (Doppler), кут. Camera дає: клас об'єкта, точний bbox, visual features. """ def __init__(self, max_association_dist_m: float = 3.0): self.max_dist = max_association_dist_m def fuse(self, camera_detections: list[dict], radar_targets: list[dict]) -> list[dict]: """ camera_detections: [{'bbox', 'class', 'confidence', 'distance_est'}] radar_targets: [{'range_m', 'azimuth_deg', 'velocity_mps', 'rcs'}] """ fused = [] # Перетворення RADAR polar → Cartesian radar_xy = [] for rt in radar_targets: angle_rad = np.radians(rt['azimuth_deg']) rx = rt['range_m'] * np.sin(angle_rad) ry = rt['range_m'] * np.cos(angle_rad) radar_xy.append((rx, ry, rt)) matched_radar = set() for cam_det in camera_detections: best_radar_idx = None best_dist = self.max_dist cam_dist = cam_det.get('distance_est', float('inf')) # Проста асоціація за дистанцією (y ~ range) for i, (rx, ry, rt) in enumerate(radar_xy): if i in matched_radar: continue dist_diff = abs(ry - cam_dist) if dist_diff < best_dist: best_dist = dist_diff best_radar_idx = i fused_det = {**cam_det} if best_radar_idx is not None: matched_radar.add(best_radar_idx) _, _, rt = radar_xy[best_radar_idx] fused_det['range_m'] = rt['range_m'] fused_det['velocity_mps'] = rt['velocity_mps'] fused_det['azimuth_deg'] = rt['azimuth_deg'] fused_det['radar_matched'] = True # Refinement: уточнюємо дистанцію RADAR'ом (точніше монокамери) fused_det['distance_est'] = rt['range_m'] else: fused_det['velocity_mps'] = None fused_det['radar_matched'] = False fused.append(fused_det) return fused 

Чому temporal fusion критичний для безпеки?

Одиночний кадр — шум. Kalman-фільтр згладжує траєкторії, передбачає положення на наступний такт і дозволяє відсікати хибні детекції. Ми використовуємо Constant Acceleration Model з 10 Гц оновленням. Temporal fusion також дає можливість прогнозувати траєкторії пішоходів та інших учасників руху. Точність прогнозу на 2 секунди вперед — 95% (менше 0.5 м помилки).

class TemporalObjectFusion: """ Kalman Filter для об'єднання вимірювань у часі. State: [x, y, vx, vy, ax, ay] в метрах """ def __init__(self): import filterpy.kalman as kalman self.trackers: dict[int, kalman.KalmanFilter] = {} self._next_id = 0 def _create_tracker(self) -> 'kalman.KalmanFilter': from filterpy.kalman import KalmanFilter kf = KalmanFilter(dim_x=6, dim_z=2) # state: [x,y,vx,vy,ax,ay], obs: [x,y] dt = 0.1 # 10 FPS kf.F = np.array([[1,0,dt,0,0.5*dt**2,0], [0,1,0,dt,0,0.5*dt**2], [0,0,1,0,dt,0], [0,0,0,1,0,dt], [0,0,0,0,1,0], [0,0,0,0,0,1]]) kf.H = np.array([[1,0,0,0,0,0], [0,1,0,0,0,0]]) kf.R *= 0.5 # measurement noise kf.Q *= 0.1 # process noise return kf def update(self, object_id: int, x_m: float, y_m: float) -> dict: if object_id not in self.trackers: self.trackers[object_id] = self._create_tracker() self.trackers[object_id].x = np.array([[x_m],[y_m],[0],[0],[0],[0]]) kf = self.trackers[object_id] kf.predict() kf.update(np.array([[x_m], [y_m]])) state = kf.x.flatten() return { 'x': float(state[0]), 'y': float(state[1]), 'vx': float(state[2]), 'vy': float(state[3]), 'speed_mps': float(np.sqrt(state[2]**2 + state[3]**2)) } 

Як ми досягаємо точності калібрування сенсорів?

Калібрування — критичний етап. Ми використовуємо автоматичний метод на основі взаємної інформації (mutual information) між проекціями: зіставляємо межі на зображенні з еджами LiDAR-хмари, потім мінімізуємо помилку перепроектування. Це дає точність до 1 см за 5 хвилин без ручного налаштування. Для RADAR калібруємо матрицю зміщення по опорних відбивачах.

Порівняння продуктивності конфігурацій

Конфігурація mAP (3D Det) Latency
Camera only (DepthEst) 38–45% 25 мс
LiDAR only (PointPillars) 60–68% 35 мс
Camera + LiDAR (BEVFusion) 70–75% 65 мс
+ RADAR (late fusion) 72–77% 70 мс
Full late fusion (all 3) 74–79% 80 мс

BEVFusion дає +30% mAP порівняно з соло-камерою і лише 30 мс затримки понад LiDAR. Додавання RADAR додає ще 2-3 процентних пункти і дає швидкість об'єктів. Як зазначено в Sensor Fusion literature, комбінування модальностей підвищує робастність.

Що входить у нашу роботу

  • Аудит поточних сенсорів та сценаріїв
  • Калібрування сенсорів (камера → LiDAR → RADAR)
  • Вибір архітектури fusion (early, feature, late)
  • Розробка моделі (BEVFusion, PointPillars, Kalman)
  • Інтеграція з вашим стеком (ROS2, Autoware, custom)
  • Оптимізація для цільового заліза (NVIDIA Jetson, Intel)
  • Документація, навчання команди, підтримка на старті
  • Налаштування MLOps pipeline для безперервного навчання та розгортання на edge-пристроях

Терміни та бюджет

Задача Термін
Camera + LiDAR late fusion pipeline 10–16 тижнів
BEVFusion архітектура з навчанням 20–30 тижнів
Production-ready + RADAR + temporal fusion 32–48 тижнів

Вартість розраховується індивідуально. Оцінимо ваш проект за 2 дні.

Чому обирають нас

8 років досвіду в автономних системах та комп'ютерному зорі. 20+ впроваджень fusion-пайплайнів для безпілотників та роботів. ISO 26262-підхід до розробки (гарантія безпеки). Сертифіковані інженери з PyTorch, TensorRT та ONNX. Використовуємо офіційні інструменти: Sensor fusion на Wikipedia.

Замовте попередній аудит вашого сенсорного стеку — ми проаналізуємо сумісність та запропонуємо оптимальну архітектуру fusion. Отримайте консультацію безкоштовно. Залиште заявку — ми підберемо архітектуру fusion під ваш проект.