Перейти к содержимому

Экспорт в OpenDRIVE / OpenSCENARIO / esmini

drawtonomy преобразует нарисованную от руки сцену в дорожную сеть ASAM OpenDRIVE (.xodr) и сценарий OpenSCENARIO (.xosc), упакованные в единый ZIP-архив, который можно сразу воспроизвести в esmini.

Конвертация намеренно базовая: поддерживаются только те фигуры, которые чисто отображаются на модель данных ASAM, остальное остаётся за бортом. Эта страница точно описывает, что именно конвертируется, как работает траектория экспортируемого транспортного средства и где проходят границы поддержки — чтобы результат никогда не вводил в заблуждение.

Видео ниже снято за один дубль: нарисован перекрёсток, нарисован маршрут, сформированы отпечатки, экспортирован ZIP для esmini, воспроизведён файл .xosc в esmini.

Один дубль: нарисовать перекрёсток, нарисовать маршрут, сформировать отпечатки, экспортировать ZIP для esmini, воспроизвести экспортированный .xosc в esmini.

Точка входа в ASAM-экспорт одна. drawtonomy не предоставляет отдельные пункты меню для .xodr и .xosc — оба файла создаются вместе и упаковываются в один архив.

Подменю Export с выделенным пунктом .zip (esmini)

  1. Нарисуйте сцену (полосы движения, перекрёсток, транспортные средства, маршрут…).
  2. Откройте меню → Export → .zip (esmini).
  3. Введите базовое имя по запросу (по умолчанию drawtonomy-<дата>).
  4. Скачается <имя>.zip, содержащий <имя>.xodr, <имя>.xosc и 3D-модели esmini, на которые ссылается сценарий.

Экспортируется вся текущая страница целиком — режима «только выделенное» для ASAM-экспорта нет.

Окно терминала
unzip drawtonomy-2026-05-30.zip
cd drawtonomy-2026-05-30
esmini --osc drawtonomy-2026-05-30.xosc --window 60 60 1024 768

Транспортное средство, движущееся по экспортированной траектории в esmini

Транспортное средство движется по оранжевой линии — это и есть FollowTrajectoryAction, сформированный из нарисованного вами маршрута.

Фигура drawtonomyЭлемент OpenDRIVEПримечания
Lane (полоса движения)один <road>1 полоса = 1 независимая дорога
Traffic light (светофор)<signal> на ближайшей дорогетолько типы vehicle / pedestrian
Crosswalk (пешеходный переход)<object type="crosswalk">размещается перпендикулярно дороге
Polygon (≥3 точек)<object type="patch"> с <outline>визуализация перекрёстков и зон

Всё остальное — транспортные средства, пешеходы, отдельные точки, свободные ломаные, текст, изображения — в .xodr не записывается.

Детали реализации каждой дороги:

  • Геометрия — только прямые отрезки. Опорная линия дороги формируется по точкам левой/правой границы полосы и записывается как сегменты <line>. Ни arc, ни spiral, ни poly3 не создаются.
  • Фиксированная разметка полос. Каждая дорога содержит ровно одну левую полосу (id=1), одну центральную (id=0) и одну правую (id=-1), все с type="driving". Многополосные дороги и несколько секций полос не поддерживаются.
  • Разметка проезжей части жёстко задана как сплошная белая линия 0,13 м.
  • Перекрёстки отсутствуют. Каждая дорога имеет junction="-1", элемент <junction> не генерируется. Перекрёстки передаются только через polygon patch (визуально) и через связи predecessor/successor, производные от соединений next/prev полосы (только первая запись).
  • Нет уклонов и поперечных профилейelevationProfile и lateralProfile генерируются пустыми (плоские дороги в горизонтальной плоскости).
  • Масштаб фиксирован: 16,67 пкс/м; географическое начало координат — 0.
Фигура drawtonomyЭлемент OpenSCENARIO
Vehicle (транспортное средство)<ScenarioObject> (<Vehicle> или <Pedestrian>)
Path footprint (ведущее ТС на маршруте)<FollowTrajectoryAction>

«Пешеход» — это фигура Vehicle, имя шаблона которой соответствует паттерну pedestrian/walk; она записывается как <Pedestrian> вместо <Vehicle>. Полосы, пешеходные переходы, светофоры и свободные ломаные в .xosc не попадают.

Экспортируемый сценарий намеренно минималистичен:

  • Единственное динамическое поведение — FollowTrajectoryAction: полилиния с метками времени. Скоростные действия, смена полосы, реакция на светофоры, предотвращение столкновений и условия взаимодействия не поддерживаются.
  • Каждый движущийся объект стартует при SimulationTime ≥ 0, сценарий завершается жёстким StopTrigger на 60 с.

Как отпечаток маршрута становится движением ТС

Заголовок раздела «Как отпечаток маршрута становится движением ТС»

Это ключевая часть динамического экспорта, поэтому разберём подробно.

