From 384769dbce96cc78e6bcb24ac002d25ba1d6155d Mon Sep 17 00:00:00 2001 From: russian_proger Date: Sun, 29 Jun 2025 13:38:37 +0300 Subject: [PATCH] ref: split program into classes --- autopilot.py | 50 ++++++++++++++++++++++++++++++++ main.py | 57 +++--------------------------------- random_pilot.py | 56 ----------------------------------- simulator.py | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ test.ipynb | 55 +++++++++++++++++++++++++++++++++++ 5 files changed, 186 insertions(+), 109 deletions(-) create mode 100644 autopilot.py delete mode 100644 random_pilot.py create mode 100644 simulator.py create mode 100644 test.ipynb diff --git a/autopilot.py b/autopilot.py new file mode 100644 index 0000000..3948f73 --- /dev/null +++ b/autopilot.py @@ -0,0 +1,50 @@ +import math +import random +from time import sleep + +import numpy as np + +# from scipy import +from matplotlib import pyplot as plt + +random.seed(1) + +class Pilot: + def __init__(self): pass + def handle(self, image: np.ndarray): pass + def act(self) -> float | None: pass + +class RandomPilot(Pilot): + def __init__(self, velocity: float = 1): + pass + + def act(self) -> float: + return (random.random() - 0.5) * 0.1 + +# def _test(): +# randomPilot = RandomPilot() +# point = [0, 0] +# iter_count = 100 +# points = [point.copy()] + +# for i in range(iter_count): +# dx, dy = randomPilot.step() +# prev_point = point.copy() +# point[0] += dx +# point[1] += dy +# points.append(point.copy()) + +# coords = list(zip(*points)) +# padding = 5 +# plt.axis([ +# min(coords[0]) - padding, max(coords[0]) + padding, +# min(coords[1]) - padding, max(coords[1]) + padding]) + +# for i in range(iter_count): +# plt.plot(coords[0][i:i+2], coords[1][i:i+2], color='#5e5') +# plt.pause(0.05) + +# sleep(1) + +# if __name__ == '__main__': +# _test() \ No newline at end of file diff --git a/main.py b/main.py index 5d0b7cd..cfb4fd7 100644 --- a/main.py +++ b/main.py @@ -1,54 +1,5 @@ -import math -import random -from io import BytesIO -from time import sleep +from autopilot import RandomPilot +from simulator import Simulator -import selenium -from PIL import Image -from selenium import webdriver -from selenium.webdriver.common.by import By -from selenium.webdriver.common.action_chains import ActionChains - -from random_pilot import RandomPilot - -options = webdriver.ChromeOptions() -# options.add_experimental_option("detach", True) -driver = webdriver.Chrome(options) - -driver.get("https://yandex.ru/maps/43/kazan/?ll=49.103814%2C55.794258&z=14") -sleep(2) - -html = driver.find_element(By.TAG_NAME, 'html') -canvas = driver.find_element(By.TAG_NAME, 'canvas') -action = ActionChains(driver) - -# Закрытие левой панели -action.click(driver.find_element(By.CLASS_NAME, 'sidebar-toggle-button')) -action.move_to_element_with_offset(driver.find_element(By.XPATH, "//div[@class='rounded-controls']/div[@class='rounded-controls__child'][5]//button"), 5, 5) -action.perform() - -# Режим спутника -action.click(driver.find_element(By.CLASS_NAME, '_key_satellite')) -action.perform() - - -randomPilot = RandomPilot(100) - -for i in range(100): - # Сдвиг камеры - action = ActionChains(driver) - action.move_to_element_with_offset(html, 200, 200) - action.click_and_hold() - dx, dy = randomPilot.step() - action.move_by_offset(-dx, dy) - action.release() - action.perform() - - # Загрузка скриншота - png = driver.get_screenshot_as_png() - im = Image.open(BytesIO(png)) - im = im.crop([0, 80, im.width-80, im.height-60]) - im.save(f"./images/{i}.png") - sleep(0.25) - -print("last position: ", driver.current_url) +simulator = Simulator(RandomPilot(), RandomPilot()) +simulator.loop() diff --git a/random_pilot.py b/random_pilot.py deleted file mode 100644 index 3058c6a..0000000 --- a/random_pilot.py +++ /dev/null @@ -1,56 +0,0 @@ -import math -import random -from time import sleep - -# from scipy import -from matplotlib import pyplot as plt - -random.seed(1) - -class RandomPilot(): - angle: float - - def __init__(self, velocity: float = 1): - self.dangle = 0 - self.angle = random.random() * math.pi * 2 - self.velocity = velocity - - def step(self) -> tuple[float, float]: - # Поворот угла траектории - self.dangle += (random.random() - 0.5) * 0.1 - self.dangle = max(min(self.dangle, 0.2), -0.2) - self.angle += self.dangle - - dx = math.cos(self.angle) * self.velocity - dy = math.sin(self.angle) * self.velocity - - return dx, dy - -def _test(): - randomPilot = RandomPilot() - point = [0, 0] - iter_count = 100 - points = [point.copy()] - - for i in range(iter_count): - dx, dy = randomPilot.step() - prev_point = point.copy() - point[0] += dx - point[1] += dy - points.append(point.copy()) - - coords = list(zip(*points)) - padding = 5 - plt.axis([ - min(coords[0]) - padding, max(coords[0]) + padding, - min(coords[1]) - padding, max(coords[1]) + padding]) - - for i in range(iter_count): - plt.plot(coords[0][i:i+2], coords[1][i:i+2], color='#5e5') - plt.pause(0.05) - - - sleep(1) - -if __name__ == '__main__': - _test() \ No newline at end of file diff --git a/simulator.py b/simulator.py new file mode 100644 index 0000000..8477837 --- /dev/null +++ b/simulator.py @@ -0,0 +1,77 @@ +import math +from io import BytesIO +from time import sleep + +from PIL import Image +from selenium import webdriver +from selenium.webdriver.common.by import By +from selenium.webdriver.common.action_chains import ActionChains + +from autopilot import Pilot + +from enum import Enum + +class SimMode(Enum): + OPERATOR = 1 + AUTONOME = 2 + +class Simulator: + driver: webdriver.Chrome + mode: SimMode + + operatorPilot: Pilot + autonomePilot: Pilot + + angle: float + + def __init__(self, operatorPilot: Pilot, autonomePilot: Pilot): + self.mode = SimMode.OPERATOR + self.operatorPilot = operatorPilot + self.autonomePilot = autonomePilot + + options = webdriver.ChromeOptions() + # options.add_experimental_option("detach", True) + self.driver = webdriver.Chrome(options) + self.driver.get("https://yandex.ru/maps/43/kazan/?ll=49.103814%2C55.794258&z=14") + sleep(2) + + action = ActionChains(self.driver) + + # Закрытие левой панели + action.click(self.driver.find_element(By.CLASS_NAME, 'sidebar-toggle-button')) + action.move_to_element_with_offset(self.driver.find_element(By.XPATH, "//div[@class='rounded-controls']/div[@class='rounded-controls__child'][5]//button"), 5, 5) + action.perform() + + # Режим спутника + action.click(self.driver.find_element(By.CLASS_NAME, '_key_satellite')) + action.perform() + + self.angle = 0 + + def loop(self): + + html = self.driver.find_element(By.TAG_NAME, 'html') + action = ActionChains(self.driver) + velocity = 10 + + for i in range(100): + # Сдвиг камеры + action = ActionChains(self.driver) + action.move_to_element_with_offset(html, 200, 200) + action.click_and_hold() + dangle = self.operatorPilot.act() + self.angle += dangle + dx = math.cos(self.angle) * velocity + dy = math.sin(self.angle) * velocity + action.move_by_offset(-dx, dy) + action.release() + action.perform() + + # Загрузка скриншота + png = self.driver.get_screenshot_as_png() + im = Image.open(BytesIO(png)) + im = im.crop([0, 80, im.width-80, im.height-60]) + im.save(f"./images/{i}.png") + sleep(0.25) + + print("last position: ", self.driver.current_url) diff --git a/test.ipynb b/test.ipynb new file mode 100644 index 0000000..505f655 --- /dev/null +++ b/test.ipynb @@ -0,0 +1,55 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "100.00078395707533 -0.0007839570753276348\n" + ] + } + ], + "source": [ + "h = 100\n", + "R = 6378 * 1000\n", + "\n", + "def solve_x2(a, b, c):\n", + " d = b ** 2 - 4 * a * c\n", + " x1 = (-b - d ** 0.5) / (2 * a)\n", + " x2 = (-b + d ** 0.5) / (2 * a)\n", + " return x1, x2\n", + "\n", + "x1, x2 = solve_x2(2, -2 * (h + R), 2 * h * R + h ** 2)\n", + "\n", + "y = h - x1\n", + "\n", + "print(x1, y)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.13.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}