2026-09-09 16:31:27 +03:00
2026-09-09 16:31:27 +03:00
2026-09-09 16:31:27 +03:00

mvch — подготовка к ЧВТ-2026

Репозиторий для самостоятельного изучения и тренировок по модулям ЧВТ.

  • module2/module_b.py — модуль Б, навигация РМК-2 по ArUco.
  • module3/ — модуль В, датасет и распознавание инструментов.
  • module4/ — модуль Г, веб-FMS для двух роверов на React/Bun.
  • module5/ — модуль Д, единый сценарий RMC1 + RMC2.

Все актуальные модули находятся в main. Ветки module2–module5 сохранены как промежуточные этапы разработки.

Запуск в Ubuntu VM

Нужен установленный официальный симулятор, ROS 2 Jazzy, rclpy, tf2_ros. Дополнительные pip-пакеты и сборка colcon самого решения не нужны.

Терминал 1 — штатный симулятор (один экземпляр):

source /opt/ros/jazzy/setup.bash
source ~/ros2_ws/install/setup.bash
ros2 launch ar_webots_fms_ros2 module2.launch.py

Терминал 2 — решение:

cd ~/mvch
git pull --ff-only
source /opt/ros/jazzy/setup.bash
source ~/ros2_ws/install/setup.bash
python3 module2/module_b.py --target 14 --sim
  1. Робот должен стоять центром над известной меткой. Начальная ориентация любая: она определяется по TF метки. Программа ждёт odometry, lidar, TF и ArUco.
  2. Программа печатает ROUTE. Эксперт фиксирует маршрут; Enter разрешает движение.
  3. После TARGET_REACHED робот стоит. Выставьте препятствие штатным инструментом симулятора.
  4. Enter строит и выводит обратный маршрут с учётом видимого препятствия.
  5. Ещё Enter разрешает возврат. Успех — MISSION_FINISHED.

Если за время подтверждения маршрут изменился, программа покажет новый и снова дождётся Enter. Время паузы между этапами не входит в movement_seconds.

Команды в том же терминале: stop, resume, return, go, quit. Ctrl+C немедленно инициирует остановку и завершение с ненулевым кодом. Для внешнего интерфейса: /mvch/command (std_msgs/String), /mvch/emergency_stop (std_msgs/Bool, true фиксирует стоп), /mvch/status (JSON в std_msgs/String). После потери датчиков программа останавливается и требует resume.

Автоматическая тренировка без подтверждений (только симулятор):

python3 module2/module_b.py --target 14 --sim --auto --return-delay 10

Цель координатами и конечная ориентация, в системе поля:

python3 module2/module_b.py --xy -2 2 --target-yaw 1.57 --sim

На физическом роботе --sim не указывать:

python3 module2/module_b.py --target 14

Тогда используется подтверждённый документацией профиль: поле 5×5 (ID 0–24), ArUco /RMC2/camera_bottom/aruco_id, TF /RMC2/tf и /RMC2/tf_static, габарит RMC2 до 0.870 м. С --sim остаётся прежний профиль Webots 6×6 (ID 0–35), /RMC2/aruco_id и глобальные /tf//tf_static.

Перед физическим заездом всё равно проверить частоту топиков, имена frame_id, шаг сетки, тормозной путь и аппаратную аварийную остановку. Документ не сообщает шаг между маркерами и точные имена TF-фреймов. Испытания в Webots не подтверждают готовность к реальному полю. У штатного Webots-драйвера нет таймаута последней команды: при SIGKILL/обрыве питания процесса программная остановка не гарантируется; остановить симулятор вручную.

Как устроен код

Весь модуль находится в одном файле module2/module_b.py: сверху параметры поля и скоростей, затем геометрия и Дейкстра, ниже ROS-узел, безопасность и логи.

Читайте в таком порядке: Field.route → localize → scan_points → plan → drive → tick.

Координаты реального поля: 0=(0,0), 5=(-1,0), 1=(0,1); в Webots 6×6: 0=(0,0), 6=(-1,0), 1=(0,1). Поворот yaw каждой метки — ориентация её TF-системы относительно поля. Измеренное положение метки в odom сравнивается с её известным положением на поле; так получаем преобразование map_from_odom. Между метками движение идёт по одометрии. У каждой промежуточной точки нужна свежая метка и попадание в допуск; «успех по таймауту» отсутствует.

Лидар переводится через TF с учётом angle_min, angle_increment и времени скана. У текущего симулятора laser_merged повёрнут относительно корпуса на 120°. Планировщик исключает рёбра, проходящие слишком близко к точкам препятствий. Он не знает ID или место будущего препятствия заранее и сам ничего не спавнит. Если преграда появилась во время движения, робот тормозит, возвращается задним ходом к предыдущему маркеру по своему ребру и публикует новый маршрут ROUTE_REPLANNED. Если отступить безопасно нельзя, он стоит и завершает попытку по таймауту.

Профили сетки находятся в REAL_FIELD и SIM_FIELD, известные занятые клетки — в BLOCKED_MARKERS. Все длины — метры.

Проверки и логи

python3 module2/module_b.py --target 14 --dry-run       # реальное поле 5x5
python3 module2/module_b.py --target 35 --sim --dry-run # Webots 6x6

reports/module_b_*.jsonl содержат маршрут, движение, ошибки, препятствия, точность попадания по меткам и время. Логи исключены из Git.

Условия финального КЗ: один запускаемый скрипт решения; маршруты в терминале и файле; явные movement_start / movement_stop; подтверждение эксперта перед каждым этапом. Фактические баллы определяют эксперты по заезду, а не наличие функций в коде.

Обновление VM с хоста

GitHub: git@github.com:mavxa/mvch.git (приватный). Для текущей VM используется локальное зеркало хостового Git без передачи ключей GitHub. На хосте запущен read-only Git daemon только для этого репозитория:

git daemon --reuseaddr --export-all --listen=127.0.0.1 --port=9418 \
  --base-path=/home/mavxa/zed/chvtFinal /home/mavxa/zed/chvtFinal/mvch

В VM с QEMU user networking хост доступен как 10.0.2.2:

git clone --branch module2 git://10.0.2.2:9418/mvch ~/mvch
cd ~/mvch
git pull --ff-only

SSH VM: ssh -p 2222 -o HostKeyAlias=chvt-3735b9fd mavxa@127.0.0.1. Проброс действует до выключения VM. Восстановить на хосте:

virsh -c qemu:///system qemu-monitor-command ubuntu24.04-chvt \
  --hmp 'hostfwd_add hostnet0 tcp:127.0.0.1:2222-:22'

Пароли и ключи в репозитории не хранятся.

S
Description
No description provided
Readme
12 MiB
Languages
Python 81.2%
TypeScript 18.5%
HTML 0.2%
CSS 0.1%