
Привет! Меня зовут Коля, я руковожу группой разработки геосервисов автономного транспорта. Одно из наших направлений деятельности — разработка инструментов картографии. Обычная дорожно‑уличная сеть подходит людям и приложениям вроде навигаторов, но роботам этого мало: им необходимы HD‑карты, способные описывать окружающий мир с десятками слоёв атрибутов и точностью до сантиметров. Такие карты кладут в основу алгоритмов локализации, навигации и поведения, и именно от их качества зависит безопасность и эффективность автономного транспорта.
Создание подробных HD‑карт — непростая инженерная задача: каждая карта складывается из данных лидаров, спутников и других источников, проходит десятки стадий обработки и валидации, а для редактирования используются специальные геоинформационные редакторы.
В этой статье мы разберём, как устроен один из ключевых инструментов — map‑editor, обеспечивающий создание и развитие HD‑карт для роботов, какие технические вызовы встречаются по пути и как мы с ними справляемся. Среди наших технологий — FastAPI и C++ для серверной логики, PostgreSQL с PostGIS для работы с геометрией, интеграция с облачными хранилищами и распределёнными вычислениями, а также элементы автоматизации на базе ML.
Для чего роботу нужна карта?
Конечно же, чтобы знать, куда ехать! Тут всё понятно и никакого сюрприза нет: с помощью карты робот понимает, где он сейчас находится, куда ему в конечном счёте надо и как туда добраться. В целом как обычный пользователь Яндекс Навигатора, но очень привередливый. Поэтому карта нужна гораздо более точная и детальная.
Чуть менее очевидно, что по карте робот понимает не только куда, но и как ему ехать: разрешённая на конкретном участке скорость, какой светофор отвечает за прохождение перекрёстка и где этот светофор находится, есть ли слева и справа полосы, пригодные для перестроения, — вот пример дополнительной информации, которую робот получает из карты.
Такие карты для автономного транспорта называют HD‑картами. Они включают в себя два слоя: лидарный и векторный.
Лидарная карта представляет собой облако точек, полученное при проезде машины с лидаром. Это 3D‑слепок пространства вокруг машины, который позволяет с точностью до 5 сантиметров локализовать робота и определить расстояние до предметов вокруг него.

Для задач локализации достаточно и лидарной карты, но дополнительная обработка позволяет на её основе создать карту с той же точностью, содержащую дополнительную информацию об объектах реального мира: светофорах, полосах движения, подъездах, к которым робот‑курьер привозит еду. Такая карта называется векторной. И о ней мы поговорим подробнее.
Как создаётся HD-карта
Для контекста — пара слов об основном стеке. Мы используем Python 3.12 и FastAPI для веб‑сервисов, а также C++ для тяжёлых вычислительных задач, например для валидации или для работы с картой на роботе. Из баз — PostgreSQL и Redis, для объектного хранилища — S3, для распределённых вычислений — YTsaurus.
С точки зрения бэкенда векторная карта — это набор объектов, каждый из которых содержит геометрию и атрибуты.
Геометрия — описание того, где находится объект, в формате GeoJSON. Это достаточно стандартный формат для работы с геометрическими данными.
Атрибуты — дополнительная информация, которая упрощает жизнь роботу: ID правой полосы для перестроения, список полос, которым следует уступить дорогу, или ID светофора, на который нужно посмотреть, чтобы повернуть налево на перекрёстке, и так далее
Все эти объекты рисуют картографы в специальном веб‑приложении, которое и разрабатывает наша команда. Но чем оно отличается от других приложений для рисования карт?
Интеграция с лидарной картой
Лидарная карта — достаточно точный слепок мира, и именно то, что она является основой для векторной карты, позволяет добиться сантиметровой точности. После того как лидарную карту записали и подготовили к использованию, делается её 2D‑проекция, на основе которой генерируются PNG‑тайлы. Далее эти тайлы складываются на S3 и по связке lat + lon + zoom доставляются в приложение, где картографы делают карты.
Лидарная карта периодически обновляется, и векторная должна уметь адаптироваться к этим обновлениям. Поэтому удобная интеграция лидарной карты в интерфейсы картографов и автоматическое обновление векторной карты вслед за ней — одна из задач, которые решает наше приложение.


