Клиент - производитель строительных материалов.
Каждый день на погрузку стройматериалов приезжают десятки фур. При этом, габариты паллет, на которых грузят материалы, фиксированы жестко, а вот реальные размеры машин — нет. Внешне кузов может выглядеть ровным прямоугольником, а внутри могут быть скрыты «сюрпризы»: заниженная к кабине крыша, выгнутые борта или самодельные крючки на дверных стойках. Глазом эту кривизну не оценить.
В момент погрузки, вилочный погрузчик заносит паллету шириной 2,40 метра, а она упирается в “неучтенный” выступ внутри кузова. Цена такой ошибки — повреждённый груз, развёрнутая на КПП машина, простой ворот, сорванный график отгрузки.
Решение заказчика: поставить человека на осмотр: сотрудник заглядывает в кузов и по визуальному осмотру решает, грузить фуру или разворачивать. Это медленно, субъективно, не масштабируется, а отказы по геометрии кузова составляют заметную долю разворотов.
Задача, которую решала наша команда: автоматизировать осмотр кузова перед погрузкой. Убрать сотрудника из точки принятия решения и выдавать решение “грузить / не грузить” на основании математических расчетов и реальной геометрии.
Планка задана высокая. Нужно замерять сразу три габарита:
ширину свободного прохода,
высоту от пола до горизонтальной балки,
длину
И, при этом, находить посторонние предметы внутри кузова.
Пороги жёсткие: ширина меньше 2,43 м — отказ, высота меньше 2,60 м — отказ, длина меньше 8 м — отказ. Право на ошибку — ровно два сантиметра. Стандартная паллета шириной 2,40 метра заходит в кузов практически впритык, поэтому любой кустарный крючок на стенке автоматически “бракует” фуру. Чтобы отбраковать кривую фуру до инцидента, нужна миллиметровая точность сканирования. Причем измерять геометрию придется не только по линии ворот, а насквозь: на всю 15-метровую глубину темного полуприцепа.
Главная сложность заключалась в невозможности протестировать оборудование до покупки. Срок поставки промышленного лидара — несколько недель. Если мы ошибемся в расчетах рабочей дистанции, угла обзора или итоговой плотности облака точек, это вскроется только на монтаже, когда сенсор уже полностью оплачен. Подбирать устройство пришлось исключительно по заявленным характеристикам.

Проверка геометрии до покупки лидара
Выбрать сенсор по строке “дальность до N метров” было бы ошибкой. Для промышленной задачи дальность сама по себе почти ничего не гарантирует. Важнее:
видит ли сенсор всю нужную зону контроля с выбранной точки монтажа?
хватает ли плотности точек на объекте, который нужно анализировать?
не попадает ли важная область в “мёртвую зону” или слишком косой угол?
будут ли точки на тех поверхностях, по которым потом строится решение?
можно ли отличить объект уже на месте от объекта, который ещё маневрирует?
Максимальная дальность в спецификации гарантирует только фиксацию единичных откликов. Реальная применимость сенсора определяется дистанцией, на которой шаг сканирования позволяет собрать достаточное облако точек для достоверного распознавания дефекта в 2 см.
Для проверки мы собрали базовую пространственную модель сцены: задали координаты лидара относительно створа ворот, FOV, граничные дистанции ROI и траектории позиционирования кузова. Это не полноценный цифровой двойник, а предварительный расчет для математической валидации сенсора до закупки. Ключевым параметром в модели стала оценка деградации облака точек в зависимости от дистанции. В ближней зоне пространственное разрешение избыточно, но на дальней границе ROI шаг между лучами критически возрастает. Требовалось подтвердить, что даже на максимальном удалении плотности сетки хватит для геометрической реконструкции рельефа с сантиметровой точностью, а не только для первичной детекции крупных габаритов.

