runtime/rbs_perception
2024-06-25 08:35:54 +00:00
..
config BT interface node works with web-service 2024-05-27 08:35:27 +00:00
include/rbs_perception add perception filter 2023-07-17 16:40:28 +03:00
launch add rbs_interface node 2024-04-01 17:46:43 +03:00
rbs_perception Add node for object perception 2023-04-25 11:57:26 +00:00
scripts Add Object Detection as Interface Node 2024-06-25 08:35:54 +00:00
src rbs_utils in env_manager and clear code 2023-12-14 12:00:35 +03:00
CMakeLists.txt add ROS2 node for DOPE (work through rbs_interface) 2024-04-01 17:55:53 +03:00
package.xml ROS2 node for 6D pose estimation skill 2023-08-03 10:01:40 +00:00
README.md Object detection: add YOLOv8 implementation; unified API with doc 2024-01-22 12:51:01 +00:00

Модуль восприятия окружения роботом rbs_perception

Навык обнаружения объектов (Object Detection). Описание API.

Вначале попытаемся описать полную последовательность действий по подготовке и использованию навыка обнаружения объектов. Задача обнаружения объектов сенсорами робота (в частности, RGB камерой в нашем случае) ставится в случае, например, когда необходимо в заданном окружении (сцене) определить наличие или отсутствие необходимых деталей для сборки изделия. Такие детали представлены в информационной среде в виде ассетов, хранимых в базе данных с заданными характеристиками. Поэтому входным параметром навыка обнаружения объектов является список ассетов, экземпляры которых в текущей задаче необходимо обнаруживать. Результатом использования навыка в информационной системе будет являться получение данных о заданном ассете на конкретном изображении, полученном с помощью RGB камеры.

Начальным этапом навыка является создание датасета, состоящего из синтетических изображений, полученных с использованием пакета BlenderProc. Этот датасет представляет из себя набор файлов изображений и файлов меток к ним, а также файл аннотации, описывающий весь датасет в целом. Он имеет определённую структуру папок и будет использован для обучения нейросетевой модели обнаружения объектов на реальных изображениях в работе (runtime-режим). После создания такой датасет должен быть помещён в базу данных, как единый объект, с заданными характеристиками. В дальнейшем датасет может быть пополнен другими изображениями (например, фото из реального окружения робота), позволяющими произвести дообучение нейросети и улучшить качество работы навыка.

На втором этапе происходит обучение нейросетевой модели YOLOv8. На выходе получаем файл весов модели, который также помещается в базу данных, с указанием версии этого файла и параметров обучения.

Теперь мы имеем всё необходимое для использования навыка обнаружения объектов (Object Detection) в реальном сценарии при управлении роботом в режиме runtime.

Рассмотрим наиболее общий вариант использования этого навыка в среде ROS2.

Первым шагом будет являться первоначальный запуск lifecycle-узла ROS2, отвечающего за работу навыка. Чтобы начать процесс обнаружения конкретной детали на изображении нужно выполнить стартовые действия по шаблону в дереве поведения, задав необходимые параметры процесса (топики получения изображения и выдачи результатов обнаружения, режим работы и другие). После решения поставленной задачи обнаружения конкретного объекта выполняются действия по шаблону приостановки работы навыка. Данные шаблоны деревьев поведения выполняются с помощью исполнителя BehaviorTree. Затем можно начать обнаружение другого объекта, вновь выполнив стартовый шаблон действий и подготовив новые параметры процесса.

Теперь перейдём к полному описанию данного API.

Этап 1. Создание датасета

Для создания датасета используется модуль на Python для BlenderProc. Внешними параметрами для модуля являются:

  • сцена, подготовленная в Blender (файл *.blend)
  • каталог с файлами мешей в формате *.fbx

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

Пример запуска модуля генерации датасета:

blenderproc run objs2Yolov4dataset.py [scene] [obj_path] [output_dir] [vhacd_path] [--imgs 1]
  • scene: путь к файлу описания сцены (*.blend)
  • obj_path: путь к каталогу с файлами описания детектируемых объектов *.obj
  • output_dir: выходной каталог
  • vhacd_path: каталог, в котором должен быть установлен или уже установлен vhacd (по умолчанию blenderproc_resources/vhacd)
  • --imgs 2: количество серий рендеринга (по 15 изображений каждая) на выходе (рекомендуется imgs=200, будет получено 3000 изображений)

