from pathlib import Path from simulator import Simulator from time import sleep from trajectory_drawer import TrajectoryDrawer from visualization import VisualizationManager from yandex_map import YandexMap from vision_chunk import VisionChunk from utility import cv2_to_pil import random import cv2 import matplotlib.pyplot as plt import numpy as np import autopilot def make_global_photo(filename): yandexMap = YandexMap() yandexMap.save_photo(filename) yandexMap.destroy() def get_trajectory_points(bg_img: str) -> list[(float, float)]: trajectoryDrawer = TrajectoryDrawer(bg_img) trajectoryDrawer.show() trajectoryDrawer.wait() points = list(map(lambda p: [p[0] / trajectoryDrawer.img.shape[1], p[1] / trajectoryDrawer.img.shape[0]], trajectoryDrawer.points)) return points def main(): # Скриншот местности # make_global_photo('map.jpg') # Получаем траекторию от пользователя # points = get_trajectory_points('map.jpg') # Trajectory #1 # points = [[np.float64(0.5384504359393909), np.float64(0.4084520767967683)], [np.float64(0.4451750568707629), np.float64(0.38213330305374654)], [np.float64(0.49266070439660997), np.float64(0.2789637099811013)], [np.float64(0.36377108968359656), np.float64(0.3263375027185404)], [np.float64(0.3535955937852008), np.float64(0.4337180995900692)]] # Trajectory #2 # points = [[np.float64(0.29197731306713737), np.float64(0.3452870198135161)], [np.float64(0.33494051797147517), np.float64(0.2010601397017569)], [np.float64(0.39768940934491587), np.float64(0.25369768718780034)], [np.float64(0.4027771572941138), np.float64(0.4158213334448144)], [np.float64(0.2914120077394487), np.float64(0.5547844588079692)]] # Trajectory #3 # points = [[np.float64(0.2755834585641664), np.float64(0.45687862048392835)], [np.float64(0.295934450360958), np.float64(0.5021469113219258)], [np.float64(0.32872215936689997), np.float64(0.4810918923275084)], [np.float64(0.3649017003389739), np.float64(0.5295184360146684)], [np.float64(0.3999506306556705), np.float64(0.49477765467387963)]] # Trajectory #4 # points = [[np.float64(0.42143223310783934), np.float64(0.6663760594783815)], [np.float64(0.4253893704016599), np.float64(0.5537317078582484)], [np.float64(0.5124463908657128), np.float64(0.5621537154560153)], [np.float64(0.5124463908657128), np.float64(0.6684815613778233)], [np.float64(0.42143223310783934), np.float64(0.6663760594783815)]] # Trajectory #5 # points = [[np.float64(0.5983728006743884), np.float64(0.7348048712102382)], [np.float64(0.5966768846913225), np.float64(0.5453097002604814)], [np.float64(0.6345523416464622), np.float64(0.7190136069644251)], [np.float64(0.6402053949233488), np.float64(0.5495207040593649)], [np.float64(0.5983728006743884), np.float64(0.7348048712102382)]] # Trajectory #6 # points = [[np.float64(0.4406526142492536), np.float64(0.28106921188054296)], [np.float64(0.38581799746345413), np.float64(0.2968604761263561)], [np.float64(0.3931669667234066), np.float64(0.353709027411283)], [np.float64(0.4248240650739713), np.float64(0.35265627646156217)], [np.float64(0.40616898926024564), np.float64(0.3179154951207735)]] # Trajectory #7 # points = [[np.float64(0.5491912371654754), np.float64(0.7505961354560512)], [np.float64(0.5537136797869846), np.float64(0.6863783275230781)], [np.float64(0.5017055896396284), np.float64(0.6653233085286606)], [np.float64(0.5520177638039186), np.float64(0.6042637534448503)], [np.float64(0.5593667330638712), np.float64(0.516885424618018)]] # Trajectory #8 # points = # Trajectory #9 # points = # Trajectory #10 # points = print(points) # Для каждой точки сделаем приближенный снимок yandexMap = YandexMap() chunks: list[VisionChunk] = [] plt.ion() for i in range(len(points)): point = points[i] yandexMap.scroll(point[0], point[1], 5, True) sleep(1) cv2_img = yandexMap.make_screenshot(point[0], point[1], 0.2, 0.2) img = cv2_to_pil(cv2_img) chunk = VisionChunk(img) Path('chunks').mkdir(exist_ok=True) chunk.save_image(Path('.') / 'chunks' / f'chunk_{i}.png') plt.subplot(1, len(points), i+1) plt.imshow(img) plt.pause(0.25) yandexMap.scroll(point[0], point[1], 5, False) plt.tight_layout() # Выделим на каждой картинке ключевые точки for i in range(len(points)): chunk = VisionChunk.load_image(Path('chunks') / f'chunk_{i}.png') chunks.append(chunk) kp, des = chunk.compute_keypoints() plt.subplot(1, len(points), i+1) plt.imshow(chunk.image) kp_coords = np.array([j.pt for j in kp]) if len(kp_coords) > 0: plt.scatter(kp_coords[:, 0], kp_coords[:, 1], c='red', s=20, alpha=0.7, marker='o') plt.pause(0.2) plt.ioff() plt.show(block=True) # Начнём симуляцию полёта с первой точки yandexMap.scroll(points[0][0], points[0][1], 5, True) sleep(0.2) yandexMap.make_as_center(*points[0]) sleep(1) vis_manager = VisualizationManager() width, height = yandexMap.get_size() # print(width, height) points_coords = np.array(list(map(lambda p: [ (p[0] - points[0][0]) * width, (points[0][1] - p[1]) * height ], points))) points_coords *= 2 ** 4 pilot = autopilot.AutoPilot(points_coords, chunks, vis_manager) simulator = Simulator(yandexMap) pilot.target_idx = 0 chunk = simulator.get_chunk() command = pilot.handle(chunk) vis_manager.update_display() vis_manager.pause(1) vis_manager.set_target_points(points_coords) proc_time = np.array([]) zoom_next_event = random.randint(5, 10) errors = [] chunk_errors = [] chunk_improves = [] last_chunk_index = 0 for i in range(10000000000): print(f"Image #{i}") if i == zoom_next_event: r = random.randint(0, 1) direction = ['up', 'down'][r] simulator.change_zoom(direction) zoom_next_event = i + random.randint(20, 40) chunk = simulator.get_chunk() command = pilot.handle(chunk) proc_time = np.append(proc_time, command.proccessing_time) # Save Image chunk.save_image(Path('images') / f"photo_{i}.png") vis_manager.update_display() vis_manager.pause(0.2) vis_manager.set_target_index(pilot.target_idx) vis_manager.update_drone_trajectory(pilot.geo.x, pilot.geo.y) vis_manager.update_global_map(simulator.geo.x, simulator.geo.y) vis_manager.update_error_plot(i, pilot.geo.x, pilot.geo.y, simulator.geo.x, simulator.geo.y) errors.append(np.hypot(pilot.geo.x - simulator.geo.x, pilot.geo.y - simulator.geo.y)) if last_chunk_index != pilot.target_idx: last_chunk_index = pilot.target_idx chunk_errors.append(errors[-1]) chunk_improves.append(errors[-1] - errors[max(len(errors) - 2, 0)]) if command.stop: break simulator.handle(command.dangle, command.velocity) vis_manager.update_display() vis_manager.pause(0.2) last_proc_times = proc_time[-10:] print("Average FPS:", 1 / last_proc_times.mean()) print("Errors:", errors) print("MSE:", (np.array(errors) ** 2).mean()) print("RMSE:", (np.array(errors) ** 2).mean() ** 0.5) print("Chunk errors:", chunk_errors) print("Chunk error improves:", chunk_improves) print("Average FPS:", 1 / proc_time.mean()) vis_manager.show_final() if __name__ == "__main__": main() #TODO