ref: decomposite geolocation
This commit is contained in:
95
simulator.py
95
simulator.py
@@ -8,6 +8,7 @@ from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.common.action_chains import ActionChains
|
||||
|
||||
from autopilot import Pilot
|
||||
from geolocation import Geolocation
|
||||
from visualization import VisualizationManager, SimMode
|
||||
from yandex_map import YandexMap
|
||||
|
||||
@@ -16,22 +17,17 @@ from PIL import Image
|
||||
import os
|
||||
|
||||
class Simulator:
|
||||
angle: float
|
||||
geo: Geolocation
|
||||
yandexMap: YandexMap
|
||||
|
||||
# Менеджер визуализации
|
||||
viz_manager: VisualizationManager
|
||||
current_x: float
|
||||
current_y: float
|
||||
|
||||
def __init__(self, yandexMap: YandexMap = None):
|
||||
self.yandexMap = yandexMap
|
||||
|
||||
# Инициализация переменных для отслеживания траектории
|
||||
self.angle = 0.0
|
||||
self.current_x = 0.0
|
||||
self.current_y = 0.0
|
||||
self.zoom = 1
|
||||
self.geo = Geolocation(0, 0, 1, 0)
|
||||
|
||||
# Создаем папку для изображений, если её нет
|
||||
os.makedirs('./images', exist_ok=True)
|
||||
@@ -69,14 +65,14 @@ class Simulator:
|
||||
Обновляет траекторию полета беспилотника
|
||||
"""
|
||||
# Обновляем текущие координаты
|
||||
self.current_x += dx * self.zoom
|
||||
self.current_y += dy * self.zoom
|
||||
self.geo.x += dx * self.geo.z
|
||||
self.geo.y += dy * self.geo.z
|
||||
|
||||
def update_map(self):
|
||||
"""
|
||||
Обновляет карту траектории полета
|
||||
"""
|
||||
self.viz_manager.update_global_map(self.current_x, self.current_y, self.mode)
|
||||
self.viz_manager.update_global_map(self.geo.x, self.geo.y, self.mode)
|
||||
|
||||
def handle(self, dangle: float, velocity: float = 50) -> None:
|
||||
""" Сдвиг камеры """
|
||||
@@ -86,11 +82,11 @@ class Simulator:
|
||||
action.move_to_element_with_offset(html, 200, 200)
|
||||
action.click_and_hold()
|
||||
|
||||
self.angle += dangle
|
||||
self.geo.angle += dangle
|
||||
# print(f" [Simulator] angle: {self.angle / math.pi * 180:.1f}°")
|
||||
velocity = max(velocity, 10)
|
||||
dx = math.cos(math.pi / 2 + self.angle) * velocity / self.zoom
|
||||
dy = math.sin(math.pi / 2 + self.angle) * velocity / self.zoom
|
||||
dx = math.cos(math.pi / 2 + self.geo.angle) * velocity / self.geo.z
|
||||
dy = math.sin(math.pi / 2 + self.geo.angle) * velocity / self.geo.z
|
||||
# print(" [Simulator] dx, dy:", [dx, dy])
|
||||
self.update_trajectory(dx, dy)
|
||||
action.move_by_offset(-dx, dy)
|
||||
@@ -103,81 +99,14 @@ class Simulator:
|
||||
self.yandexMap.scroll(0.5, 0.5, 2, direction == 'down')
|
||||
sleep(0.4)
|
||||
if direction == 'down':
|
||||
self.zoom /= 2
|
||||
self.geo.z /= 2
|
||||
else:
|
||||
self.zoom *= 2
|
||||
self.geo.z *= 2
|
||||
|
||||
def get_photo(self) -> Image.Image:
|
||||
png = self.yandexMap.driver.get_screenshot_as_png()
|
||||
im = Image.open(BytesIO(png))
|
||||
|
||||
# Применяем поворот как будто съемка с дрона
|
||||
rotated_im = self.rotate_image_like_drone(im, -self.angle)
|
||||
rotated_im = self.rotate_image_like_drone(im, -self.geo.angle)
|
||||
return rotated_im
|
||||
|
||||
def loop(self):
|
||||
|
||||
html = self.driver.find_element(By.TAG_NAME, 'html')
|
||||
action = ActionChains(self.driver)
|
||||
|
||||
# Добавляем начальную точку в траекторию
|
||||
self.update_trajectory(0, 0)
|
||||
self.viz_manager.update_global_map(self.current_x, self.current_y, self.mode)
|
||||
|
||||
for i in range(1000):
|
||||
signal = None
|
||||
if self.mode == SimMode.OPERATOR:
|
||||
signal = self.operatorPilot.act()
|
||||
if signal is None:
|
||||
self.mode = SimMode.AUTONOME
|
||||
# print("Режим возвращения домой!")
|
||||
|
||||
if self.mode == SimMode.AUTONOME:
|
||||
signal = self.autonomePilot.act()
|
||||
|
||||
if signal is None:
|
||||
break
|
||||
|
||||
dangle, velocity = signal
|
||||
drone_x, drone_y = self.autonomePilot.get_position()
|
||||
self.viz_manager.update_error_plot(i, drone_x, drone_y, self.current_x, self.current_y)
|
||||
|
||||
# Сдвиг камеры
|
||||
action = ActionChains(self.driver)
|
||||
action.move_to_element_with_offset(html, 200, 200)
|
||||
action.click_and_hold()
|
||||
|
||||
self.angle += dangle
|
||||
dx = math.cos(math.pi / 2 + self.angle) * velocity
|
||||
dy = math.sin(math.pi / 2 + self.angle) * velocity
|
||||
action.move_by_offset(-dx, dy)
|
||||
action.release()
|
||||
action.perform()
|
||||
|
||||
# Обновляем траекторию
|
||||
self.update_trajectory(dx, dy)
|
||||
|
||||
# Загрузка скриншота
|
||||
png = self.driver.get_screenshot_as_png()
|
||||
im = Image.open(BytesIO(png))
|
||||
im = im.crop([0, 80, im.width-80, im.height-60])
|
||||
|
||||
# Применяем поворот как будто съемка с дрона
|
||||
rotated_im = self.rotate_image_like_drone(im, math.pi / 2 - self.angle)
|
||||
|
||||
# Передаем изображение в AutoPilot для анализа
|
||||
self.autonomePilot.handle(rotated_im)
|
||||
|
||||
# Обновляем визуализацию каждые несколько итераций для производительности
|
||||
self.update_map()
|
||||
self.viz_manager.update_display()
|
||||
|
||||
# Финальное обновление карты
|
||||
self.update_map()
|
||||
self.viz_manager.update_display()
|
||||
print("last position: ", self.driver.current_url)
|
||||
print(f"Финальная позиция: ({self.current_x:.2f}, {self.current_y:.2f})")
|
||||
|
||||
# Показываем карту до закрытия, но не поднимаем на передний план
|
||||
self.viz_manager.show_final()
|
||||
print("Симуляция завершена. Окно визуализации остается открытым для анализа.")
|
||||
|
||||
Reference in New Issue
Block a user