Pull to refresh

Как мы делали автопилот для сервисной станции

Reading time 7 min
Views 3.8K
Привет, Хабр! Я работаю в небольшом стартапе в Берлине, занимающимся разработкой автопилотов для автомобилей. Мы заканчиваем проект для сервисных станций одного крупного немецкого автопроизводителя и я бы хотел рассказать о нём: как мы его делали, с какими трудностями столкнулись и что нового открыли для себя. В этой части я расскажу про perception модуль и немного про архитектуру решения в целом. Про остальные модули, возможно, расскажем в следующих частях. Буду очень рад обратной связи и взгляду со стороны на наш подход.

Пресс-релиз проекта со стороны заказчика можно найти тут.

Для начала скажу, зачем автопроизводитель обратился к нам, а не сделал проект своими силами. Крупным немецким концернам сложно менять процессы, а формат разработки автомобилей редко подходит для программного обеспечения — итерации долгие и требуют хорошего планирования. Мне кажется, немецкие автопроизводители это понимают, и поэтому можно встретить стартапы, которые основаны ими, но работают как независимая фирма (например, AID от Audi и Zenuity от Volvo). Другие автопроизводители организуют мероприятия вроде Startup Autobahn, где они ищут возможных подрядчиков для задач и новые идеи. Они могут заказать продукт или прототип и через короткий промежуток времени получить готовый результат. Это может оказаться быстрее, чем пробовать делать то же самое самим, и по затратам выходит не дороже собственной разработки. Сложность изменения процессов хорошо демонстрирует количество разрешений, необходимое для того, чтобы начать тестирование машины с автопилотом у заказчиков: согласие на видеосъемку людей (даже если мы не сохраняем данные, а потоковое видео используем только в анонимном виде без идентификации конкретных людей), согласие на видеосъемку территории, согласие профсоюза и рабочего консула на тестирование данных технологий, согласие службы безопасности, согласие службы IT — это ещё не весь список.

Задача


В текущем проекте заказчик хочет понять, возможно ли управлять автомобилями в сервисных центрах при помощи “AI”. Пользовательский сценарий при этом такой:

  1. Техник хочет начать работу с машиной, которая стоит где-то на парковке снаружи тестовой зоны.
  2. Он выбирает на планшете машину, выбирает сервисный бокс и нажимает “Заехать”.
  3. Машина заезжает внутрь и останавливается в конечной точке (лифт, рампа, или что-то ещё).
  4. Когда техник заканчивает работу над машиной, он нажимает на кнопку на планшете, машина выезжает и паркуется на какое-то свободное место снаружи.

Особенности: не на всех машинах есть камеры. На тех машинах, на которых они есть, мы не имеем к ним доступа. Единственные данные на машине, к которым у нас есть доступ — сонары и одометрия

Cонары и одометрия
Сонары — это датчики расстояния, устанавливаются по кругу на машине и часто выглядят как круглые точки, они позволяют оценить расстояние до объекта, но только близкого и с невысокой точностью. Одометрия — данные по фактической скорости и направлению автомобиля. Зная эти данные и начальное положение, можно довольно точно определить текущее положение машины.

Таким образом, управление автомобилем должно происходить по внешним сенсорам, установленным в сервисной зоне.

Решение


Архитектура конечного продукта выглядит следующим образом:

  • В сервисной зоне мы устанавливаем внешние камеры, лидаров и прочего нет (привет Тесла).
  • Данные с камер поступают на Jetson TX2 (по три камеры на каждый), которые занимаются задачей поиска машины и предобработкой изображений с камер.
  • Далее данные камеры приходят на центральный сервер, который носит гордое название Control Tower и на котором они попадают в модули perception, tracking и path-planning. В результате анализа принимается решение о дальнейшем направлении движения автомобиля и оно отправляется в машину.
  • На данном этапе проекта в машину ставится ещё один Jetson TX2, который при помощи нашего драйвера подключается к Vector, который производит дешифровку данных автомобиля и отправку команд. TX2 получает команды на управление с центрального сервера и транслирует их автомобилю.

Для уровня инфраструктуры используется ROS.

Вот что происходит после того, как техник выбрал машину и нажал “заехать”:

  1. Система ищет машину: мы посылаем команду автомобилю мигать аварийными сигналами, после чего мы можем определить, какая из машин на парковке выбрана техником. На начальном этапе разработки мы рассматривали также вариант определения машины по планке номера, но на некоторых участках у запаркованной машины номер может быть не виден. Кроме того, если бы мы сделали определение машины по регистрационном номеру, то разрешение фотографий пришлось бы сильно увеличить, что отрицательно повлияло бы на производительность, а так мы используем одно и то же изображение для поиска и управления автомобилем. Данный этап происходит один раз и повторяется только в случае, если по какой-то причине мы потеряли автомобиль в трекинге.
  2. Как только машина найдена, мы закидываем картинки с камер, на которые попадает автомобиль, в модуль perception, который производит сегментацию пространства и отдает координаты всех объектов, их ориентацию и размеры. Этот процесс постоянный, выполняется со скоростью примерно 30 кадров в секунду. Последующие процессы также постоянные и выполняются до тех пор, пока машина не приедет в конечную точку.
  3. Модуль трекинга получает на вход данные от perception, сонаров и одометрии, держит в памяти все найденные объекты, объединяет их, уточняет местоположение, предсказывает положение и скорость объектов.
  4. Далее path planner, который делится на две части: global path planner для глобального маршрута и local path planner для локального (отвечает за обход препятствий), строит путь и принимает решение, куда ехать нашей машине, отправляет команду.
  5. Jetson на машине принимает команду и транслирует её автомобилю.

