Станислав Кикоть
«Квантик» №11, 2024
Это была вторая демонстрация взаимодействия беспилотного легкового автомобиля с пешеходами. На первой на дорогу ставили манекен, машина его распознавала как человека и перед ним останавливалась. Теперь нужно было показать что-то более впечатляющее.
Наш автомобиль предназначался для того, чтобы ездить по небольшим дорогам на частной территории (такой, как больница или завод с несколькими корпусами), где иногда ходят люди. К этому времени мы уже научились и пропускать пешеходов, и объезжать неподвижные препятствия, и только-только начинали осознавать необходимость модуля, принимающего решение «пропустить или объехать».
Действительно, если человек переходит дорогу, то автомобиль должен не крутить рулём, а остановиться и ждать, пока человек пройдёт. А вот если человек идёт по краю дороги, то его можно попытаться объехать.
Для движения по пустой дороге мы реализовали один из классических алгоритмов, который по границам дороги и положению автомобиля постоянно уточнял траекторию движения и мог при необходимости учитывать неподвижные препятствия. Он работал неплохо, но имел недостаток: в небольшом числе «мёртвых точек» алгоритм не успевал найти корректную траекторию за разумное время. Поэтому в логику работы беспилотника добавили правило: если на каком-то шаге не получается быстро «обновить» траекторию, то нужно двигаться «как и ехал», по последней корректно подсчитанной траектории. Автомобиль стал передвигаться стабильнее. Задача движения по пустой дороге была решена, и мы начали работать над взаимодействием с другими участниками движения.
За несколько дней перед демонстрацией руководитель нашей команды предложил решать вопрос «пропустить или объехать» с помощи проверки по ширине. Пусть на проезжей части находится препятствие. Измеряем расстояние от него до левой и правой границ дороги и сравниваем с шириной машины. Если по ширине машина может проехать хотя бы с одной стороны с небольшим запасом, то шлём ей траекторию объезда, иначе — траекторию остановки. И молодой человек собственноручно написал этот кусочек кода.
Демонстрация прошла на ура. Ставили манекен на край дороги — машина его объезжала. Ставили посередине — машина останавливалась. Все были опьянены успехом. Руководителя носили на руках. Ещё бы: казалось, что за пару дней он полностью решил проблему взаимодействия с пешеходом.
А на следующий день наступило разочарование. Сначала беспилотник несколько раз попытался объехать переходящих дорогу людей. А потом он всем на удивление поехал в беседующую посередине дороги пару. Каждого из людей по отдельности ширина дороги позволяла объехать, а траекторию объезда обоих беспилотник построить не смог, и сработало правило движения по последней удачно рассчитанной траектории.
С тех пор много воды утекло, было написано много нового кода и переписано старого, и беспилотник больше не едет в толпу. А проверка по ширине временно отключена, но её код не удалён. Вдруг пригодится?
Какие изменения в код вы бы внесли для корректной реакции на группы объектов?
Например, можно добавить правило «тормозить, если мы выбрали движение по старой траектории и на ней находится или скоро окажется пешеход». Эту проверку можно осуществлять и на всех траекториях (как старых, так и новых) после того, как беспилотник определился с её формой. Это снизит время реакции тормозом, так как в него не будет входить время, нужное на построение формы траектории, по сравнению подходом из истории, когда по дорожной ситуации мы пытаемся сначала принять решение о действии, а потом его планировать с точки зрения и руля, и тормоза. А вот правило «тормозить, если траекторию построить не получилось» не годится, так как оно будет выдавать торможения без причины на пустой дороге из-за «мёртвых точек».
Как правильно принимать решение, пропускать или объезжать идущего пешехода? Попробуйте придумать алгоритм, использующий положение, направление движения и скорость пешехода. Как по этим данным понять, идёт ли пешеход вдоль дороги или переходит её?
Например, можно измерить угол между направлением движения пешехода и направлением дороги. Если угол достаточно маленький, то считаем, что пешеход идет вдоль дороги и требует объезда. Сюда же относим стоящих и очень медленных пешеходов. Иначе считаем, что пешеход переходит дорогу и не требует реакции рулём. Это правило будет работать для почти всех пешеходов, переходящих дорогу, и четырёх из пяти пешеходов, идущих вдоль дороги. Что же не так с каждым пятым пешеходом? Дело в том, что если пешеход идёт вперёд по дороге на небольшом расстоянии от края, видит, что по дороге едет машина, и решает прижаться к краю, чтобы её пропустить, то в момент движения пешехода к краю дороги беспилотник может ошибочно перестать его объезжать, и сделать движение рулём в его сторону. Этот недостаток можно устранить при помощи дополнительного правила: «Если мы начали объезжать пешехода, а потом он вдруг пошёл поперек дороги, действуем так: если он пошёл к центру дороги, то нужно затормозить, а если пошёл к краю дороги, то нужно продолжать объезжать».
Художник Мария Усеинова