Skip to content
klever-coexPublic

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

clover2-gym

Фреймворк для заданий соревнований по программированию беспилотников на базе PyBullet. Первое задание — motion planner для гоночного дрона: участник получает трассу (ворота: положения, нормали, размеры) и должен выдать траекторию полёта, которая проходит ворота по порядку и не нарушает лимиты модели дрона. Счёт — время круга в симуляции.

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

Участник                       Фреймворк
─────────                      ───────────────────────────────────────────
solve(task) -> Trajectory  →   1. StaticChecker: формат, лимиты (v, тяга,
                                  наклон, рывок), ворота по порядку, клиренсы
                                2. Rollout: PyBullet-заезд со встроенным
                                  tracking-контроллером; ворота/коллизии/
                                  арена проверяются по фактическому полёту
                                3. Счёт = время пересечения последних ворот

Обе стадии читают одни и те же Constraints из yaml трассы, а условие задачи генерируется из того же объекта — правила в условии и в чекере не могут разойтись.

  • Модель дрона — racer.urdf (0.83 кг, thrust-to-weight 4.17, инерция моторов motor_tau = 25 мс). Все параметры в <properties> URDF.
  • Контроллер — геометрический (SE(3)) position→attitude→RPM, один для всех участников; его способность отслеживать траекторию — часть «физики» задания: кинематически идеальная, но агрессивная траектория не пролетится.
  • Траектория — сэмплы позиций (N×3) с равномерным dt ≤ 0.01 c; фреймворк строит по ним сплайн (v(0)=0 — старт с висения), yaw считает сам по касательной к скорости.

Установка

uv sync

Рабочий процесс участника (и отладка)

# 0. посмотреть трассу в GUI (ворота пронумерованы по порядку прохождения)
uv run clover2gym viz --task tracks/track1.yaml

# 1. быстрый чек без симуляции (секунды) — лимиты, ворота, клиренсы
uv run clover2gym check --task tracks/track1.yaml --solution solutions/template_solution.py

# 2. полный прогон с заездом в GUI и живым HUD (время/ворота/скорость/ошибка)
uv run clover2gym run \
    --task tracks/track1.yaml --solution solutions/template_solution.py --gui

# 3. headless-прогон + JSON-отчёт (для CI и сравнения вариантов)
uv run clover2gym run \
    --task tracks/track1.yaml --solution solutions/template_solution.py \
    --out output/report.json --plot output/report.png

# 4. оценка на наборе трасс (скрытый финал считается так же)
uv run clover2gym run-set --task-dir tracks/ --solution solutions/template_solution.py

Отчёт показывает каждое нарушение с временем, значением и лимитом, а PNG — план (зелёный) и факт (красный) сверху и в 3D. Стартовый код — examples/template_solution.py; рабочие референсы — examples/baseline_solution.py (просто и надёжно) и examples/fast_solution.py (лесенка скоростей с проверкой полным конвейером — «спланировал → прогнал → уточнил»).

Формат трассы

Yaml (clover2gym/tasks/tracks/track1.yaml): ворота (center, normal, size, shape: rect|circle), старт, арена, constraints (все лимиты), timing. Тот же файл — «выдача» участнику.

Оценка времени с динамикой и контроллером

.venv/bin/python examples/theoretical_time.py --task tracks/track2.yaml
# Машиночитаемый результат:
.venv/bin/python examples/theoretical_time.py --task tracks/track2.yaml --json
# Без симуляции: повороты, рывок и остальные ограничения StaticChecker:
.venv/bin/python examples/theoretical_time.py --task tracks/track2.yaml --mode dynamics
# Только прежняя оптимистическая нижняя граница:
.venv/bin/python examples/theoretical_time.py --task tracks/track2.yaml --mode lower-bound
# Более широкий независимый поиск и сохранение лучшего допустимого полёта:
.venv/bin/python examples/theoretical_time.py --task tracks/track2.yaml \
    --starts 4 --iterations 120 --controller-trials 64 --trajectory-out /tmp/best-flight.npz
# Только явно выбранная готовая траектория (ограниченный поиск по масштабу):
.venv/bin/python examples/theoretical_time.py --task tracks/track2.yaml \
    --solution examples/planning_solution.py

