Compare commits
7 commits
Author | SHA1 | Date | |
---|---|---|---|
d41973ca52 | |||
dd551f8344 | |||
531190b4a1 | |||
0f55663304 | |||
4a62e9ecba | |||
a5783618c5 | |||
587441baac |
2 changed files with 443 additions and 0 deletions
150
docs/entities.md
Normal file
150
docs/entities.md
Normal file
|
@ -0,0 +1,150 @@
|
|||
# Сущности фреймворка применительно к веб-сервису
|
||||
|
||||
Веб-сервис позволяет добавить типы Моделей для запуска цифрового двойника (DT), навыка, процесса или дерева поведения. Модели оформляются в виде пакетов. Пакет - это условный "контейнер" для запуска этой сущности в командной строке. Схема пакета общая для всех сущностей. Различны только данные/аргументы. Все вводимые поля, кроме первого (command), могут быть пустыми.
|
||||
|
||||
Типы пакетов:
|
||||
|
||||
- Процессы - "computing_process" - вычислительные процессы, не требующие взаимодействия в ходе исполнения (нет интерфейсов)
|
||||
- Навыки (Серверы навыков) - "skill_server" - произвольные ROS 2 пакеты
|
||||
- Деревья поведения - "behavior_tree" - то, что исполняется нашим ROS 2 bt_executor
|
||||
- Цифровые двойники - "digital_twin" - драйверы устройств, имеющие интерфейс ROS 2
|
||||
|
||||
Нужно создать в веб-сервисе сущность/класс "Пакет", от которой будут наследоваться "Процесс", "Навык", "Цифровой двойник" (устройство/твёрдое тело/точка/воркспейс - всё, что добавляется в Scene Builder), "Дерево поведения". Пакеты будут создаваться в веб-интерфейсе в самом начальном разделе (где проекты, процессы, навыки).
|
||||
|
||||
## Примеры
|
||||
|
||||
Пример для процесса (Генератор датасетов)
|
||||
|
||||
```json
|
||||
{
|
||||
"sid": 1,
|
||||
"type": "computing_process",
|
||||
"description": "Robossembler Dataset Generator",
|
||||
"command": "blenderproc",
|
||||
"package": "dataset_generator.py",
|
||||
"executable": "",
|
||||
"args": {
|
||||
"folder": \${NAME:string:""},
|
||||
},
|
||||
"interfaces": "" // у процессов нет интерфейсов
|
||||
}
|
||||
```
|
||||
|
||||
Пример для цифрового двойника (ROS драйвер для камеры)
|
||||
|
||||
```json
|
||||
{
|
||||
"sid": 2,
|
||||
"type": "digital_twin",
|
||||
"description": "ROS Wrapper for Intel RealSense Cameras",
|
||||
"command": "ros2 launch",
|
||||
"package": "realsense2_camera",
|
||||
"executable": "rs_launch.py",
|
||||
"args": {
|
||||
"camera_namespace": \${NAME:string:""},
|
||||
"camera_name": \${NAME:string:""},
|
||||
},
|
||||
"interfaces": {
|
||||
"cmd": "python ros2_topic_to_json.py"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Пример для навыка (pose estimation skill server)
|
||||
```json
|
||||
{
|
||||
"sid": 3,
|
||||
"type": "skill_server",
|
||||
"description": "Pose Estimation Skill Dope 6D",
|
||||
"command": "ros2 launch",
|
||||
"package": "dope6d",
|
||||
"executable": "dope.py",
|
||||
"args": {
|
||||
"param1": \${NAME:string:""},
|
||||
"param2": \${STRUCTURE:json:""},
|
||||
"param3": \${INT:string:""},
|
||||
"image_raw": \${TOPIC:CameraInfo:""},
|
||||
},
|
||||
"interfaces": {
|
||||
"cmd": "python ros2_topic_to_json.py"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Пример для дерева (behaviour tree)
|
||||
```json
|
||||
{
|
||||
"sid": 4,
|
||||
"type": "behaviour_tree",
|
||||
"description": "Behaviour tree executor",
|
||||
"command": "ros2 launch",
|
||||
"package": "rbs-bt",
|
||||
"executable": "bt_executor",
|
||||
"args": {
|
||||
"xml": \${NAME:string:""},
|
||||
"json": \${NAME:string:""}
|
||||
},
|
||||
"interfaces": {
|
||||
"cmd": "python skills_interfaces_to_json.py [args]",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Пример цифрового двойника камеры
|
||||
|
||||
1. В главном меню создаётся новый тип для сущности "Цифровой двойник" (см. схему выше)
|
||||
2. После создания проекта на экране "Scene Builder" эти цифровые двойники добавляются и конфигурируются. Веб-сервис формирует таблицу цифровых двойников.
|
||||
|
||||
Экземпляр Камеры №1
|
||||
```json
|
||||
{
|
||||
"sid": 0,
|
||||
"package_model": 2, // ссылка на модель данного пакета
|
||||
"args": {
|
||||
"camera_namespace": "cv",
|
||||
"camera_name": "camera1",
|
||||
}
|
||||
}
|
||||
```
|
||||
Экземпляр Камеры №2
|
||||
```json
|
||||
{
|
||||
"sid": 1,
|
||||
"package_model": 2, // ссылка на модель данного пакета
|
||||
"args": {
|
||||
"camera_namespace": "cv",
|
||||
"camera_name": "camera2",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. После завершения конфигурации цифрового двойника Backend фоново запускает команду `get_interfaces.py --json={}`, где json - это набор параметров двойника для данного экземпляра. Программа `get_interfaces.py --json={}` внутри будет запускать субпроцесс вида `<command> <package> <executable> <key1>:=<value1> <key2>:=<value2>` и после запуска получать перечень интерфейсов, после чего возвращает веб-сервису все топики и их типы в системе. Веб-сервис записывает их в таблицу. Структура таблицы БД: `parent` (ссылка на экземпляр цифрового двойника из п.2), `topic_name` (строка или path), `msg_type` (строка), `hash` (хеш, пока не будет использоваться, оставлять пустым по дефолту). Все изменения в Scene Builder должны быть синхронизированы с БД. Если устройство удаляется из сцены, то её интерфейсы также удаляются из таблицы по parent'у.
|
||||
|
||||
## Пример навыка
|
||||
|
||||
1-3. см. предыдущий пример (вместо "Цифровой двойник" - "Навык", вместо Scene Builder - BT Builder, вместо Сцены - Холст). При конфигурации навыка пользователь видит только те топики, которые поддерживают данный тип интерфейса (то есть из цифровых двойников или других источников данных). При удалении данного навыка с холста, его интерфейсы удаляются из таблицы.
|
||||
|
||||
## Виды цифровых двойников (в разработке)
|
||||
|
||||
Parts:
|
||||
`/parts/bolt_x/mesh_path [std_msgs/FilePath]`
|
||||
`/parts/bolt_x/pose_6d [geometry_msgs/Pose]`
|
||||
`/parts/bolt_x/bound_box [geometry_msgs/BoundBox]`
|
||||
`/parts/bolt_x/grasp_pose [geometry_msgs/PoseArray]`
|
||||
|
||||
Wrist Cameras
|
||||
`/robot_1/camera_rgb/camera_info [sensor_msgs/CameraInfo]`
|
||||
`/robot_1/camera_rgbd/camera_info [sensor_msgs/CameraInfo]`
|
||||
|
||||
Robots + Controllers
|
||||
`/robot_1/joint_trajectory_controller [sensor_msgs/CameraInfo]` // moveit
|
||||
`/robot_2/move_cartesian [rbs_skill_interfaces/MoveItSendPose]` // cartesian
|
||||
|
||||
Assemblies:
|
||||
`/assemblies/...`
|
||||
|
||||
Environment
|
||||
`/environment/...`
|
||||
|
||||
Static:
|
||||
`/camera/camera_info []`
|
293
docs/example.md
Normal file
293
docs/example.md
Normal file
|
@ -0,0 +1,293 @@
|
|||
# Пример: проект "Шахматы"
|
||||
|
||||
Имеем доску, две модели фигур - коня и пешку, робота, камеру. Задачей будет из фигур в наличии расставить шахматы на доску в начальную позицию.
|
||||
|
||||
## Создаём проект
|
||||
* Projects
|
||||
```json
|
||||
{
|
||||
"sid": 1,
|
||||
"name": "chess",
|
||||
"description": "Robossembler Example"
|
||||
}
|
||||
```
|
||||
|
||||
## Добавляем модели твёрдых тел (фигур и доски) в библиотеку проекта
|
||||
Сначала добавляются пакеты:
|
||||
|
||||
* Packages
|
||||
```json
|
||||
{
|
||||
"sid": 1,
|
||||
"project": 1,
|
||||
"type": "part_model",
|
||||
"description": "Robossembler: chessboard",
|
||||
"command": "python",
|
||||
"package": "",
|
||||
"executable": "chessboard.py",
|
||||
"args": {
|
||||
"blend": \${FILE:string:""},
|
||||
"dae": \${FILE:string:""},rbs_arm/robot1/controller
|
||||
"fbx": \${FILE:string:""},
|
||||
"...": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
```json
|
||||
{
|
||||
"sid": 2,
|
||||
"project": 1,
|
||||
"type": "part_model",
|
||||
"description": "Robossembler: chess pieces",
|
||||
"command": "python",
|
||||
"package": "",
|
||||
"executable": "chess_pieces.py",
|
||||
"args": [ // ARRAY of pieces
|
||||
{
|
||||
"name": \${NAME:string:""},
|
||||
"blend": \${FILE:string:""},
|
||||
"dae": \${FILE:string:""},
|
||||
"fbx": \${FILE:string:""},
|
||||
"...": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
Затем при запуске "get_interface.py" для каждого пакета, получаем json со структурой:
|
||||
```json
|
||||
{
|
||||
"cameras": [{"properties1": "value1", "propertiesN": "valueN"}],
|
||||
"robots": [{"properties1": "value1", "propertiesN": "valueN"}],
|
||||
"topics": [{"properties1": "value1", "propertiesN": "valueN"}],
|
||||
"...": ""
|
||||
}
|
||||
```
|
||||
в которой ключи - это наши сущности из БД.
|
||||
В данном случае будет присутствовать только массив "parts". Web-сервис записывает парсинг результата в соответствующую таблицу.
|
||||
|
||||
* Parts_lib
|
||||
```json
|
||||
{
|
||||
"sid": 1,
|
||||
"package": 1,
|
||||
"name": "chessboard",
|
||||
"description": "Robossembler: chessboard",
|
||||
"meshs": {
|
||||
"blend": "chessboard.blend",
|
||||
"dae": "chessboard.dae",
|
||||
"fbx": "chessboard.fbx",
|
||||
"...": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"sid": 2,
|
||||
"package": 2,
|
||||
"name": "pawn",
|
||||
"description": "Robossembler: pawn",
|
||||
"meshs": {
|
||||
"blend": "pawn.blend",
|
||||
"dae": "pawn.dae",
|
||||
"fbx": "pawn.fbx",
|
||||
"...": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"sid": 3,
|
||||
"package": 2,
|
||||
"name": "knight",
|
||||
"description": "Robossembler: knight",
|
||||
"meshs": {
|
||||
"blend": "knight.blend",
|
||||
"dae": "knight.dae",
|
||||
"fbx": "knight.fbx",
|
||||
"...": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
Note. Кроме "sid" и "packages" все остальные поля заполняются из массива [{"properties1": "value1", "propertiesN": "valueN"}].
|
||||
|
||||
# Пример: цифровой двойник "Камера"
|
||||
|
||||
## Добавляем пакет с моделью камеры в библиотеку проекта
|
||||
|
||||
```json
|
||||
{
|
||||
"sid": 3,
|
||||
"type": "digital_twin",
|
||||
"entity": "CAMERA",
|
||||
"description": "ROS Wrapper for Intel RealSense Cameras",
|
||||
"command": "ros2 launch",
|
||||
"package": "realsense2_camera",
|
||||
"executable": "rs_launch.py",
|
||||
"args": {
|
||||
"camera_namespace": \${NAME:string:""},
|
||||
"camera_name": \${NAME:string:""},
|
||||
... // + всё, что сейчас в модели данных в коде
|
||||
},
|
||||
"interfaces": {
|
||||
"cmd": "python ros2_topic_to_json.py"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Добавляем экземпляр камеры в сцену (Scene Builder)
|
||||
|
||||
При этом запускаем "get_interface.py" и получаем json со структурой, описанной выше, но в данном случае в результате будет
|
||||
|
||||
```json
|
||||
{
|
||||
"cameras": [
|
||||
{
|
||||
"model_name": "Intel RealSense",
|
||||
"model_type": "RGBD",
|
||||
"...": "..."
|
||||
}
|
||||
],
|
||||
"topics": [
|
||||
{
|
||||
"topic_name": "camera/camera1/image_raw",
|
||||
"msg_type":"sensor_msgs/msg/Image"
|
||||
},
|
||||
{
|
||||
"topic_name": "camera/camera1/camera_info",
|
||||
"msg_type":"sensor_msgs/msg/CameraInfo"
|
||||
}
|
||||
],
|
||||
}
|
||||
```
|
||||
В БД создаются:
|
||||
|
||||
* Cameras
|
||||
```json
|
||||
{
|
||||
"sid": 1,
|
||||
"package": 3,
|
||||
"model_name": "Intel RealSense",
|
||||
"model_type": "RGBD",
|
||||
"pose": {}
|
||||
}
|
||||
```
|
||||
* Topics
|
||||
```json
|
||||
{
|
||||
"sid": 1,
|
||||
"package": 3,
|
||||
"topic_name": "camera/camera1/image_raw",
|
||||
"msg_type":"sensor_msgs/msg/Image"
|
||||
}
|
||||
```
|
||||
```json
|
||||
{
|
||||
"sid": 2,
|
||||
"package": 3,
|
||||
"topic_name": "camera/camera1/camera_info",
|
||||
"msg_type":"sensor_msgs/msg/CameraInfo"
|
||||
}
|
||||
```
|
||||
|
||||
## Робот добавляется аналогично камере
|
||||
|
||||
Модель робота
|
||||
```json
|
||||
{
|
||||
"sid": 3,
|
||||
"type": "digital_twin",
|
||||
"entity": "ROBOT",
|
||||
"description": "Robossembler Arm",
|
||||
"command": "ros2 launch",
|
||||
"package": "rbs_bringup",
|
||||
"executable": "single_robot.launch.py",
|
||||
"args": {
|
||||
"robot_name": \${NAME:string:""},
|
||||
"dof": \${NAME:number:""},
|
||||
... // + всё, что сейчас в модели данных в коде
|
||||
},
|
||||
"interfaces": {
|
||||
"cmd": "python ros2_topic_to_json.py"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* Topics
|
||||
```json
|
||||
{
|
||||
"sid": 3,
|
||||
"package": 4,
|
||||
"topic_name": "rbs_arm/robot1/controller",
|
||||
"msg_type":"sensor_msgs/msg/JointState"
|
||||
}
|
||||
```
|
||||
```json
|
||||
{
|
||||
"sid": 4,
|
||||
"package": 4,
|
||||
"topic_name": "rbs_arm/robot1/controller1",
|
||||
"msg_type":"sensor_msgs/msg/JointState"
|
||||
}
|
||||
```
|
||||
|
||||
## Добавляем пакет навыка Pose Estimation DOPE в библиотеку проекта
|
||||
|
||||
* Packages
|
||||
```json
|
||||
{
|
||||
"sid": 5,
|
||||
"project": 1,
|
||||
"type": "skill_server",
|
||||
"description": "Pose Estimation Skill Dope 6D",
|
||||
"command": "ros2 launch",
|
||||
"package": "dope6d",
|
||||
"executable": "dope.py",
|
||||
"args": {
|
||||
"mode": "image/bbox",
|
||||
"output_topic": \${NAME:string:"bound_box"}
|
||||
"output_topic_image": \${NAME:string:"imagebb"}
|
||||
},
|
||||
"interfaces": {
|
||||
"cmd": "python ros2_topic_to_json.py"
|
||||
},
|
||||
"bt_param":[
|
||||
{
|
||||
"name": "peConfigure",
|
||||
"description": "configuring lifecycle node ROS 2",
|
||||
"type_action": "action/condition",
|
||||
"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] },
|
||||
"sid": "123"
|
||||
}
|
||||
],
|
||||
"result": ["POSE"]
|
||||
},
|
||||
{ "name": "peStop", "type": "stop", "param": [], "result": [] }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Запускаем "get_interfaces.py"
|
||||
* Topics
|
||||
```json
|
||||
{
|
||||
"sid": 5,
|
||||
"package": 5,
|
||||
"topic_name": "bound_box",
|
||||
"msg_type":"geometry_msgs/msg/BoundBox"
|
||||
}
|
||||
```
|
||||
* BTrees
|
||||
```json
|
||||
{
|
||||
"sid": 1,
|
||||
"package": 5,
|
||||
"command_name": "peConfigure",
|
||||
"dependency": {"$FormBuilderTemplate$"}
|
||||
}
|
||||
```
|
Loading…
Add table
Add a link
Reference in a new issue