Куст вместо пешехода: как в SpeedyBot чинили восприятие препятствий

· ·

Куст вместо пешехода: как в SpeedyBot чинили восприятие препятствий

PrimeCoder · 2026 · формат: tech

Разбор новинки простыми словами: что это, кому нужно и брать ли.

Кейс показывает, что ошибки классов и семантическая маска дороги могут скрывать реальные препятствия — проверять нужно весь пайплайн восприятия, а не один детектор.

Связанные услуги: каталог, AI Boost Team, стать клиентом.

Куст, который перекрыл проезд

Робот-доставщик встал посреди дорожки и вежливо попросил уступить. Перед камерой — куст. Никого больше. Робот был совершенно уверен, что перед ним человек.

Это не анекдот про железку, а нормальный рабочий сбой. Инженер Unibot Лев Ларин разбирал его на проекте подключения Alfa Robotics SpeedyBot к платформе UNIBOT Fleet — штатную навигацию робота при этом оставляют как есть, свою не прикручивают. И вместо одной причины нашлись три. Ложный пешеход оказался верхушкой: под ним лежали возврат земли в препятствия и маска дороги, которая стирала настоящую коробку высотой 27 см.

Для владельца парка роботов вывод неприятный, но полезный. Пока вы смотрите на один детектор, дефект живёт в стыке между узлами.

Два тракта, один трекер

На борту RK3588, ROS1, лидар RoboSense Airy Lite и детектор PointPillars. Камерная модель крутится через RKNN. Дальше две ветки сходятся в одной точке.

Лидар даёт 3D-рамки. Камера через RKNN даёт 2D-детекции. Их сопоставляет fusion-узел, потом трекер присваивает объектам устойчивые ID. Классы лидарной ветки идут по номерам: 0 — car, 1 — pedestrian, 2 — cyclist, 3 — truck, 4 — forklift, 5 — Unknown. Камерный publisher передаёт текстовые метки: car, person, rider. Порядковые номера этих списков не совпадают. Вот первая мина.

Если выбирать максимальный IoU до проверки класса, рамка машины спокойно подтвердит пешехода или перебьёт верное совпадение с человеком. Порядок обратный: сначала отбор камерных рамок по классу и confidence, только потом IoU. Пороги остаются штатными, ничего не подкручивали под результат.

Второй слой — что делать с объектом, который лидар видит, а камера не подтверждает. Его переводят в Unknown, геометрию при этом не трогают. На одинаковом записанном входе рамки сохраняют число, порядок, положение, размеры, поворот и confidence. Меняется только категория. Порог трекера для Unknown — 0,2, для остальных классов — 0,6; для human-like классов логика та же. При публикации берётся текущая категория, иначе прошлое состояние трека вернёт «пешехода» обратно.

«Проезд перекрыт, пожалуйста, уступите дорогу». На камере — куст.

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

Земля вернулась в препятствия

GroundFilter ищет плоскость поверхности через PCL SAC segmentation на RANSAC и относит согласованные точки к земле. В коде была дополнительная ветка: часть inliers возвращали обратно в препятствия. Смысл — не потерять ступени. Побочный эффект — покрытие дорожки снова становилось препятствием.

Убрали возврат — и пропала контрольная коробка высотой 27 см. Причина в допуске поиска плоскости: 50 см. Коробка попадала в полосу земли. Пришлось делать два действия сразу: ставить предусмотренный кодом допуск 5 см и убирать возврат inliers. Допуск — это расстояние от найденной плоскости, а не высота препятствия над корпусом. Разницу легко перепутать и потом полдня искать, почему коробки исчезают.

Просто убрать возврат не получилось: пропала контрольная коробка высотой 27 см.

Дальняя область добавляла свою ошибку. Нижняя граница там считалась по фиксированному Z и врала на наклонной дорожке. Заменили высотой той же найденной SAC-плоскости, без второго fit. Отступ дальней ветки — 0,45 м, границы по XY и верхний Z штатные. Если плоскость или её inliers некорректны, вызывается прежний crop. Ближний основной вход имеет границу 2,6 м, предварительный диапазон — 4,5 м. Дальние 45 см на ближние коробки не переносятся.

Маска дороги съела коробку

Перед неподвижным роботом поставили коробку 27 см и записали данные примерно с одного и двух метров. После Ground точки на месте. После маски проезжей области часть исчезает, а в близком контроле пропала вся проверенная область коробки.