Панель отпечатков: Variable positioning, Interval и Anchor

Маршрут — это нарисованная ломаная, отпечатки — призрачные копии транспортного средства, расставленные вдоль неё (след, который вы видите в редакторе). При экспорте:

  1. Только ведущий отпечаток (первый) становится движущимся <ScenarioObject>. Остальные — лишь визуализация на холсте и отбрасываются. В результате получается одно транспортное средство, проходящее весь маршрут, а не колонна.
  2. Контрольные точки маршрута становятся вершинами траектории в мировых координатах (ENU, метры).
  3. Каждая вершина получает метку time, и результат записывается как <Trajectory><Polyline> из <Vertex time="…"> внутри <FollowTrajectoryAction>.

Скорость фиксирована — это ключевое ограничение

Заголовок раздела «Скорость фиксирована — это ключевое ограничение»

Траектория привязана к жёстко заданной скорости 10 м/с (≈ 36 км/ч). В drawtonomy нет поля скорости нигде в интерфейсе, и экспортёр никогда не изменяет это значение по умолчанию. В esmini объект будет показывать ~36 км/ч независимо от того, что вы нарисовали. Скорость не задаётся — вместо этого вы управляете распределением времени через расстановку отпечатков, как описано ниже.

Переключатель Variable positioning на маршруте определяет, как время распределяется вдоль траектории:

  • Равномерный (переключатель выключен) — отпечатки расставлены через равные дуговые расстояния (Interval), время вычисляется как расстояние / 10 м/с. Движение — с постоянной скоростью. Изменение Interval влияет только на количество записываемых вершин (плотность дискретизации); форма пути и общая продолжительность не меняются.
  • Переменный (переключатель включён) — каждый отпечаток закреплён в определённой точке маршрута, а общее время делится на равные временные интервалы между отпечатками. Там, где отпечатки скучены, ТС движется медленнее; там, где они расставлены широко — быстрее. Это единственный способ менять эффективную скорость на разных участках.
Действие в редактореЭффект при экспорте
Переместить контрольную точку маршрутаКоординаты вершины траектории + общая продолжительность (длина меняется, скорость остаётся 10 м/с)
Перетащить отпечаток в режиме VariableНормализованная позиция отпечатка → time его вершины → локальная (эффективная) скорость на этом участке
Переключить Variable positioningПереключение между равновременным и равноскоростным расчётом
Изменить Interval (равномерный режим)Только количество вершин — форма траектории и скорость не меняются
Изменить AnchorТолько смещение отрисовки отпечатка — на экспортируемую траекторию не влияет
Изменить шаблон транспортного средстваvehicleCategory, 3D-модель, высота ограничивающего прямоугольника, набор параметров производительности
Изменить размер ТС (ширину, длину)Размеры BoundingBox и геометрия осей
Повернуть ТСНачальный курс (только если у ТС нет траектории)
Переместить ТСInit WorldPosition (привязывается к началу траектории, если она есть)

Прямой ответ на частый вопрос: да — перемещение отпечатка вдоль маршрута в режиме Variable меняет план скоростей при экспорте, поскольку перераспределяет время на этом участке. Перемещение в равномерном режиме и изменение Anchor на экспорт не влияют.

Для честного описания области применения: следующие параметры берутся из фиксированных таблиц или констант и не доступны для редактирования: категория и набор параметров производительности транспортного средства, пути к 3D-моделям, высота ТС по категории, геометрия осей (вычисляется из габаритов), режим следования (position), триггер остановки на 60 с и — самое важное — скорость траектории 10 м/с.

Экспортёр входит в состав @drawtonomy/sdk и работает без редактора. В отличие от меню, SDK позволяет также генерировать файлы по отдельности:

import { exporter, createSnapshot } from '@drawtonomy/sdk'
const snapshot = createSnapshot(shapes)
// Упакованный архив (то же, что пункт меню):
const { blob, baseName } = exporter.buildEsminiZip(snapshot, {
baseName: 'my-scene',
})
// Или каждый формат отдельно:
const xodr = exporter.exportToOpenDrive(snapshot)
const xosc = exporter.exportToOpenScenario(snapshot, {
xodrFilename: 'my-scene.xodr',
})

Полный API и точки расширения см. в справочнике Exporter SDK.

ФорматВерсия
OpenDRIVE1.8
OpenSCENARIO1.3

Поддерживается: прямолинейные дороги из полос движения; светофоры, пешеходные переходы и патчи перекрёстков как объекты OpenDRIVE; одно транспортное средство на маршрут с временной траекторией; рабочий ZIP для esmini, готовый к воспроизведению.

Не поддерживается: перекрёстки OpenDRIVE, криволинейная геометрия, многополосные дороги, уклон дорог; скоростные действия OpenSCENARIO, смена полосы, логика светофоров, взаимодействие нескольких агентов, управление скоростью отдельных ТС.