runtime/rbs_perception
2024-12-09 12:51:20 +03: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 delete pe_dope from rbs_perception 2024-10-15 16:19:14 +03:00
src rbs_utils in env_manager and clear code 2023-12-14 12:00:35 +03:00
CMakeLists.txt update dependencies in package 2024-10-29 10:07:44 +03:00
package.xml update dependencies in package 2024-10-29 10:07:44 +03:00
README.md interface node synchronized + readme for perception 2024-12-09 12:51:20 +03:00

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

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

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

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

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

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

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

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

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

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

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

  • файл, описывающий параметры рандомизиции, а также объекты сцены с подготовленными мешами (файл *.json)
  • выходной каталог.

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

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

blenderproc run renderBOPdataset2.py --form description.json --path /home/user/path/to/dataset

Пример файла description.json:

{"output":{
    "datasetObjects":{
        "details":[
            {"name":"star",
             "inertia":{
                "ixx":0.1,"ixy":0,"ixz":0,"iyy":0.1,"iyz":0,"izz":0.1
                },
             "mass":"0",
             "visual":"/assets/libs/objects/star.dae",
             "collision":"/assets/libs/objects/star.stl",
             "type":"env",
             "material_path":"",
             "part_path":"/libs/objects/star.stl",
             "fbx":"/home/webservice/server/build/public/4c4f3909-74b0-4206-aec1-fc4acd3a1081/assets/libs/objects/star.fbx",
             "solidType":"active",
             "isSelect":true
            }
        ]
    },
    "typedataset":"ObjectDetection",
    "models_randomization":{
        "loc_range_low":[-1,-1,0],"loc_range_high":[1,1,2]
    },
    "scene":{
        "objects":[
            {"name":"floor","collision_shape":"BOX","loc_xyz":[0,0,0],"rot_euler":[0,0,0],"material_randomization":{"specular":[0,1],"roughness":[0,1],"metallic":[0,1],"base_color":[[0,0,0,1],[1,1,1,1]}}},
            {"name":"star","collision_shape":"BOX","loc_xyz":[0,0,0.2],"rot_euler":[0,0,0],"material_randomization":{"specular":[0,1],"roughness":[0,1],"metallic":[0,1],"base_color":[[0,0,0,1],[1,1,1,1]}}
        ],
        "lights":[
            {"id":1,"type":"SUN","loc_xyz":[5,5,5],"rot_euler":[-0.06,0.61,-0.19],"color_range_low":[0.5,0.5,0.5],"color_range_high":[1,1,1],"energy_range":[2,9]}
        ]
    },
    "camera_position":{
        "center_shell":[0,0,0],
        "radius_range":[0.3,0.65],
        "elevation_range":[10,90]
    },
    "generation":{
        "n_cam_pose":3,
        "n_sample_on_pose":3,
        "n_series":222,
        "image_format":"JPEG",
        "image_size_wh":[640,480]
    }
}

В результате работы модуля в папке '/home/user/path/to/dataset' будет создана файловая структура с датасетом.

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

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

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

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

python train_Yolo.py --path /home/user/path/to/dataset --epoch 11 --outpath /home/user/path/to/weights
  • path: путь к каталогу с датасетом
  • epoch 11: количество эпох обучения (пока рекомендуем 30-50)
  • outpath: выходной каталог
    В результате работы создается файл весов нейросети с лучшими характеристиками обнаружения best.pt

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

  1. Подготовить папку с файлами BT v.4
  • Папка /path/to/bt/
  • bt.xml
<root BTCPP_format="4">
    <BehaviorTree ID="Main">
        <Sequence>
            <Action ID="RbsAction" do="ObjectDetection" command="odConfigure" sid="a"></Action>
        </Sequence>
    </BehaviorTree>
</root>
  • skills.json
{"skills": [
    {
        "sid": "a",
        "SkillPackage": {
            "name": "Robossembler", "version": "1", "format": "1.0"
        },
        "Module": {
            "node_name": "lc_yolo", "name": "ObjectDetection", "description": "Object detection skill with YOLOv8"
        },
        "BTAction": [
            {
                "name": "odConfigure",
                "type": "run",
                "param": [
                    {
                        "type": "weights",
                        "dependency": {"object_name": "board", "weights_file": "/home/shalenikol/0_rbs/w_od_board.pt"}
                    },
                    {
                        "type": "topic",
                        "dependency": {
                            "type": "topic",
                            "topicType": "sensor_msgs/msg/Image",
                            "sid": "7b832b17-3030-4758-aab5-96a5046797f7",
                            "topicOut": "/robot_camera/image"
                        },
                        "isFilled": true
                    }
                ],
                "result": [],
                "typeAction": "ACTION"
            }
        ],
        "topicsOut": [
            {
                "name": "lc_yolo/object_detection",
                "type": "rbs_skill_interfaces/msg/BoundBox"
            }
        ],
        "Launch": {
            "executable": "od_yolo_lc.py",
            "package": "rbss_objectdetection"
        }
    }
]}
  1. Запуск интерфейсной ноды с сервером навыка, реализующего алгоритм обнаружения объектов.
ros2 launch rbs_bt_executor interface.launch.py bt_path:=/path/to/bt
  1. Запуск процесса обнаружения заданного объекта через дерево поведения.
    Выполняется командой:
ros2 launch rbs_bt_executor rbs_executor.launch.py bt_path:=/path/to/bt

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

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

Для завершения навыка нужно выполнить дерево поведения:

<root BTCPP_format="4">
    <BehaviorTree ID="Main">
        <Sequence>
            <Action ID="RbsAction" do="ObjectDetection" command="odStop" sid="b"></Action>
        </Sequence>
    </BehaviorTree>
</root>

Файл skills.json

{"skills": [
    {
        "sid": "b",
        "SkillPackage": { "name": "Robossembler", "version": "1", "format": "1.0" },
        "Module": {"node_name": "lc_yolo", "name": "ObjectDetection", "description": "Object detection skill with YOLOv8"},
        "BTAction": [
            {
                "name": "odStop",
                "type": "stop",
                "param": [],
                "result": [],
                "typeAction": "ACTION"
            }
        ],
        "topicsOut": [
            {
                "name": "lc_yolo/object_detection",
                "type": "rbs_skill_interfaces/msg/BoundBox"
            }
        ],
        "Launch": {
            "executable": "od_yolo_lc.py",
            "package": "rbss_objectdetection"
        }
    }
]}

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

Оценка 6D положения объекта (Pose Estimation). API навыка.

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

Этот этап точно такой же, как и в случае с Object Detection. Так как синтетический датасет формата BOP содержит в аннотации истинные позиции заданных объектов в сцене (ground true pose), поэтому его можно использовать также и при обучения модели DOPE для оценки 6D положения объекта.

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

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

  • каталог с датасетом, сгенерированный на первом этапе. В ходе работы скрипта исходный датасет предварительно конвертируется в формат, который используется непосредственно при обучении модели DOPE.

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

python train_Dope.py --path /home/user/path/to/dataset --epoch 44 --outpath /home/user/path/to/weights --name weightsX
  • path: путь к каталогу с датасетом
  • epoch: количество эпох обучения
  • name: наименование файла весов модели на выходе
  • outpath: выходной каталог
    В результате работы создается файл весов модели с лучшими характеристиками обнаружения weightsX.pth

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

Этот процесс аналогичен такому же при обнаружении объекта (YoloV8), здесь приведу лишь дерево (bt.xml) и файл описания скилов в дереве (skills.json).

  • Папка /path/to/bt/
  • bt.xml
<root BTCPP_format="4">
    <BehaviorTree ID="Main">
        <Sequence>
            <Action ID="RbsAction" do="PoseEstimation" command="peConfigure" sid="a"></Action>
        </Sequence>
    </BehaviorTree>
</root>
  • skills.json
{"skills": [
    {
        "sid": "a",
        "SkillPackage": {"name": "Robossembler","version": "1.0","format": "1"},
        "Module": {"node_name": "lc_dope","name": "PoseEstimation","description": "Pose Estimation skill with DOPE"},
        "BTAction": [
            {
                "name": "peConfigure",
                "type": "run",
                "param": [
                    {
                        "type": "weights",
                        "dependency": { "object_name": "knight", "weights_file": "/home/shalenikol/0_rbs/w_knight.pth", "dimensions": [0.03, 0.026, 0.065] }
                    },
                    {
                        "type": "topic",
                        "dependency": {
                            "type": "topic",
                            "topicType": "sensor_msgs/msg/Image",
                            "topicOut": "/rgbd_camera/image"
                        },
                        "isFilled": true
                    },
                    {
                        "type": "topic",
                        "dependency": {
                            "type": "topic",
                            "topicType": "sensor_msgs/msg/CameraInfo",
                            "topicOut": "/rgbd_camera/camera_info"
                        },
                        "isFilled": true
                    }
                ],
                "result": [],
                "typeAction": "ACTION"
            }
        ],
        "topicsOut": [
            {
                "name": "lc_dope/pose_estimation",
                "type": "geometry_msgs/msg/Pose"
            }
        ],
        "Launch": {
            "executable": "pe_dope_lc.py",
            "package": "rbss_poseestimation"
        },
        "Settings": {
            "output": {
                "params": [
                    {
                        "name": "publishDelay",
                        "value": "0.5"
                    },
                    {
                        "name": "tf2_send_pose",
                        "value": "1"
                    },
                    {
                        "name": "mesh_scale",
                        "value": "0.001"
                    }
                ]
            },
            "type": "formBuilder"
        }
    }
]}