В результате работы модуля в папке output_dir будет создана файловая структура с датасетом.

Этап 2. Обучение модели Yolov8.

Для обучения модели используется модуль на Python. Внешним параметром для модуля является:

  • каталог с датасетом, сгенерированный на первом этапе.

Пример запуска модуля обучения:

python rbs_yolov8_train.py [dataset_path] [n_epoch]
  • dataset_path: путь к каталогу с датасетом
  • --n_epoch 3: количество эпох обучения (пока рекомендуем 60-100)
    В результате работы создается файл весов нейросети с лучшими характеристиками обнаружения best.pt

Замечание. Пока этот модуль отсутствует. Подготовка параметров запуска обучения и само обучение проводились в тестовом (ручном) режиме.

Этап 3. Использование навыка в ROS2 для обнаружения объекта на изображении (runtime).

  1. Запуск lifecycle-узла ROS2, реализующего алгоритм навыка обнаружения объектов.

Запуск узла производится командой:

ros2 run rbs_perception pose_estimation_lifecycle.py

Запускается узел с именем lc_detection по умолчанию. Настроечные переменные задаются в файле конфигурации rbs_perception/config/detection_config.json. Пример:

{
    "nodeName":"object_detection",
    "cameraLink":"inner_rgbd_camera",
    "topicImage":"/inner_rgbd_camera/image",
    "publishDelay": 0.5
}
  • "nodeName"- это поле указывает на имя узла в контексте ROS;
  • "cameraLink"- это поле определяет наименование RGB-камеры;
  • "topicImage"- это поле определяет топик, по которому публикуются изображения, полученные с RGB-камеры;
  • "topicSrv"- это поле определяет выходной топик (публикуется сообщение BoundBox);
  • "publishDelay"- это поле, указывает задержку (в секундах) перед публикацией сообщений в выходной топик.
  1. Запуск процесса обнаружения заданного объекта.

Процесс стартует после выполнения операций конфигурирования lifecycle-узла, запущенного в пункте 1. Операции конфигурирования реализуются в дереве поведения rbs_bt_executor/bt_trees/test_objdet_run.xml, которое выполняется командой:

ros2 launch rbs_bt_executor rbs_executor.launch.py bt_file:=test_objdet_run.xml

В файле дерева поведения test_objdet_run.xml используется внешний параметр - SettingPath, для указания пути к json-файлу с настройками:

<?xml version="1.0"?>
<root main_tree_to_execute="ObjDetection">
    <BehaviorTree ID="ObjDetection">
        <Sequence>
            <Action ID="ObjectDetection" 
            SettingPath="!/home/shalenikol/0yolov8/test.json"
            ReqKind = "configure"
            server_name="/object_detection/change_state" 
            server_timeout="1000"/>
            <Action ID="ObjectDetection" 
            SettingPath=""
            ReqKind = "activate"
            server_name="/object_detection/change_state" 
            server_timeout="1000"/>
        </Sequence>
    </BehaviorTree>
</root>

Пример json-файла с настройками навыка обнаружения объекта:

{
 "yolov8_weights_file":"/home/shalenikol/0yolov8/yolov8n.pt",
 "objName":"king",
 "mode":"image_res",
}
  • "yolov8_weights_file"- это путь к файлу весов нейросети;
  • "objName"- это наименование объекта для обнаружения;
  • "mode"- это режим работы навыка (по умолчанию - в топик "topicSrv" публикуется сообщение BoundBox, если "image_res" - то публикуется изображение с наименованными рамками обнаруженных объектов).

После этого узел начинает публиковать в выходной топик информацию об обнаружении объекта на каждом полученном с камеры изображении.

  1. Прекращение процесса обнаружения объекта.

Для завершения навыка нужно выполнить действия из дерева поведения rbs_bt_executor/bt_trees/test_objdet_cleanup.xml:

<?xml version="1.0"?>
<root main_tree_to_execute="ObjDetection">
    <BehaviorTree ID="ObjDetection">
        <Sequence>
            <Action ID="ObjectDetection" 
            SettingPath=""
            ReqKind = "deactivate"
            server_name="/object_detection/change_state" 
            server_timeout="1000"/>
            <Action ID="ObjectDetection" 
            SettingPath=""
            ReqKind = "cleanup"
            server_name="/object_detection/change_state" 
            server_timeout="1000"/>
        </Sequence>
    </BehaviorTree>