Возможность совместной работы
Чтобы работа шла быстрее, мы даём картографам возможность совместно работать над картой — условно это некоторое подобие Git. Картограф, который хочет поработать над каким‑нибудь перекрёстком, скажем, на «Парке культуры», выделяет зону, над которой собирается работать, — и она блокируется для остальных.
Для работы с геометрией на уровне базы мы используем специальное Postgres‑расширение, предназначенное для удобной и эффективной работы с геометрическими данными, — PostGIS. Мы сохраняем в нём геометрию заблокированного полигона. При каждом создании новой или обновлении существующей зоны блокировки проверяем, что нет пересечений с другими зонами. Эта проверка на уровне базы позволяет гарантировать отсутствие пересечений и конфликтов.
Однако важно правильно выделить зону интереса. Например, если картограф отметил зону, которая делит пешеходный переход пополам, мы не разрешаем редактирование объекта — иначе сосед может непоправимо изменить вторую часть. Поэтому мы проверяем не только пересечения, но и то, что все редактируемые объекты полностью попадают в зону блокировки. Это уже делается на уровне приложения, с помощью Python‑библиотеки Shapely.
После завершения работы картограф запрашивает ревью. Успешное прохождение ревью разрешает принять изменения в карту. Под капотом это также похоже на Git: объекты имеют версии, накапливаются инкрементально, а head‑карты — последняя версия каждого объекта. У нас есть история, и мы можем получить слепок карты в любой момент времени.

Валидация карты
К картам есть два жёстких требования:
Во‑первых, карта должна быть правильно отформатирована, чтобы робот мог её прочитать.
Во‑вторых, она должна быть логически корректной, чтобы робот мог по ней проехать.
Например, если на карте указано, что из полосы А можно перестроиться в полосу Б, а полосы Б больше нет — у робота возникнут проблемы. Он не въедет в стену, но будет вынужден экстренно менять манёвр и, возможно, вызывать оператора на помощь.
Поэтому, помимо проверки формата, мы делаем более сложные проверки на соответствие атрибутов действительности. Сейчас у нас реализовано несколько десятков различных валидаций на правильность геометрии и атрибутов. Например, мы проверяем, что между полосами и полигонами нет дырок, что нерегулируемые пешеходные переходы всегда имеют приоритет перед пересекающими их полосами дороги, что две полосы, которые ссылаются друг на друга как параллельные, действительно параллельны и между ними нет третьей полосы.
Здесь снова встаёт вопрос правильного определения зоны. В отличие от блокировки при валидации нам критически необходимо не пропустить ничего важного, но при этом не валидировать каждый раз всю карту, так как это дорого. Картографы часто хотят проверять свои правки в процессе, поэтому мы должны быстро валидировать нужную область.
Автоматическая простановка атрибутов
Атрибуты — неотъемлемая и достаточно важная часть карты. Напомню, что речь идёт о полосах, светофорах, перекрёстках и так далее Ручная простановка атрибутов довольно трудоёмкая и подвержена ошибкам, особенно если нужно заполнить одну и ту же форму из десяти элементов для каждой полосы восьмиполосной дороги.
Здесь открывается простор для автоматизации. Например, можно автоматически определить, что полоса заходит на пешеходный переход, и проставить соответствующий атрибут без помощи картографа или проверить, что полосы параллельны, сонаправлены и не имеют других полос между собой. Цель — освободить картографа от проставления атрибутов вручную, но пока в этом направлении ещё много работы
ML в построении карт
Отрисовать всю карту России с сантиметровой точностью одними только руками картографов — достаточно масштабная задача, так как протяжённость только самих дорог составляет около 1 500 000 км. Пожалуй, самым перспективным вариантом автоматизации тут будет попытка внедрения модели, умеющей генерировать карты.
Генерация карт — куда менее распространённая задача, чем генерация картинок или текста, но она вполне решаема. В ход идёт всё: лидарная карта местности, спутниковые снимки, данные из Яндекс Карт. На выходе мы получаем уже знакомые векторные объекты в формате GeoJSON. Наши ML‑инженеры экспериментируют с моделями генерации карт, а мы встраиваем их в редактор карт, получая своего рода Copilot для картографов.
Пользователь выделяет область, где нужна карта, мы запускаем процесс генерации в YTsaurus, который подготовили наши коллеги из ML‑команды, затем получаем результат и показываем его картографу. Картограф оценивает полученный результат и может принять или не принять его.
Нам интересно сравнивать результаты различных версий модели, потому что мы постоянно дообучаем их и проводим эксперименты на стороне ML. Для этого мы запускаем несколько вариантов и отдаём картографу сразу несколько результатов. Это позволяет проводить А/Б‑тестирование моделей с целью их улучшения.


