ref: split program into classes

This commit is contained in:
2025-06-29 13:38:37 +03:00
parent 2b529b1448
commit 384769dbce
5 changed files with 186 additions and 109 deletions

50
autopilot.py Normal file
View File

@@ -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()

57
main.py
View File

@@ -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()

View File

@@ -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()

77
simulator.py Normal file
View File

@@ -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)

55
test.ipynb Normal file
View File

@@ -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
}