feat: main loop

This commit is contained in:
2025-09-22 22:29:51 +03:00
parent afd54c55f0
commit 7a1a4050c8
5 changed files with 214 additions and 82 deletions

View File

@@ -1,8 +1,11 @@
from enum import Enum
import math
import random
import cv2
import numpy as np
from PIL import Image
import math
from visualization import VisualizationManager
random.seed(1)
@@ -13,25 +16,42 @@ class Pilot:
def act(self) -> tuple[float, float] | None: pass
def get_position(self) -> tuple[float, float]: pass
class PilotCommand:
dangle: float
stop: bool
def __init__(self, dangle: float = 0, stop: bool = False):
self.dangle = dangle
self.stop = stop
class AutoPilot(Pilot):
prev_image: np.ndarray | None
# Состояние одометрии
angle: float
x: float # Координата X БПЛА
y: float # Координата Y БПЛА
# Ориентиры
points: list[tuple[float,float]] # Координаты
keypoints: list[any] # Ключевые точки ориентиров
target_idx: int # Текущая целевая метка
# Всякие вспомогательные штуки
prev_image: np.ndarray | None
orb_detector: cv2.ORB
bf_matcher: cv2.BFMatcher
frame_count: int
image_center: tuple # Центр изображения (x, y)
viz_manager: VisualizationManager # Менеджер визуализации (опционально)
vis_manager: VisualizationManager # Менеджер визуализации (опционально)
def __init__(self, viz_manager=None):
def __init__(self, points = [], keypoints = [], viz_manager=None):
self.prev_image = None
self.angle = 0.0
self.x = 0.0
self.y = 0.0
self.frame_count = 0
self.image_center = (0, 0) # Будет обновлено при получении первого изображения
self.viz_manager = viz_manager # Менеджер визуализации
self.vis_manager = viz_manager # Менеджер визуализации
# Инициализация ORB детектора
self.orb_detector = cv2.ORB_create(
@@ -48,7 +68,11 @@ class AutoPilot(Pilot):
# Инициализация матчера для сопоставления ключевых точек
self.bf_matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
def get_position(self):
self.points = points
self.keypoints = keypoints
self.target_idx = 0
def get_position(self) -> tuple[float, float]:
return self.x, self.y
def image_to_numpy(self, image: Image.Image) -> np.ndarray:
@@ -224,9 +248,9 @@ class AutoPilot(Pilot):
return img_matches
def handle(self, image: Image):
def handle(self, image: Image) -> PilotCommand:
self.frame_count += 1
if self.prev_image is None:
self.prev_image = self.image_to_numpy(image)
# Вычисляем центр изображения
@@ -234,11 +258,11 @@ class AutoPilot(Pilot):
self.image_center = (width // 2, height // 2)
# Обновляем визуализацию детекции
if self.viz_manager:
if self.vis_manager:
kp, _ = self.orb_detector.detectAndCompute(self.prev_image, None)
self.viz_manager.update_detection(self.prev_image, kp)
self.vis_manager.update_detection(self.prev_image, kp)
return
return PilotCommand()
# Конвертируем текущее изображение
current_image = self.image_to_numpy(image)
@@ -260,27 +284,21 @@ class AutoPilot(Pilot):
# Выводим текущее состояние БПЛА
drone_state = self.get_drone_state()
self.viz_manager.update_drone_trajectory(drone_state['x'], drone_state['y'])
self.vis_manager.update_drone_trajectory(drone_state['x'], drone_state['y'])
print(f" [Pilot] Drone Position: ({drone_state['x']:.2f}, {drone_state['y']:.2f})")
print(f" [Pilot] Angle: {drone_state['angle_degrees']:.1f}°")
# Обновляем визуализацию
if self.viz_manager:
if self.vis_manager:
# Обновляем детекцию ключевых точек
self.viz_manager.update_detection(current_image, kp2)
self.vis_manager.update_detection(current_image, kp2)
# Обновляем сопоставление точек
self.viz_manager.update_matches(self.prev_image, current_image,
self.vis_manager.update_matches(self.prev_image, current_image,
kp1, kp2, matches, transformation_info)
# Визуализация (опционально, если нет менеджера визуализации)
if not self.viz_manager:
img_matches = self.visualize_matches(self.prev_image, current_image,
kp1, kp2, matches, transformation_info)
cv2.imshow('Drone Tracking', img_matches)
cv2.waitKey(1)
# Обновляем предыдущее изображение
self.prev_image = current_image
return PilotCommand()
def act(self) -> tuple[float, float] | None:
"""