Жизнь после коммита
После создания карты начинается её использование:
Загрузка карты на роботов‑доставщиков. Карта версионируется и загружается на робота при сборке, а онлайн подгружаются только небольшие части (например, новый маршрут или ремонт). Несколько раз в день мы берём head‑карты и нарезаем их на фрагменты, необходимые роботам для работы, — локации. Например, роботам в Сочи не нужна карта Москвы. Локации могут быть и ещё меньшего размера: если мы точно знаем, что сегодня робот‑доставщик будет работать только в Хамовниках, мы соберём карту лишь этого района. После этого мы валидируем конкретный фрагмент, архивируем его и передаём команде деплоя (семь раз провалидируй — один раз задеплой).
Поддержка команды оперирования. Её участники определяют локации, где будет ездить робот сегодня, и редактируют их. Для этого мы предоставляем им инструменты, чтобы заводить и редактировать такие локации.
Генерация PNG‑тайлов. Для некоторых пользователей важно уметь отображать карту в своих интерфейсах. Однако возиться именно с векторным форматом не хочется, так как это требует специфичного кода на клиенте. К тому же возрастает нагрузка как на сервер, так и на клиент — на участке карты в пару квадратных километров может быть несколько тысяч объектов, у каждого из которых будут координаты с точностью восемь знаков после запятой. Чтобы упростить работу в случаях, когда векторные объекты не нужны, мы генерируем на их основе PNG‑тайлы для разных связок x‑y-z, которые затем складываем на S3. Это позволяет просто отдавать пользователю картинку по запросу, что упрощает работу на клиенте и снижает нагрузку для всех.
Выгрузка карты для аналитики. С помощью Yandex Data Transfer мы выгружаем данные о карте и истории её изменений в YTsaurus. Это нужно для дальнейшей аналитики: скорость рисования карты, количество нарисованных километров дорог, средняя площадь локации — за всем этим нужно следить.
Это далеко не полный список тех, кто использует карту. У каждого — свои задачи и требования, поэтому мы стараемся доставлять карту так, чтобы с ней было удобно работать всем коллегам и не только.
Будущее картографии автономного транспорта
Создание HD‑карт для автономного транспорта — сложный и постоянно развивающийся процесс. Мы неплохо продвинулись в этом направлении, но впереди у нас ещё много интересных задач. От качества картографических инструментов зависит, насколько быстро и безопасно автономный транспорт станет частью нашей повседневной жизни.
У нас нет хайлоада на миллионы пользователей, но есть сложные по структуре и большие по объёму данные. Развитие автономного транспорта требует быть готовыми к росту нагрузок уже сейчас — полтора миллиона километров дорог России сами себя не нарисуют.
BoriskovKB
x86 сервер в багажнике так и лежит ?