טיסה דרך מנהרה, בין מבנים, בתוך מחסן, או תחת שיבושי GPS — מצב סטנדרטי שבו GPS נועל 2 לוויינים או אפס. ללא מיקום חיצוני, הרחפן חווה סחיפה ופגיעות תוך 10 שניות. זה קריטי במיוחד עבור כלי טיס מסחריים יקרים. אנו פותרים משימות כאלה כמעט בכל פרויקט שני, מבדיקת גשרים ועד לוגיסטיקה במחסנים של 10,000 מ"ר. ניווט הרחפן האוטונומי המופעל על ידי AI שלנו משלב אודומטריה ויזואלית-אינרציאלית, הימנעות מהתנגשויות ו-SLAM. אנו בונים מערכות רחפן לניווט עצמי במפתח מלא — מבחירת חיישנים ועד תוכנה סובלנית לתקלות. נבחן את המשימה שלך תוך 3 ימי עסקים.
מדוע אודומטריה ויזואלית-אינרציאלית חיונית לטיסה ללא GPS
VIO ממזגת נתוני מצלמה עם קריאות IMU. המצלמה מספקת נקודות ציון ויזואליות, ה-IMU מספק מהירויות זוויתיות ותאוצות. אלגוריתם (למשל, VINS-Mono או ORB-SLAM3) ממטב את השגיאה המשותפת באמצעות הערכת תנוחה עם שש דרגות חופש (6-DOF) דרך אופטימיזציית bundle adjustment. בפועל, זה מניב דיוק אופקי של 5–15 ס"מ בתאורה טובה. הקוד שלהלן הוא המחשה פשוטה של הלולאה: זיהוי תכונות ORB, התאמתן, שחזור תנועה דרך perspective-n-point (PnP) ומטריצה אסential, ושילוב עם IMU באמצעות פילטר קלמן מורחב.
import numpy as np
import cv2
from scipy.spatial.transform import Rotation
class VisualInertialOdometry:
"""
VINS-Mono / ORB-SLAM3 логика — упрощённо.
На практике используем готовые библиотеки с ROS2 интеграцией.
"""
def __init__(self, camera_matrix: np.ndarray, imu_noise: dict):
self.K = camera_matrix
self.orb = cv2.ORB_create(nfeatures=500)
self.matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
self.prev_frame = None
self.prev_kp = None
self.prev_desc = None
# Состояние: позиция + ориентация
self.position = np.zeros(3)
self.rotation = np.eye(3)
self.imu_noise = imu_noise
def update(self, frame: np.ndarray, imu_data: dict) -> dict:
"""Обновление оценки позиции по кадру + IMU"""
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
kp, desc = self.orb.detectAndCompute(gray, None)
if self.prev_frame is not None and desc is not None:
matches = self.matcher.match(self.prev_desc, desc)
matches = sorted(matches, key=lambda x: x.distance)[:100]
if len(matches) > 20:
pts1 = np.float32([self.prev_kp[m.queryIdx].pt for m in matches])
pts2 = np.float32([kp[m.trainIdx].pt for m in matches])
E, mask = cv2.findEssentialMat(pts1, pts2, self.K, method=cv2.RANSAC, prob=0.999, threshold=1.0)
if E is not None:
_, R, t, _ = cv2.recoverPose(E, pts1, pts2, self.K)
# Интеграция движения
self.position += self.rotation @ t.flatten()
self.rotation = R @ self.rotation
self.prev_frame = gray
self.prev_kp = kp
self.prev_desc = desc if desc is not None else self.prev_desc
return {
'position': self.position.copy(),
'rotation': self.rotation.copy(),
'tracked_features': len(kp) if kp else 0
}
איך להימנע ממכשולים ללא LiDAR?
לטיסות פנים, מצלמת סטריאו (Intel RealSense D435) מספקת מפת עומק צפופה ב-30 fps וצורכת רק 2 W. LiDAR (למשל, Velodyne Puck) מדויק יותר אך עולה $4000+ ושוקל 400 גרם — לא כל רחפן יכול לשאת אותו. מצלמות סטריאו זולות פי 10 וקלות פי 5 מ-LiDAR, מה שהופך אותן לאידיאליות לרחפנים קלים. המחסנית שלנו משתמשת בסטריאו כחיישן בסיס ומוסיפה אופציונלית מצלמת ToF לשימוש חיצוני. האלגוריתם שלהלן מחלק את שדה הראייה ל-5 מגזרים ומחשב את המרחק המינימלי בכל אחד — מספיק להימנעות מהתנגשויות במהירויות של עד 2 מ"ש.
| חיישן | רזולוציית עומק | טווח | הספק | משקל | עלות |
|---|---|---|---|---|---|
| Intel RealSense D435 | 1280x720 px | עד 10 מ' | 2 W | 72 גרם | $300 |
| Velodyne Puck (LiDAR) | 360° x 30° | עד 100 מ' | 8 W | 400 גרם | $4000 |
| מצלמת ToF (L515) | 1024x768 px | עד 9 מ' | 3 W | 100 גרם | $350 |
class ObstacleAvoidance:
def __init__(self, depth_camera, safety_distance: float = 1.5):
self.depth_cam = depth_camera
self.safety_dist = safety_distance # метры
self.fov_h = 87 # градусов (RealSense D435)
self.sectors = 5 # делим поле зрения на 5 секторов
def compute_clear_directions(self, depth_frame: np.ndarray) -> dict:
"""Находим свободные направления полёта"""
h, w = depth_frame.shape
sector_width = w // self.sectors
clearance = {}
for i in range(self.sectors):
sector = depth_frame[:, i*sector_width:(i+1)*sector_width]
# Игнорируем нулевые значения (нет данных)
valid = sector[sector > 0]
if len(valid) == 0:
clearance[i] = float('inf')
continue
# P10 — ближняя граница препятствия в секторе
min_dist = float(np.percentile(valid, 10)) / 1000.0 # мм -> м
clearance[i] = min_dist
# Направление с максимальным clearance
best_sector = max(clearance, key=clearance.get)
angle = (best_sector - self.sectors // 2) * (self.fov_h / self.sectors)
return {
'clearance_by_sector': clearance,
'best_direction_angle': angle,
'is_path_clear': clearance[self.sectors//2] > self.safety_dist
} תכנון נתיב: רשת תפוסה תלת-ממדית לעומת RRT*
רשת תפוסה היא שיטה דטרמיניסטית: כל תא (0.2 מ"ק) מסומן כפנוי או תפוס. A* מבטיח את הנתיב הקצר ביותר במרחב בדיד. למכשולים דינמיים, RRT* עדיף אך מניב אורך נתיב תת-אופטימלי. רשת תפוסה עם A* היא מהירה פי 2 מ-RRT* למפות סטטיות, בעוד RRT* מטפל במכשולים דינמיים טוב יותר ב-30%. אנו משלבים: בונים את המפה עם רשת voxel, ולתכנון מחדש בזמן אמת משתמשים ב-RRT* עם מגבלה של 100 איטרציות. הקוד שלהלן הוא A* קלאסי על רשת דלילה.
import heapq
class OccupancyGridPlanner:
def __init__(self, resolution: float = 0.2):
self.resolution = resolution # метров на ячейку
self.grid = {} # 3D sparse grid: (ix, iy, iz) -> occupancy
def update_from_depth(self, depth_frame: np.ndarray, camera_pose: np.ndarray):
"""Обновляем карту препятствий"""
# Конвертация depth в point cloud
points = self._depth_to_pointcloud(depth_frame)
# Трансформация в мировые координаты
points_world = (camera_pose[:3, :3] @ points.T).T + camera_pose[:3, 3]
for pt in points_world:
ix, iy, iz = (int(pt[0] / self.resolution), int(pt[1] / self.resolution), int(pt[2] / self.resolution))
self.grid[(ix, iy, iz)] = 1 # occupied
def astar_3d(self, start: tuple, goal: tuple) -> list:
"""A* в 3D occupancy grid"""
def heuristic(a, b):
return np.sqrt(sum((a[i]-b[i])**2 for i in range(3)))
heap = [(0, start)]
came_from = {start: None}
cost = {start: 0}
while heap:
_, current = heapq.heappop(heap)
if current == goal:
break
for dx, dy, dz in [(1,0,0),(-1,0,0),(0,1,0), (0,-1,0),(0,0,1),(0,0,-1)]:
neighbor = (current[0]+dx, current[1]+dy, current[2]+dz)
if self.grid.get(neighbor, 0) == 1:
continue # препятствие
new_cost = cost[current] + 1
if neighbor not in cost or new_cost < cost[neighbor]:
cost[neighbor] = new_cost
priority = new_cost + heuristic(neighbor, goal)
heapq.heappush(heap, (priority, neighbor))
came_from[neighbor] = current
# Восстанавливаем путь
path = []
node = goal
while node is not None:
path.append(node)
node = came_from.get(node)
return list(reversed(path)) מקרה בוחן: בדיקת מחסן אוטונומית (8,000 מ"ר)
הלקוח שלנו, מפעיל לוגיסטי, נזקק לבדיקה חודשית של מדפים ב-4 קומות. מדפים בגובה עד 12 מ', מעברים צרים של 2 מ', והיעדר מוחלט של GPS. פיתחנו רחפן מבוסס DJI F450 עם בקר טיסה מותאם אישית המצויד ב-Intel RealSense D435i (עומק + IMU). המחסנית: ROS2 Humble + PX4 Autopilot + פיצול של ORB-SLAM3 עם פילטר EKF למיזוג ברומטר.
תוצאות: דיוק מיקום ±8 ס"מ אופקי, ±5 ס"מ אנכי. מהירות סקר 0.5 מ"ש, שורת מדפים אחת (50 מ') עוברת ב-110 שניות. המערכת פועלת ללא תקלות כבר למעלה משנה — 50+ משימות. פתרון זה חוסך ללקוח $7,000 לחודש בעלויות בדיקה ידנית.
תהליך היישום
מידע נוסף על כיול חיישנים
כיול מצלמה ו-IMU נעשה באמצעות Kalibr או סקריפט מותאם אישית. נדרשות מספר תנוחות סטטיות עם כיוונים שונים. התוצאה היא מטריצת המצלמה ומקדמי העיוות, וכן מטריצת הסיבוב בין מצלמה ל-IMU. דיוק אופייני לאחר כיול: שגיאת השלכה < 0.5 פיקסלים.- ניתוח תרחיש: מדידת תאורה, גיאומטריה, חומרים (מתכת/בטון — החזריות שונה). בחירת חיישנים.
- אב-טיפוס VIO: כיול מצלמה+IMU, כוונון פרמטרי ORB (מספר תכונות, סף).
- הימנעות מהתנגשות: הגדרת safety_distance, שילוב עומק בבקר הטיסה דרך MAVSDK.
- מתכנן: בחירה בין מפת רשת ל-RRT* בהתאם לדינמיקת המשימה.
- בדיקות: טיסה בסימולציה (Gazebo + PX4 SITL), ולאחר מכן טיסות אמיתיות עם שלט גיבוי.
לוח זמנים ועלות משוערת
| סוג פרויקט | משך | הערה |
|---|---|---|
| ניווט VIO בסיסי | 6–10 שבועות | כולל כיול, בדיקות, בקר טיסה |
| ניווט אוטונומי מלא (VIO + הימנעות ממכשולים + תכנון) | 3–5 חודשים | + רשת Voxel, RRT*, אינטגרציית ROS2 |
| הסמכה לטיסות מסחריות (אופציונלי) | +3–6 חודשים | תלוי ברגולטור (EASA, FAA) |
העלות מחושבת באופן אישי — תלויה במורכבות התרחיש ובמספר איטרציות הבדיקה. עלות פרויקט אופיינית נעה בין $30,000 ל-$100,000. פרויקטים בדרך כלל מחזירים את ההשקעה תוך 6 חודשים בזכות הפחתת עלויות בדיקה ידנית. קבלו ייעוץ — נבחן את המשימה שלך תוך 3 ימים.
מה אתה מקבל
- קוד מקור של מודול VIO עם הערות (Python/C++).
- תמונת Docker עם סביבת ROS2 לשחזוריות.
- קבצי כיול למצלמה ו-IMU.
- אינטגרציה עם בקר טיסה (PX4/ArduPilot).
- תיעוד התקנה ותפעול.
- חודשיים של תמיכה לאחר פריסה.
למה לבחור בפיתוח שלנו?
אנו עובדים על ניווט רחפנים עם AI כבר למעלה מ-5 שנים: 20+ פרויקטים מיושמים למחסנים, מכרות, גשרים ואסדות נפט. אנו משתמשים רק במחסניות קוד פתוח (ORB-SLAM3, ROS2, PX4) — ללא נעילת ספק. כל הפתרונות נבדקים בסימולציה על 100+ תרחישים לפני הטיסה הראשונה. הפתרונות שלנו בדרך כלל מפחיתים עלויות תפעול ב-$5,000–15,000 לחודש. צרו קשר — נספר לכם אילו חיישנים ואלגוריתמים מתאימים למשימה הספציפית שלכם.