Наличие официального драйвера с поддержкой ROS 2 позволило исключить разработку низкоуровневого парсера сырых протоколов. Базовым окружением на серверном оборудовании выступила связка Ubuntu 22.04 и ROS 2 Humble. При проектировании мы жестко изолировали зону ответственности ROS: фреймворк выполняет исключительно роль транспортного слоя для сбора данных. Вендорская нода публикует телеметрию в топик в формате PointCloud2 — бинарном blob-массиве с пространственными координатами и значениями интенсивности. Промежуточный адаптер осуществляет подписку, десериализацию кадра и его трансформацию в массив NumPy для геометрического анализа. Такая декомпозиция исключает интеграцию прикладной логики внутрь графа ROS: весь математический аппарат вынесен в независимый сервис, взаимодействующий с аппаратным слоем по HTTP/API.
Пайплайн
Аппаратная задержка поставки не остановила разработку: базовая архитектура была развернута заранее. Система четко разделена на слой сбора данных (сенсор + ROS 2) и независимый прикладной бэкенд. Его задача — забрать снимок, отсечь лишнее, подтвердить готовность площадки и запустить тяжелые математические вычисления.
Обработка кадра разбита на 7 этапов:
Лидар генерирует сырое 3D-облако сцены.
Вендорский драйвер публикует этот поток в ROS 2.
Служебный адаптер слушает топик и перехватывает единичный актуальный фрейм.
Бинарный пакет PointCloud2 конвертируется в матрицу координат NumPy.
Накладываются геометрические фильтры (CropBox): удаляются все точки вне заданных габаритов рабочей зоны.
Блок предварительной оценки проверяет стабильность сцены и дает разрешение на финальное сканирование.
Сервис геометрического анализа вычисляет точный 3D-профиль кузова и формирует вердикт с визуализацией.
Само по себе облако точек — это массив сырых координат, и основная инженерная задача была в обработке: как задавать зоны, фильтровать шумы и отделять ложные движения на площадке от момента, когда пора запускать анализ.
Первая версия логики работала прямолинейно: если в границах рабочей зоны появлялось критическое количество точек, система считала, что объект прибыл, и запускала сканирование. При тестировании на реальном объекте этот алгоритм показал свою несостоятельность из-за динамики сцены. Грузовики маневрируют неравномерно, заезжают со смещением или частично перекрывают зону контроля. В результате любая активность в кадре провоцировала преждевременный запуск геометрической реконструкции, забивая процессор холостыми прогонами до того, как машина окончательно припаркуется.
Чтобы зафиксировать момент остановки, алгоритм разделили на два независимых контура:
Контур 1 непрерывно анализирует поток на предмет стабильности: проверяет дисперсию координат и плотность точек в зоне интереса. Цель — подтвердить, что объект заехал в рабочую зону, перестал двигаться и сцена замерла.
Контур 2 находится в режиме ожидания и запускается один раз по триггеру от Контура 1. Здесь выполняются основные операции: финальная фильтрация взвеси и пыли, выравнивание облаков после сдвига актуатора, сегментация плоскостей и расчёт геометрических параметров кузова с формированием отчёта.
Контур 1 берёт на себя валидацию прибытия машины, Контур 2 включается один раз для точного расчета геометрии. Такое разделение пайплайна надежно отсекло ложные срабатывания триггера. Вопрос с логикой софта был закрыт, но полевые тесты на реальных объектах показали следующую уязвимость: физические пределы самого сенсора. Реальное поведение лазерных лучей дало искажения, которые невозможно было заложить в идеальную геометрическую среду симулятора.

Конфликт жизненных циклов: ROS 2 против веб-бэкенда
Стык ROS 2 (с его подсистемой DDS, контекстами и строгим жизненным циклом узлов) и стандартного веб-сервиса потребовал пересмотра архитектуры. Попытка держать ROS-подписчика постоянно запущенным внутри долгоживущего веб-процесса приводила к системным сбоям. При частых запросах возникали ошибки повторной инициализации контекста, зависали потоки и сервис вел себя непредсказуемо.
Для задачи дискретного сканирования кузова мы перешли на короткие ROS-сессии. Алгоритм поднимает контекст исключительно на время захвата одного кадра облака точек, после чего сессия принудительно завершается. В сценариях высокочастотного реалтайм-трекинга постоянный перевызов контекста дал бы недопустимый overhead. Но для задачи «один снимок по запросу» такой подход отлично стабилизировал пайплайн и исключил утечки памяти.
Второе техническое ограничение возникло на этапе визуализации. Промышленные серверы на КПП работают без графического окружения, что исключает использование интерактивных 3D-вьюверов для просмотра сырых облаков точек. Да это и не нужно: оператору склада требуются статические, легковесные артефакты для фиксации инцидентов.
В качестве рабочего решения тяжелое 3D-облако программно конвертируется в плоские 2D-проекции и тепловые карты (хитмапы). Этот формат без проблем сохраняется в логах, передается по сети с минимальными задержками и прикладывается к отчету о непригодности кузова.
Локальная отладка через дампы PCD
Зависимость разработки от единственного аппаратного стенда блокировала тестирование: любое изменение в геометрических фильтрах, границах ROI или API требовало физического прогона фуры через рампу для получения актуального кадра с лидара.
Чтобы снять эту зависимость, внедрили пайплайн тестирования на основе сохранённых дампов облаков в формате PCD.
Эталонные сцены с пустым кузовом, дефектами и процессом маневрирования мы отсняли на объекте всего один раз. Вся дальнейшая логика: расчёт плоскостей, фильтрация шума и генерация 2D-ответов — прогонялась уже локально на этих дампах. Дополнительно мы написали эмулятор внешнего контракта. Это полностью сняло зависимость от физического сенсора, исключило простои в разработке и позволило спокойно тестировать fallback-сценарии.
Границы применимости и выводы
Промышленный лидар закрывает только базовую потребность, а именно, генерацию массива пространственных координат. Переход к рабочему продукту обеспечивает алгоритмическая обвязка. Главный урок проекта: софт не исправит физические ограничения железа. Поэтому пригодность сенсора нужно считать математически до закупки.
Кто-то сталкивался с похожими ограничениями на реальном производстве? Как уплотняли облако точек на дальних дистанциях и чем фильтровали шумы, если механически двигать сенсор нельзя?
igrblkv
Какое сложное решение простой проблемы. Чугунная болванка нужных габаритов решает проблему размеров на раз-два.
Или в договоре с транспортной компанией не прописан необходимый габарит? Тогда за чей счёт банкет с подгоном негабаритной фуры?
Arhammon
Так все равно чтоб предъявить что-то по договору - надо же сперва измерить... по сути лидар говорит, куда надо пойти туда-то с рулеткой, чтоб написать акт и предъявить транспортной... по идее так должно работать.
igrblkv
Зачем мерить? Загнали чушку чугунную - погнуло/посрезало всякие выступающие части - загрузили товаром. При претензиях от транспортной компании о повреждении фуры - отправляем читать договор, где прописан внутренний габарит.