По умолчанию скрипт строит и оптимизирует траекторию по YAML трека, без загрузки planning_solution.py или другого готового решения. Свободны точки пересечения ворот внутри проёмов, скорости и ускорения в них, а также длительности отдельных участков. Участки задаются полиномами пятой степени с непрерывными позицией, скоростью и ускорением. SLSQP минимизирует время до последних ворот из нескольких начальных приближений, построенных по геометрии трека. После разреженной проверки ограничений сетка сгущается около экстремумов и рамок ворот. Каждый опубликованный допустимый кандидат повторно проверяется StaticChecker на полной траектории: скорость, тяга, наклон, рывок, повороты, направление и порядок ворот, клиренс, арена, старт и хвост. Затем PyBullet проверяет фактический полёт с моделью дрона, динамикой моторов и контроллером, указанными в YAML трассы.

Выводятся отдельно лучшее статически допустимое плановое время и лучшее фактическое время успешного полёта. Неудачные кандидаты не становятся результатом. Если допустимый вариант не найден, скрипт возвращает код 1, а JSON содержит null в соответствующем поле best_static/best_controller. JSON также содержит длительности участков, точки/скорости/ускорения в воротах, статусы нелинейного решателя и отчёты всех проверенных попыток; прогресс идёт в stderr. --starts, --iterations, --probes, --seed управляют независимой оптимизацией. При необходимости выполняются до двух дополнительных этапов сгущения сетки с половиной основного бюджета итераций каждый. --controller-trials ограничивает число дополнительных кандидатов для контроллера: варианты геометрии, замедления, уточнения переходов PASS/FAIL, локальные изменения времени отдельных участков и точек прохода. Исходная модель дрона, контроллер и ограничения трассы не меняются. В .npz сохраняются positions и dt лучшего кандидата выбранного режима.

Найденное допустимое время является верхней оценкой оптимума соответствующей модели. Это локальный численный поиск по выбранному семейству сплайнов: ни статус сходимости, ни число начальных приближений не доказывают глобальный минимум. Например, 17.762 с, найденные прежним масштабированием planning_solution.py, не являются теоретическим пределом трека.

При явно переданном --solution сохраняется прежний ограниченный поиск по общему масштабу времени solve(task). Только в этом режиме используются --samples, --refinements, --scale-min, --scale-max; форма пути и относительное распределение времени исходного решения фиксированы.

Нижняя граница считается отдельно: кратчайшая ломаная через проёмы ворот с gate_margin, двойственная оценка длины с start_tol, лимит v_max и разгон с нулевой скорости. Тяга a_max, гравитация и tilt_max_deg задают оптимистический предел ускорения. Эта упрощённая граница не учитывает динамику поворотов, рывок и контроллер; для tracks/track2.yaml — около 6.170 с. Она не является гарантированной границей счёта PyBullet.

Приёмка трасс (для организаторов)

Каждая трасса (публичная или скрытая) должна проходить измеренную приёмку: baseline проходит, fast-референс быстрее него минимум в 1.3 раза:

.venv/bin/python reference/acceptance.py --task clover2gym/tasks/tracks/track1.yaml
.venv/bin/python reference/acceptance.py --generate --seeds 1 2 3   # сгенерировать и принять

Скрытые трассы генерируются тем же генератором (clover2gym.tasks.generator) по seed'ам, которые не публикуются.

Как добавить новое задание

  1. Описать спецификацию dataclass'ами в clover2gym/tasks/spec.py (+ yaml).
  2. Реализовать solve()-контракт и чекеры под задачу (статика — без pybullet, симуляция — через sim/world.py + sim/rollout.py).
  3. Подключить команды в runner.py; условие генерировать из того же спецификационного объекта (см. statement/).

Тесты

.venv/bin/python -m pytest tests/ -q

Проверяются: сплайн-производные и граничные условия, геометрия ворот (проход/промах/не по нормали), статический чекер на хороших/плохих траекториях, hover-и-полёт в headless-симуляции, детерминизм (два идентичных заезда дают одинаковый лог состояний).

Статус / что дальше

  • Ядро: спецификация, Trajectory, статика+симуляция, скоринг, CLI, графики
  • Два референс-решения и измеренная приёмка трасс
  • Генератор скрытых трасс: подобрать параметры и набрать финальный набор
  • Условие задачи (statement/) — генерация из Constraints
  • Конвертация Clover (xacro → URDF) как второй дрон

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages