feat: split build into markup and build.
This commit is contained in:
86
README.md
86
README.md
@@ -27,10 +27,13 @@ python main.py --mode standalone --name test_route
|
|||||||
Можно выполнить шаги отдельно:
|
Можно выполнить шаги отдельно:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
|
python main.py --mode markup --name test_route
|
||||||
python main.py --mode build --name test_route
|
python main.py --mode build --name test_route
|
||||||
python main.py --mode run --name test_route
|
python main.py --mode run --name test_route
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`markup` только скачивает карту и сохраняет разметку маршрута. `build` наполняет маршрут chunks и служебными данными. Если при `build` папки маршрута ещё нет, сначала автоматически выполнится разметка, затем наполнение. `standalone` выполняет весь путь: разметка, build и run.
|
||||||
|
|
||||||
Дополнительно можно указать координаты и карты:
|
Дополнительно можно указать координаты и карты:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
@@ -39,7 +42,7 @@ python main.py --mode standalone --name test_route --lat 49.103814 --lon 55.7942
|
|||||||
|
|
||||||
## Флаги
|
## Флаги
|
||||||
|
|
||||||
- `--mode` - режим работы: `standalone`, `build`, `run`.
|
- `--mode` - режим работы: `standalone`, `markup`, `build`, `run`.
|
||||||
- `--name` - название маршрута.
|
- `--name` - название маршрута.
|
||||||
- `--lat`, `--lon` - координаты начальной области.
|
- `--lat`, `--lon` - координаты начальной области.
|
||||||
- `--reference` - карта для эталонных изображений: `google` или `yandex`.
|
- `--reference` - карта для эталонных изображений: `google` или `yandex`.
|
||||||
@@ -49,19 +52,27 @@ python main.py --mode standalone --name test_route --lat 49.103814 --lon 55.7942
|
|||||||
- `--debug-landmark` - вывести отладку ориентиров.
|
- `--debug-landmark` - вывести отладку ориентиров.
|
||||||
- `--use-sian-similarity` - выбирать ориентир через SiaN Similarity.
|
- `--use-sian-similarity` - выбирать ориентир через SiaN Similarity.
|
||||||
- `--use-gan` - преобразовывать эталонные изображения через GAN.
|
- `--use-gan` - преобразовывать эталонные изображения через GAN.
|
||||||
|
- `--no-landmarks` - отключить эталоны и лететь только по межкадровой одометрии.
|
||||||
- `--interframe-method` - метод межкадрового сравнения: `optical-flow`, `orb`, `akaze`, `sift`, `brisk`.
|
- `--interframe-method` - метод межкадрового сравнения: `optical-flow`, `orb`, `akaze`, `sift`, `brisk`.
|
||||||
- `--landmark-method` - метод сравнения с эталонами: `orb`, `akaze`, `sift`, `brisk`.
|
- `--landmark-method` - метод сравнения с эталонами: `orb`, `akaze`, `sift`, `brisk`.
|
||||||
|
|
||||||
## Автоматические серии запусков
|
## Автоматические серии запусков
|
||||||
|
|
||||||
Для прогона уже построенных маршрутов с разными параметрами:
|
`run_batch.ps1` запускает серию экспериментов по уже построенным маршрутам. Скрипт не делает ручную разметку: маршруты должны быть заранее подготовлены через `markup` и `build`, либо через `standalone`. Каждый запуск вызывает `python main.py --mode run ...`, а результаты сохраняются обычным способом в `test_runs`.
|
||||||
|
|
||||||
|
Минимальный запуск для одного маршрута:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
.\run_batch.ps1 -Routes test_route -SimulationMaps yandex,google -InterframeMethods optical-flow,orb,akaze -LandmarkMethods orb,sift -RefMinDistances 75,100
|
.\run_batch.ps1 -Routes test_route
|
||||||
```
|
```
|
||||||
|
|
||||||
Если `-Routes` не указан, скрипт запустит все маршруты из `trajectories`.
|
Если `-Routes` не указан, скрипт запустит все маршруты из `trajectories`, у которых есть `positions.pkl`:
|
||||||
Маршруты можно указать списком:
|
|
||||||
|
```powershell
|
||||||
|
.\run_batch.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
Несколько маршрутов можно указать через запятую:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
.\run_batch.ps1 -Routes 2026-05-31_15-32-53,2026-05-31_15-21-17
|
.\run_batch.ps1 -Routes 2026-05-31_15-32-53,2026-05-31_15-21-17
|
||||||
@@ -73,8 +84,73 @@ python main.py --mode standalone --name test_route --lat 49.103814 --lon 55.7942
|
|||||||
.\run_batch.ps1 -RouteListPath .\routes.txt
|
.\run_batch.ps1 -RouteListPath .\routes.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Пример `routes.txt`:
|
||||||
|
|
||||||
|
```text
|
||||||
|
2026-05-31_15-32-53
|
||||||
|
2026-05-31_15-21-17
|
||||||
|
# строки с комментариями игнорируются
|
||||||
|
```
|
||||||
|
|
||||||
|
Прогон разных методов межкадрового сравнения:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\run_batch.ps1 `
|
||||||
|
-Routes test_route `
|
||||||
|
-InterframeMethods optical-flow,orb,akaze,sift,brisk `
|
||||||
|
-LandmarkMethods orb
|
||||||
|
```
|
||||||
|
|
||||||
|
Прогон разных методов эталонов:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\run_batch.ps1 `
|
||||||
|
-Routes test_route `
|
||||||
|
-InterframeMethods optical-flow `
|
||||||
|
-LandmarkMethods orb,akaze,sift,brisk
|
||||||
|
```
|
||||||
|
|
||||||
|
Прогон с эталонами и без эталонов:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\run_batch.ps1 `
|
||||||
|
-Routes test_route `
|
||||||
|
-UseLandmarksValues true,false
|
||||||
|
```
|
||||||
|
|
||||||
|
Полная матрица экспериментов:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
.\run_batch.ps1 `
|
||||||
|
-Routes test_route `
|
||||||
|
-SimulationMaps yandex,google `
|
||||||
|
-InterframeMethods optical-flow,orb,akaze `
|
||||||
|
-LandmarkMethods orb,sift `
|
||||||
|
-UseLandmarksValues true,false `
|
||||||
|
-UseSianSimilarityValues false,true `
|
||||||
|
-UseGanValues false,true `
|
||||||
|
-RefMinDistances 75,100
|
||||||
|
```
|
||||||
|
|
||||||
Для проверки команд без запуска Selenium:
|
Для проверки команд без запуска Selenium:
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
.\run_batch.ps1 -DryRun
|
.\run_batch.ps1 -DryRun
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Флаги `run_batch.ps1`
|
||||||
|
|
||||||
|
| Флаг | Описание | Пример |
|
||||||
|
|---|---|---|
|
||||||
|
| `-Routes` | Список имён маршрутов из `trajectories`. Можно через запятую. | `-Routes route1,route2` |
|
||||||
|
| `-RouteListPath` | Путь к txt-файлу со списком маршрутов, по одному на строку. | `-RouteListPath .\routes.txt` |
|
||||||
|
| `-SimulationMaps` | Карты, на которых выполнять симуляцию. | `-SimulationMaps yandex,google` |
|
||||||
|
| `-InterframeMethods` | Методы межкадрового сравнения. | `-InterframeMethods optical-flow,orb,sift` |
|
||||||
|
| `-LandmarkMethods` | Методы сравнения с эталонами. | `-LandmarkMethods orb,akaze,brisk` |
|
||||||
|
| `-UseLandmarksValues` | Использовать эталоны или лететь только по межкадровой одометрии. | `-UseLandmarksValues true,false` |
|
||||||
|
| `-UseSianSimilarityValues` | Включать выбор эталона через SiaN Similarity. | `-UseSianSimilarityValues false,true` |
|
||||||
|
| `-UseGanValues` | Включать GAN-преобразование эталонных изображений. | `-UseGanValues false,true` |
|
||||||
|
| `-RefMinDistances` | Минимальное расстояние между загружаемыми эталонами. | `-RefMinDistances 50,100,150` |
|
||||||
|
| `-UseSianSimilarity` | Быстрый вариант `-UseSianSimilarityValues true`. | `-UseSianSimilarity` |
|
||||||
|
| `-UseGan` | Быстрый вариант `-UseGanValues true`. | `-UseGan` |
|
||||||
|
| `-DryRun` | Только напечатать команды, не запускать Selenium и симуляцию. | `-DryRun` |
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ class AutoPilot(Pilot):
|
|||||||
use_gan: bool = False,
|
use_gan: bool = False,
|
||||||
interframe_method: str = "optical_flow",
|
interframe_method: str = "optical_flow",
|
||||||
landmark_method: str = "orb",
|
landmark_method: str = "orb",
|
||||||
|
use_landmarks: bool = True,
|
||||||
):
|
):
|
||||||
self.prev_chunk = None
|
self.prev_chunk = None
|
||||||
self.pos = Position(0, 0, 1, 0, 0, 0)
|
self.pos = Position(0, 0, 1, 0, 0, 0)
|
||||||
@@ -86,6 +87,7 @@ class AutoPilot(Pilot):
|
|||||||
self.pixel_ratio = pixel_ratio
|
self.pixel_ratio = pixel_ratio
|
||||||
self.use_sian_similarity = use_sian_similarity
|
self.use_sian_similarity = use_sian_similarity
|
||||||
self.use_gan = use_gan
|
self.use_gan = use_gan
|
||||||
|
self.use_landmarks = use_landmarks
|
||||||
if interframe_method not in INTERFRAME_METHODS:
|
if interframe_method not in INTERFRAME_METHODS:
|
||||||
raise ValueError(f"Unsupported interframe method: {interframe_method}")
|
raise ValueError(f"Unsupported interframe method: {interframe_method}")
|
||||||
if landmark_method not in FEATURE_METHODS:
|
if landmark_method not in FEATURE_METHODS:
|
||||||
@@ -191,7 +193,7 @@ class AutoPilot(Pilot):
|
|||||||
landmark_timer.start()
|
landmark_timer.start()
|
||||||
|
|
||||||
current_chunk = VisionChunk(self.prev_chunk.image, self.landmark_method) if self.prev_chunk is not None else None
|
current_chunk = VisionChunk(self.prev_chunk.image, self.landmark_method) if self.prev_chunk is not None else None
|
||||||
if current_chunk is None or not self.chunks:
|
if not self.use_landmarks or current_chunk is None or not self.chunks:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if self.use_sian_similarity:
|
if self.use_sian_similarity:
|
||||||
@@ -367,7 +369,7 @@ class AutoPilot(Pilot):
|
|||||||
# Пытаемся найти ориентир на картинке:
|
# Пытаемся найти ориентир на картинке:
|
||||||
self.prev_chunk = current_chunk
|
self.prev_chunk = current_chunk
|
||||||
# Для улучшения среднего FPS
|
# Для улучшения среднего FPS
|
||||||
if self.frame_count % 5 == 0:
|
if self.use_landmarks and self.frame_count % 5 == 0:
|
||||||
pos_by_chunk = self.get_position_by_chunk()
|
pos_by_chunk = self.get_position_by_chunk()
|
||||||
if pos_by_chunk is not None:
|
if pos_by_chunk is not None:
|
||||||
self.pos = pos_by_chunk
|
self.pos = pos_by_chunk
|
||||||
|
|||||||
147
main.py
147
main.py
@@ -75,35 +75,87 @@ def move_map_safely(online_map: YandexMap | GoogleMap, dx: float, dy: float, ste
|
|||||||
def normalize_interframe_method(method: str) -> str:
|
def normalize_interframe_method(method: str) -> str:
|
||||||
return "optical_flow" if method == "optical-flow" else method
|
return "optical_flow" if method == "optical-flow" else method
|
||||||
|
|
||||||
def build(name: str, map_name: str, lat: float, lon: float):
|
def get_trajectory_dir(name: str) -> Path:
|
||||||
|
|
||||||
# Создание папки с информацией о маршруте
|
|
||||||
dir = Path('trajectories')
|
dir = Path('trajectories')
|
||||||
if not dir.exists(): dir.mkdir()
|
if not dir.exists(): dir.mkdir()
|
||||||
dir /= name
|
return dir / name
|
||||||
assert not dir.exists()
|
|
||||||
|
def markup(name: str, map_name: str, lat: float, lon: float):
|
||||||
|
dir = get_trajectory_dir(name)
|
||||||
|
assert not dir.exists(), "Маршрут уже существует"
|
||||||
dir.mkdir()
|
dir.mkdir()
|
||||||
dir_chunks = dir / 'chunks'
|
|
||||||
dir_chunks.mkdir()
|
|
||||||
|
|
||||||
make_global_photo('map.jpg', map_name, lat, lon, 15)
|
|
||||||
map_path = dir / 'map.jpg'
|
|
||||||
shutil.copyfile('map.jpg', map_path)
|
|
||||||
|
|
||||||
points = get_trajectory_points(str(map_path))
|
|
||||||
map_zoom = 15
|
map_zoom = 15
|
||||||
flight_zoom = 18
|
flight_zoom = 18
|
||||||
map_pixel_ratio = get_pixel_ratio(map_name, map_zoom)
|
map_pixel_ratio = get_pixel_ratio(map_name, map_zoom)
|
||||||
|
map_path = dir / 'map.jpg'
|
||||||
online_map: YandexMap | GoogleMap = get_map(map_name, lat, lon, map_zoom)
|
online_map: YandexMap | GoogleMap = get_map(map_name, lat, lon, map_zoom)
|
||||||
|
online_map.save_photo(str(map_path))
|
||||||
|
|
||||||
width, height = online_map.get_size()
|
width, height = online_map.get_size()
|
||||||
|
online_map.destroy()
|
||||||
|
|
||||||
|
points = get_trajectory_points(str(map_path))
|
||||||
points_coords = np.array(list(map(lambda p: [
|
points_coords = np.array(list(map(lambda p: [
|
||||||
(p[0] - points[0][0]) * width, (points[0][1] - p[1]) * height
|
(p[0] - points[0][0]) * width, (points[0][1] - p[1]) * height
|
||||||
], points)))
|
], points)))
|
||||||
|
|
||||||
points_coords_pixels = points_coords.copy()
|
points_coords_pixels = points_coords.copy()
|
||||||
points_coords *= online_map.pixel_ratio
|
points_coords *= map_pixel_ratio
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'points': points_coords,
|
||||||
|
'drawn_points': points,
|
||||||
|
'map_image': 'map.jpg',
|
||||||
|
'map_size': (width, height),
|
||||||
|
'map_zero_point': points[0],
|
||||||
|
'map_provider': map_name,
|
||||||
|
'map_zoom': map_zoom,
|
||||||
|
'flight_zoom': flight_zoom,
|
||||||
|
'map_pixel_ratio': map_pixel_ratio,
|
||||||
|
'build_params': {
|
||||||
|
'name': name,
|
||||||
|
'reference': map_name,
|
||||||
|
'lat': lat,
|
||||||
|
'lon': lon,
|
||||||
|
'map_zoom': map_zoom,
|
||||||
|
'flight_zoom': flight_zoom,
|
||||||
|
},
|
||||||
|
'map_extent': make_map_extent(width, height, points[0], map_pixel_ratio),
|
||||||
|
'route_length': calc_polyline_length(points_coords),
|
||||||
|
'route_length_meters': calc_polyline_length(points_coords),
|
||||||
|
'route_length_pixels': calc_polyline_length(points_coords_pixels),
|
||||||
|
}
|
||||||
|
|
||||||
|
with (dir / 'positions.pkl').open('wb') as file:
|
||||||
|
pickle.dump(data, file)
|
||||||
|
|
||||||
|
print(points_coords)
|
||||||
|
print("WRITE POINTS:", points)
|
||||||
|
|
||||||
|
def build(name: str, map_name: str, lat: float, lon: float):
|
||||||
|
dir = get_trajectory_dir(name)
|
||||||
|
if not dir.exists():
|
||||||
|
markup(name, map_name, lat, lon)
|
||||||
|
|
||||||
|
dir_chunks = dir / 'chunks'
|
||||||
|
dir_chunks.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
file_positions = dir / 'positions.pkl'
|
||||||
|
with file_positions.open('rb') as file:
|
||||||
|
data = pickle.load(file)
|
||||||
|
|
||||||
|
build_params = data.get('build_params', {})
|
||||||
|
map_name = data.get('map_provider', build_params.get('reference', map_name))
|
||||||
|
lat = build_params.get('lat', lat)
|
||||||
|
lon = build_params.get('lon', lon)
|
||||||
|
points_coords = data['points']
|
||||||
|
points = data.get('drawn_points')
|
||||||
|
if points is None:
|
||||||
|
points = [data['map_zero_point']]
|
||||||
|
|
||||||
|
map_zoom = data.get('map_zoom', 15)
|
||||||
|
flight_zoom = data.get('flight_zoom', 18)
|
||||||
|
online_map: YandexMap | GoogleMap = get_map(map_name, lat, lon, map_zoom)
|
||||||
|
|
||||||
# Начнём симуляцию полёта с первой точки
|
# Начнём симуляцию полёта с первой точки
|
||||||
online_map.make_as_center(*points[0])
|
online_map.make_as_center(*points[0])
|
||||||
@@ -158,17 +210,13 @@ def build(name: str, map_name: str, lat: float, lon: float):
|
|||||||
simulator.pos.y = 0
|
simulator.pos.y = 0
|
||||||
sleep(1.5)
|
sleep(1.5)
|
||||||
|
|
||||||
data = {
|
data.update({
|
||||||
'points': points_coords,
|
'points': points_coords,
|
||||||
'chunk_positions': positions,
|
'chunk_positions': positions,
|
||||||
'initial_geolocation': geo,
|
'initial_geolocation': geo,
|
||||||
'map_image': 'map.jpg',
|
|
||||||
'map_size': (width, height),
|
|
||||||
'map_zero_point': points[0],
|
|
||||||
'map_provider': map_name,
|
'map_provider': map_name,
|
||||||
'map_zoom': map_zoom,
|
'map_zoom': map_zoom,
|
||||||
'flight_zoom': flight_zoom,
|
'flight_zoom': flight_zoom,
|
||||||
'map_pixel_ratio': map_pixel_ratio,
|
|
||||||
'flight_pixel_ratio': online_map.pixel_ratio,
|
'flight_pixel_ratio': online_map.pixel_ratio,
|
||||||
'build_params': {
|
'build_params': {
|
||||||
'name': name,
|
'name': name,
|
||||||
@@ -178,18 +226,13 @@ def build(name: str, map_name: str, lat: float, lon: float):
|
|||||||
'map_zoom': map_zoom,
|
'map_zoom': map_zoom,
|
||||||
'flight_zoom': flight_zoom,
|
'flight_zoom': flight_zoom,
|
||||||
},
|
},
|
||||||
'map_extent': make_map_extent(width, height, points[0], map_pixel_ratio),
|
|
||||||
'route_length': calc_polyline_length(points_coords),
|
|
||||||
'route_length_meters': calc_polyline_length(points_coords),
|
|
||||||
'route_length_pixels': calc_polyline_length(points_coords_pixels),
|
|
||||||
'build_flight_length': calc_polyline_length([[pos.x, pos.y] for pos in positions]),
|
'build_flight_length': calc_polyline_length([[pos.x, pos.y] for pos in positions]),
|
||||||
'build_flight_length_meters': calc_polyline_length([[pos.x, pos.y] for pos in positions]),
|
'build_flight_length_meters': calc_polyline_length([[pos.x, pos.y] for pos in positions]),
|
||||||
'build_flight_length_pixels': calc_polyline_length([[pos.x / online_map.pixel_ratio, pos.y / online_map.pixel_ratio] for pos in positions]),
|
'build_flight_length_pixels': calc_polyline_length([[pos.x / online_map.pixel_ratio, pos.y / online_map.pixel_ratio] for pos in positions]),
|
||||||
}
|
})
|
||||||
|
|
||||||
print(points_coords)
|
print(points_coords)
|
||||||
|
|
||||||
file_positions = dir / 'positions.pkl'
|
|
||||||
with file_positions.open('wb') as file:
|
with file_positions.open('wb') as file:
|
||||||
pickle.dump(data, file)
|
pickle.dump(data, file)
|
||||||
|
|
||||||
@@ -206,6 +249,7 @@ def run(
|
|||||||
use_gan: bool = False,
|
use_gan: bool = False,
|
||||||
interframe_method: str = "optical_flow",
|
interframe_method: str = "optical_flow",
|
||||||
landmark_method: str = "orb",
|
landmark_method: str = "orb",
|
||||||
|
use_landmarks: bool = True,
|
||||||
run_params: dict | None = None,
|
run_params: dict | None = None,
|
||||||
):
|
):
|
||||||
dir = Path('trajectories')
|
dir = Path('trajectories')
|
||||||
@@ -218,6 +262,8 @@ def run(
|
|||||||
|
|
||||||
with file_positions.open('rb') as file:
|
with file_positions.open('rb') as file:
|
||||||
data = pickle.load(file)
|
data = pickle.load(file)
|
||||||
|
|
||||||
|
assert 'initial_geolocation' in data, "Маршрут размечен, но не наполнен chunks. Сначала запустите --mode build."
|
||||||
|
|
||||||
initial_geolocation = data['initial_geolocation']
|
initial_geolocation = data['initial_geolocation']
|
||||||
|
|
||||||
@@ -227,15 +273,16 @@ def run(
|
|||||||
sleep(2)
|
sleep(2)
|
||||||
|
|
||||||
chunks: list[VisionChunk] = []
|
chunks: list[VisionChunk] = []
|
||||||
for i in range(len(data['chunk_positions'])):
|
if use_landmarks:
|
||||||
pos = data['chunk_positions'][i]
|
for i in range(len(data['chunk_positions'])):
|
||||||
chunk_path = dir_chunks / f"chunk_{i}.png"
|
pos = data['chunk_positions'][i]
|
||||||
if not chunk_path.exists():
|
chunk_path = dir_chunks / f"chunk_{i}.png"
|
||||||
continue
|
if not chunk_path.exists():
|
||||||
if len(chunks) == 0 or np.hypot(chunks[-1].pos.x - pos.x, chunks[-1].pos.y - pos.y) > ref_min_distance:
|
continue
|
||||||
chunk = VisionChunk.load_image(chunk_path, landmark_method)
|
if len(chunks) == 0 or np.hypot(chunks[-1].pos.x - pos.x, chunks[-1].pos.y - pos.y) > ref_min_distance:
|
||||||
chunk.pos = data['chunk_positions'][i] / online_map.pixel_ratio
|
chunk = VisionChunk.load_image(chunk_path, landmark_method)
|
||||||
chunks.append(chunk)
|
chunk.pos = data['chunk_positions'][i] / online_map.pixel_ratio
|
||||||
|
chunks.append(chunk)
|
||||||
|
|
||||||
r = 0
|
r = 0
|
||||||
for i in range(len(data['points']) - 1):
|
for i in range(len(data['points']) - 1):
|
||||||
@@ -283,6 +330,7 @@ def run(
|
|||||||
use_gan=use_gan,
|
use_gan=use_gan,
|
||||||
interframe_method=interframe_method,
|
interframe_method=interframe_method,
|
||||||
landmark_method=landmark_method,
|
landmark_method=landmark_method,
|
||||||
|
use_landmarks=use_landmarks,
|
||||||
)
|
)
|
||||||
simulator = Simulator(online_map)
|
simulator = Simulator(online_map)
|
||||||
pilot.target_idx = 0
|
pilot.target_idx = 0
|
||||||
@@ -391,6 +439,7 @@ def run(
|
|||||||
'ref_min_distance': ref_min_distance,
|
'ref_min_distance': ref_min_distance,
|
||||||
'use_sian_similarity': use_sian_similarity,
|
'use_sian_similarity': use_sian_similarity,
|
||||||
'use_gan': use_gan,
|
'use_gan': use_gan,
|
||||||
|
'use_landmarks': use_landmarks,
|
||||||
'interframe_method': interframe_method,
|
'interframe_method': interframe_method,
|
||||||
'landmark_method': landmark_method,
|
'landmark_method': landmark_method,
|
||||||
},
|
},
|
||||||
@@ -435,8 +484,8 @@ def parse_args():
|
|||||||
'--mode',
|
'--mode',
|
||||||
type=str,
|
type=str,
|
||||||
required=True,
|
required=True,
|
||||||
choices=['standalone', 'build', 'run'],
|
choices=['standalone', 'markup', 'build', 'run'],
|
||||||
help='Режим работы: standalone, build или run'
|
help='Режим работы: standalone, markup, build или run'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Добавляем опциональный аргумент --name
|
# Добавляем опциональный аргумент --name
|
||||||
@@ -514,6 +563,21 @@ def parse_args():
|
|||||||
help='Преобразовывать эталонный vision_chunk через GAN перед поиском ключевых точек'
|
help='Преобразовывать эталонный vision_chunk через GAN перед поиском ключевых точек'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'--use-landmarks',
|
||||||
|
dest='use_landmarks',
|
||||||
|
action='store_true',
|
||||||
|
default=True,
|
||||||
|
help='Использовать эталоны для коррекции позиции (по умолчанию включено)'
|
||||||
|
)
|
||||||
|
|
||||||
|
parser.add_argument(
|
||||||
|
'--no-landmarks',
|
||||||
|
dest='use_landmarks',
|
||||||
|
action='store_false',
|
||||||
|
help='Не использовать эталоны, лететь только по межкадровой одометрии'
|
||||||
|
)
|
||||||
|
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--interframe-method',
|
'--interframe-method',
|
||||||
type=str,
|
type=str,
|
||||||
@@ -535,8 +599,8 @@ def parse_args():
|
|||||||
# Парсим аргументы
|
# Парсим аргументы
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
# Проверяем, что для build и run указан --name
|
# Проверяем, что для markup, build и run указан --name
|
||||||
if args.mode in ['build', 'run'] and not args.name:
|
if args.mode in ['markup', 'build', 'run'] and not args.name:
|
||||||
parser.error(f"--name обязателен для режима {args.mode}")
|
parser.error(f"--name обязателен для режима {args.mode}")
|
||||||
|
|
||||||
return args
|
return args
|
||||||
@@ -557,6 +621,9 @@ if __name__ == "__main__":
|
|||||||
constants.DEBUG_FPS = args.debug_fps
|
constants.DEBUG_FPS = args.debug_fps
|
||||||
constants.DEBUG_LANDMARK = args.debug_landmark
|
constants.DEBUG_LANDMARK = args.debug_landmark
|
||||||
|
|
||||||
|
if mode == 'markup':
|
||||||
|
markup(name, ref, lat, lon)
|
||||||
|
|
||||||
if mode == 'build' or mode == 'standalone':
|
if mode == 'build' or mode == 'standalone':
|
||||||
build(name, ref, lat, lon)
|
build(name, ref, lat, lon)
|
||||||
|
|
||||||
@@ -569,6 +636,7 @@ if __name__ == "__main__":
|
|||||||
args.use_gan,
|
args.use_gan,
|
||||||
interframe_method,
|
interframe_method,
|
||||||
landmark_method,
|
landmark_method,
|
||||||
|
args.use_landmarks,
|
||||||
{
|
{
|
||||||
'mode': mode,
|
'mode': mode,
|
||||||
'name': name,
|
'name': name,
|
||||||
@@ -581,6 +649,7 @@ if __name__ == "__main__":
|
|||||||
'debug_landmark': args.debug_landmark,
|
'debug_landmark': args.debug_landmark,
|
||||||
'use_sian_similarity': args.use_sian_similarity,
|
'use_sian_similarity': args.use_sian_similarity,
|
||||||
'use_gan': args.use_gan,
|
'use_gan': args.use_gan,
|
||||||
|
'use_landmarks': args.use_landmarks,
|
||||||
'interframe_method': interframe_method,
|
'interframe_method': interframe_method,
|
||||||
'landmark_method': landmark_method,
|
'landmark_method': landmark_method,
|
||||||
},
|
},
|
||||||
|
|||||||
BIN
map.jpg
BIN
map.jpg
Binary file not shown.
|
Before Width: | Height: | Size: 424 KiB After Width: | Height: | Size: 424 KiB |
@@ -4,6 +4,9 @@ param(
|
|||||||
[string[]]$SimulationMaps = @("yandex"),
|
[string[]]$SimulationMaps = @("yandex"),
|
||||||
[string[]]$InterframeMethods = @("optical-flow", "orb", "akaze", "sift", "brisk"),
|
[string[]]$InterframeMethods = @("optical-flow", "orb", "akaze", "sift", "brisk"),
|
||||||
[string[]]$LandmarkMethods = @("orb", "akaze", "sift", "brisk"),
|
[string[]]$LandmarkMethods = @("orb", "akaze", "sift", "brisk"),
|
||||||
|
[string[]]$UseSianSimilarityValues = @("false"),
|
||||||
|
[string[]]$UseGanValues = @("false"),
|
||||||
|
[string[]]$UseLandmarksValues = @("true"),
|
||||||
[double[]]$RefMinDistances = @(100),
|
[double[]]$RefMinDistances = @(100),
|
||||||
[switch]$UseSianSimilarity,
|
[switch]$UseSianSimilarity,
|
||||||
[switch]$UseGan,
|
[switch]$UseGan,
|
||||||
@@ -29,6 +32,29 @@ $Routes = Expand-List $Routes
|
|||||||
$SimulationMaps = Expand-List $SimulationMaps
|
$SimulationMaps = Expand-List $SimulationMaps
|
||||||
$InterframeMethods = Expand-List $InterframeMethods
|
$InterframeMethods = Expand-List $InterframeMethods
|
||||||
$LandmarkMethods = Expand-List $LandmarkMethods
|
$LandmarkMethods = Expand-List $LandmarkMethods
|
||||||
|
$UseSianSimilarityValues = Expand-List $UseSianSimilarityValues
|
||||||
|
$UseGanValues = Expand-List $UseGanValues
|
||||||
|
$UseLandmarksValues = Expand-List $UseLandmarksValues
|
||||||
|
|
||||||
|
if ($UseSianSimilarity) {
|
||||||
|
$UseSianSimilarityValues = @("true")
|
||||||
|
}
|
||||||
|
if ($UseGan) {
|
||||||
|
$UseGanValues = @("true")
|
||||||
|
}
|
||||||
|
|
||||||
|
function Convert-ToBool {
|
||||||
|
param([string]$Value)
|
||||||
|
|
||||||
|
$Normalized = $Value.Trim().ToLowerInvariant()
|
||||||
|
if ($Normalized -in @("true", "1", "yes", "y", "on")) {
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
if ($Normalized -in @("false", "0", "no", "n", "off")) {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
throw "Не удалось распознать boolean значение: $Value"
|
||||||
|
}
|
||||||
|
|
||||||
if ($RouteListPath) {
|
if ($RouteListPath) {
|
||||||
if (-not (Test-Path $RouteListPath)) {
|
if (-not (Test-Path $RouteListPath)) {
|
||||||
@@ -59,7 +85,7 @@ if (-not (Test-Path $Python)) {
|
|||||||
$Python = "python"
|
$Python = "python"
|
||||||
}
|
}
|
||||||
|
|
||||||
$Total = $Routes.Count * $SimulationMaps.Count * $InterframeMethods.Count * $LandmarkMethods.Count * $RefMinDistances.Count
|
$Total = $Routes.Count * $SimulationMaps.Count * $InterframeMethods.Count * $LandmarkMethods.Count * $UseSianSimilarityValues.Count * $UseGanValues.Count * $UseLandmarksValues.Count * $RefMinDistances.Count
|
||||||
$RunIndex = 0
|
$RunIndex = 0
|
||||||
|
|
||||||
Write-Host "Batch run started"
|
Write-Host "Batch run started"
|
||||||
@@ -71,32 +97,45 @@ foreach ($Route in $Routes) {
|
|||||||
foreach ($RefMinDistance in $RefMinDistances) {
|
foreach ($RefMinDistance in $RefMinDistances) {
|
||||||
foreach ($InterframeMethod in $InterframeMethods) {
|
foreach ($InterframeMethod in $InterframeMethods) {
|
||||||
foreach ($LandmarkMethod in $LandmarkMethods) {
|
foreach ($LandmarkMethod in $LandmarkMethods) {
|
||||||
$RunIndex += 1
|
foreach ($UseSianSimilarityValue in $UseSianSimilarityValues) {
|
||||||
$Args = @(
|
foreach ($UseGanValue in $UseGanValues) {
|
||||||
"main.py",
|
foreach ($UseLandmarksValue in $UseLandmarksValues) {
|
||||||
"--mode", "run",
|
$SianEnabled = Convert-ToBool $UseSianSimilarityValue
|
||||||
"--name", $Route,
|
$GanEnabled = Convert-ToBool $UseGanValue
|
||||||
"--simulation", $SimulationMap,
|
$LandmarksEnabled = Convert-ToBool $UseLandmarksValue
|
||||||
"--ref-min-distance", "$RefMinDistance",
|
|
||||||
"--interframe-method", $InterframeMethod,
|
|
||||||
"--landmark-method", $LandmarkMethod
|
|
||||||
)
|
|
||||||
|
|
||||||
if ($UseSianSimilarity) {
|
$RunIndex += 1
|
||||||
$Args += "--use-sian-similarity"
|
$Args = @(
|
||||||
}
|
"main.py",
|
||||||
if ($UseGan) {
|
"--mode", "run",
|
||||||
$Args += "--use-gan"
|
"--name", $Route,
|
||||||
}
|
"--simulation", $SimulationMap,
|
||||||
|
"--ref-min-distance", "$RefMinDistance",
|
||||||
|
"--interframe-method", $InterframeMethod,
|
||||||
|
"--landmark-method", $LandmarkMethod
|
||||||
|
)
|
||||||
|
|
||||||
Write-Host ""
|
if ($SianEnabled) {
|
||||||
Write-Host "[$RunIndex/$Total] route=$Route simulation=$SimulationMap ref=$RefMinDistance interframe=$InterframeMethod landmark=$LandmarkMethod"
|
$Args += "--use-sian-similarity"
|
||||||
Write-Host "$Python $($Args -join ' ')"
|
}
|
||||||
|
if ($GanEnabled) {
|
||||||
|
$Args += "--use-gan"
|
||||||
|
}
|
||||||
|
if (-not $LandmarksEnabled) {
|
||||||
|
$Args += "--no-landmarks"
|
||||||
|
}
|
||||||
|
|
||||||
if (-not $DryRun) {
|
Write-Host ""
|
||||||
& $Python @Args
|
Write-Host "[$RunIndex/$Total] route=$Route simulation=$SimulationMap ref=$RefMinDistance interframe=$InterframeMethod landmark=$LandmarkMethod landmarks=$LandmarksEnabled sian=$SianEnabled gan=$GanEnabled"
|
||||||
if ($LASTEXITCODE -ne 0) {
|
Write-Host "$Python $($Args -join ' ')"
|
||||||
throw "Run failed with exit code $LASTEXITCODE"
|
|
||||||
|
if (-not $DryRun) {
|
||||||
|
& $Python @Args
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw "Run failed with exit code $LASTEXITCODE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user