</root>

Команда запуска этого дерева:

ros2 launch rbs_bt_executor rbs_executor.launch.py bt_file:=test_objdet_cleanup.xml

После выполнения этих действий lifecycle-узел перейдёт в начальное состояние и можно, повторив пункт 2, вновь запустить процесс обнаружения уже с другим объектом.

Оценка 6D положения объекта

Есть два варианта работы узла по оценке 6D позы объекта. Первый предполагает использование ROS-узла как сервиса, второй - как lifecycle-узла. Узел с управляемым жизненным циклом (lifecycle) позволяет лучше контролировать состояние системы ROS. Такой подход позволит системе убедиться, что все компоненты были созданы правильно, прежде чем любой компонент сможет начать выполнение своей задачи. Это также позволит перезапускать или заменять узел в режиме онлайн.
Так как задача оценки позиции объекта требует использования больших вычислительных ресурсов, то реализация lifecycle-узла позволяет управлять загрузкой ресурсов при этом.

Вариант 1. Сервис по оценке позы объекта

Запуск узла производится командой:

ros2 run rbs_perception pose_estimation.py

Запускается узел с именем image_sub2 по умолчанию. В нём создаётся сервис для распознавания позиции с именем detect6Dpose, который ожидает клиентский запрос.
Для получения позиции заданного объекта клиент посылает сервису запрос с параметром ObjectInfo на входе

  • id - идентификатор,
  • name - имя объекта,
  • mesh_path - путь к mesh-файлу в формате *.ply.

При получении запроса сервис detect6Dpose подписывается на Image-сообщения с камеры /ground_true/camera_node, которые использует для запуска алгоритма 6D оценки позиции Megapose. После получения результата от Megapose сервис публикует сообщение с позицией (Quaternion) в pose6D_[obj] topic.

Вариант 2. Lifecycle-узел ROS для получения 6D-позы

Запуск узла производится командой:

ros2 run rbs_perception pose_estimation_lifecycle.py

Запускается узел с именем image_sub2 по умолчанию. Настроечные переменные задаются в файле конфигурации config/pose_estimation_config.json. Пример:

{
 "nodeName":"image_sub2",
 "topicImage":"/outer_rgbd_camera/image",
 "topicCameraInfo":"/outer_rgbd_camera/camera_info",
 "topicDepth":"/outer_rgbd_camera/depth_image",
 "topicSrv":"/image_sub2/detect6Dpose",
 "publishDelay": 3.3,
 "tf2_send_pose": 1
}
  • "nodeName"- это поле указывает на имя узла в контексте ROS;
  • "topicImage"- это поле определяет топик, по которому публикуются изображения, полученные с RGBD-камеры;
  • "topicCameraInfo"- это поле указывает на топик, по которому публикуется информация о камере, такая как параметры калибровки и настройки;
  • "topicDepth"- это поле определяет топик для изображений глубины, получаемых от RGBD-камеры. Изображения глубины предоставляют информацию о расстоянии до объектов в сцене;
  • "topicSrv"- это поле определяет топик, по которому публикуется 6D-поза объекта после оценки;
  • "publishDelay"- это поле, указывает задержку (в секундах) перед публикацией сообщений в топики;
  • "tf2_send_pose"- это поле связано с отправкой данных о позе (положении и ориентации) в системе tf2, которая используется в ROS для управления координатными преобразованиями. Значение 1 означает включение или активацию данной функции (0 - отключение).

Первым этапом работы узла будет являться его настройка вызовом on_configure(), перед которым необходимо установить параметр узла "mesh_path". Этот строковый параметр должен содержать полный путь к файлу сетчатой модели объекта в формате *.ply.
Если конфигурирование завершено успешно, узел перейдёт в состояние 'inactive'. Затем нужно узел сделать активным, вызвав on_activate(). При этом активируется подписчик на изображения с камеры ("topicImage"), в обратном вызове которого будет происходить распознавание позиции объекта (megapose) и его публикация в топике "topicSrv".
Чтобы отключить распознавание нужно вызвать событие on_deactivate(). Для новой настройки узла при необходимости оценки позы другого объекта нужно вызвать событие on_cleanup(), а затем повторить процедуру конфигурирования и активации.

Важное замечание


Для правильной работы алгоритма Megapose нужно передавать модель объекта с размерами в мм (mesh-файл *.ply).