Проверили проекцию точек глубины в изображение. Рассогласование нашли. Но диагностический пересчёт с правильной проекцией коробку не спас: её центральная часть была размечена как дорога. Две разные ошибки, два разных исправления — геометрию маски и её семантику одной правкой не закрыть.

Итог: удаляющий mask-stage выкинули из пространственного тракта Ground → Remember → classifier. Камерные детекции остались в ветке категорий, где им и место. Заодно важная оговорка — этот опыт относится к камере глубины, а не к ситуации, когда коробку теряют все сенсоры робота.

Чем это отличается от «поменяли порог»

Обычный ремонт такого бага — опустить порог уверенности или подкрутить один классификатор. Здесь починили порядок операций. Класс проверяется до IoU. Неподтверждённое не выбрасывается, а понижается в Unknown с сохранением геометрии. Земля не возвращается в препятствия. Семантическая маска не имеет права стирать точки в пространственном тракте.

Проверяли на настоящем ARM64-коде с одинаковыми сохранёнными входами: смотрели точки в одной 3D-области предмета после каждого этапа. На реальных сценах — коробка, кусты, бетон; на искусственных облаках — низкая и высокая преграды на заданной поверхности. Нативный стенд: 33 условия и 132 callback с разными поверхностями и контрольными коробками на разных расстояниях. На установленном неподвижном роботе Ground и Remember выдавали около 10 Гц, локальная costmap — 480×480 клеток по 5 см, то есть 24×24 м.

В проверенных областях лишние точки покрытия удалялись, коробка на последующих сообщениях и ближние кусты сохранялись.

Владелец встал перед камерой — человек подтвердился, категория пешехода дошла дальше по цепочке. В другом коротком наблюдении без камерных подтверждений остались Unknown-объекты без человеческих категорий, как и должно быть. После установки комплекта, включая исправление порядка TF, робот прошёл маршрут Площадка → Пруд → док. Три команды завершились успешно, шасси подтвердило контакт зарядки.

Где подвох

  • В некоторых контролях первое сообщение после запуска оставалось пустым. Это поведение включили в результат, а не спрятали.
  • Стенд не равен полигону. 33 условия — хорошо, но погода, освещение и грязь на лидаре туда не влезли.
  • По записям нельзя установить физический источник каждой старой голосовой реплики. Прослеживается путь категорий, не каждая реплика.
  • Обзорные IP-камеры из предыдущей части серии не стоит автоматически считать источником кадров этой модели.

Кому нужно и что делать

Владельцу парка роботов — читать как чеклист приёмки. Требуйте не отчёт «детектор обучен», а проверку сквозного тракта: класс проверяется до IoU? Что происходит с объектом, который лидар видит, а камера нет? Возвращает ли GroundFilter точки в препятствия? Есть ли у семантической маски право удалять точки? Проверено ли это на коробке 27 см с одного и двух метров?

Интегратору — держать под рукой принцип «одна ошибка, одна правка». Смешаете допуск плоскости и возврат inliers в один коммит — получите коробку, которая то есть, то нет.

Брать или подождать: вердикт за 30 секунд

Брать — если у вас свой парк, свой интегратор и доступ к пайплайну восприятия. Порядок проверок и логика Unknown экономят недели переписки с вендором. Подождать — если вы покупаете робота как сервис и ждёте, что вендор сам принесёт релиз с исправлениями. Тогда ваша задача — приёмочный тест, а не патч.

Обещаний «теперь не ошибается» тут нет и быть не может. Есть проверенный участок пайплайна и честный список того, что осталось за кадром.

FAQ

Робот правда принял куст за человека?

Категория пешехода пришла по цепочке 2D/3D-сопоставления, а не от отдельного «глупого» детектора. Поэтому и лечится на уровне порядка проверок и понижения в Unknown.

Почему не подняли порог уверенности?

Пороги остались штатными: 0,6 для обычных классов и 0,2 для Unknown. Лечили логику, а не крутилку.

Маска дороги теперь не используется?

Используется в ветке категорий. Из пространственного тракта Ground → Remember → classifier её убрали — она удаляла настоящие точки препятствий.

Это финальное решение?

Это пятая часть серии и рабочая проверка на конкретном роботе. Дальше — эксплуатация и новые сценарии, где всплывут новые стыки.

Что делать на следующей неделе

Возьмите свой текущий пайплайн и прогоните три вещи: коробку 27 см на покрытии, куст вблизи и человека перед камерой. Сравните, что остаётся в облаке препятствий после каждого этапа, а не только на выходе. Если расхождение есть — вы нашли свой куст раньше, чем он перекрыл проезд.

Читайте также