Выезд наружу происходит так же, как и заезд.

Perception


Одним из основных и, по моему мнению, самым интересным модулем является perception. Этот модуль описывает данные с сенсоров в таком виде, чтобы можно было точно принять решение о движении. В нашем проекте он выдает координаты, ориентацию и размеры всех объектов, попадающих на камеры. При проектировании этого модуля мы решили начать с алгоритмов, которые позволили бы производить анализ изображения за один проход. Мы попробовали:

  1. Disentangled VAE. Небольшая модификация, внесенная в β-VAE, позволила нам тренировать сеть так, что латентные векторы хранили информацию об изображении в схематическом виде сверху вниз.
  2. Conditional GAN (самая известная реализация — pix2pix). Данную сеть можно использовать для построения карт. Мы также использовали её для построения схематического вида сверху, вкладывая в неё данные с одной или всех камер одновременно и ожидая схематический вид сверху на выходе.

Одна из итераций Conditional GAN для одной камеры, слева направо: входное изображение, предсказание сети, ожидаемый результат



Фактически идея этих подходов сводится к тому, чтобы конечная сеть могла понимать расположение и ориентацию всех автомобилей и других подвижных объектов, попавших на камеру, посмотрев на входную фотографию один раз. Данные об объектах в таком случае будут хранится в латентных векторах. Тренировка сети происходила на данных из симулятора, который является точной копией точки, где будет проходить демонстрация. И у нас получилось добиться определенных результатов, но мы решили не использовать данные методы по нескольким причинам:

  • За отведенное время мы не смогли научиться использовать данные из латентных векторов для описания изображения. Результатом работы сети всегда была картинка — вид сверху со схематическим расположением объектов. Это менее точно и мы опасались, что такой точности будет недостаточно для управления автомобилем.
  • Решение получается не масштабируемым: для всех последующих установок и для случаев, когда нужно изменить направление некоторых камер, требуется переконфигурация симулятора и повторная полная тренировка.

Тем не менее, нам интересно было понять возможности данных подходов, и мы будем иметь их в виду для будущих задач.

После этого мы подошли к задаче с другой стороны, через обычный поиск объектов + сеть для определения пространственного положения найденных объектов (например такая или такая). Этот вариант нам показался наиболее точным. Единственный минус — он медленнее предложенных до этого подходов, но укладывается в наши возможные рамки задержки, так как скорость движения автомобиля по сервисной зоне не более 5 км/час. Самой интересной работой в области предсказания 3D-положения объекта нам показалась вот эта, которая показывает довольно неплохие результаты на KITTI. Мы построили аналогичную сеть с некоторыми изменениями и написали наш собственный алгоритм определения surrounding box, а если быть более точным, алгоритм оценки координат центра проекции объекта на землю — для принятия решений о направлении движения нам не нужны данные о высоте объектов. На вход сети подается изображение объекта и его тип (машина, пешеход,..), на выходе — его размеры и ориентация в пространстве. Далее модуль оценивает центр проекции и отдает данные по всем объектам: координаты центра, ориентацию и размеры (ширину и длину).

В конечном продукте каждая картинка сначала прогоняется через сеть для поиска объектов, затем все объекты отправляются в 3D-сеть для предсказания ориентации и размеров, после чего мы оцениваем центр проекции каждого и отправляем его и данные об ориентации и размере дальше. Особенностью данного метода является то, что он очень сильно завязан на точность границы boundary box из сети поиска объектов. По этой причине сети типа YOLO нам не подошли. Оптимальный баланс производительности и точности boundary box нам показался на сети RetinaNet.

Стоит заметить одну вещь, с которой нам повезло на данном проекте: земля плоская. Ну, то есть, не такая плоская, как у известного сообщества, но на нашей территории изгибов не наблюдается. Это позволяет использовать зафиксированные монокулярные камеры для проекции объектов в координаты плоскости земли без информации о расстоянии до объекта. В дальнейших планах стоит внедрение monocular depth prediction. Работ на эту тему много, вот, например, одна из последних и очень интересных, которую мы сейчас пробуем для будущих проектов. Depth prediction позволит работать не только на плоской земле, он потенциально должен увеличить точность определения препятствий, упростить процесс конфигурации новых камер и позволит отказаться от необходимости лейблировать каждый объект — нам не важно что именно это за объект, если это какое-то препятствие.

На этом всё, спасибо, что прочитали, и с удовольствием отвечу на вопросы. В качестве бонуса хочу рассказать про неожиданный негативный эффект: автопилот не заботится об ориентации автомобиля, для него не важно как ехать — передом или задом. Главное — ехать оптимально и ни в кого не врезаться. Поэтому есть большая вероятность, что автомобиль часть пути будет проезжать задним ходом, особенно на небольших площадках, где требуется высокая маневренность. Однако люди привыкли, что автомобиль в основном двигается передом, и часто ожидают такого же поведения от автопилота. Если человек бизнеса видит машину, которая вместо того, чтобы ехать передом, едет задом, то он может посчитать, что продукт не готов и содержит ошибки.

P.S. Прошу прощения, что нет изображений и видео с реальным тестированием, но я не могу их публиковать по юридическим причинам.
Tags:
Hubs:
+19
Comments 31
Comments Comments 31

Articles