append spawn objects

This commit is contained in:
Даниил Грабарь
2026-09-18 12:37:28 +10:00
parent 9dc1073f42
commit b1b8cedef1
26 changed files with 124049 additions and 77 deletions
@@ -39,3 +39,96 @@ Set `digital_twin.tcp_gizmo.enabled: false` and restart to disable this mode. Th
- Motion still obeys configured joint and TCP limits; simulation does not reproduce all physical robot protections.
- Physics is approximate, including inertia, friction, and elasticity.
- FRI is not used; communication goes through the Webots ROS 2 driver.
## Spawning textured objects
Set `digital_twin.webots.objects` in `cobot-setting.yaml`:
```yaml
objects:
enabled: true
count: 5
models:
- path: pkg://iiwa_description/objects/hammer/hammer1.obj
rotation_deg: [0, 0, 0]
- path: pkg://iiwa_description/objects/hammer/hammer2.obj
rotation_deg: [0, 0, 0]
area:
x: [0.3, 0.7]
y: [-0.3, 0.3]
z: [0.1, 0.1]
```
Webots spawns exactly `count` instances once at startup, independently choosing
from `models` with replacement. This list specifies allowed models, not individual
quantities. An absent section, `enabled: false`, or `count: 0` disables spawning.
Paths support `pkg://`, absolute paths and paths relative to the settings file.
Currently only Wavefront OBJ is supported.
Bounds are in metres in the robot base frame. The spawner uses the same
`webots.transform` and `webots.rotation` (axis and angle in radians) as the robot:
`p_world = t_robot + R_robot * p_local`. They constrain initial spawn positions;
physics may move the objects afterwards. Moving the robot with the mouse after
startup does not relocate existing objects.
The spawn anchor is the bounding-box XY centre and bottom Z. Exported vertex
offsets are compensated without modifying the original files, UVs, scale
(1 unit = 1 metre); orientation is configured per model. Bounds constrain the anchor, not the entire
object. Random placements may overlap; choose a sufficiently large area.
`CadShape` loads OBJ materials through `mtllib` and textures through MTL. Preserve
relative asset paths: for example, `hammer1.mtl` references
`hammer1_basecolor.png`. The complete `objects` directory is installed with
`iiwa_description`. Missing models, materials or textures fail before the first
spawn request. Physics uses an approximate bounding Box and a mass of 0.5 kg,
not calibrated hammer inertia or grasp geometry. Objects are not automatically
added to the MoveIt Planning Scene.
The `object_spawner` node calls `/Ros2Supervisor/spawn_node_from_string`
(`webots_ros2_msgs/srv/SpawnNodeFromString`) once per object. A rejected request
aborts remaining work. Timeouts are not retried to avoid duplicates. The node
exits after success and only runs in simulation.
### Simulation smoke test
1. Build with `colcon build --base-paths src --packages-select iiwa_description iiwa_utils iiwa_bringup iiwa_config --symlink-install`.
2. Run `source install/setup.bash`, then `cobot run local`, selecting Webots.
3. Inspect the five nodes `spawned_object_0000` through `spawned_object_0004`, their
textures and the `All 5 objects spawned` log.
4. Change `transform` and `rotation`, restart and confirm the spawn area translates
and rotates with the robot base. Pause before objects fall to inspect initial positions.
5. Check `count: 0`, operation without cameras and rejection of missing models.
Reference: [Webots CadShape](https://cyberbotics.com/doc/reference/cadshape).
### Per-model rotation
Each `models` entry accepts `path` and `rotation_deg: [X, Y, Z]`.
Angles are fixed degrees: apply X, then Y, then Z about the robot base axes,
`R_model = Rz * Ry * Rx` and `R_world = R_robot * R_model`. For example:
```yaml
models:
- path: pkg://iiwa_description/objects/hammer/hammer1.obj
rotation_deg: [0, 0, 0]
- path: pkg://iiwa_description/objects/hammer/hammer2.obj
rotation_deg: [90, 0, 0]
- path: pkg://iiwa_description/objects/hammer/hammer3.obj
rotation_deg: [0, 0, 45]
```
The supplied OBJ hammers have their long axis along Z. `[0, 0, 0]` gives an
initial vertical orientation, `[90, 0, 0]` lays the hammer sideways and
`[0, 0, 45]` turns it around the vertical axis. Both configuration files now
explicitly set `[0, 0, 0]` for each model; adjust each independently.
Legacy path-only entries remain supported and imply zero rotation.
Both the visible model and its collision Box rotate. Height is recalculated:
`area.z` locates the bottom of the rotated collision bounds in the robot frame;
X/Y locate their centre. Model rotation does not rotate the spawn area.
Changes take effect on the next launch.
This sets the initial orientation, not a constraint. Gravity and contact can
still topple the hammer. Pause simulation at spawn to inspect it. Smoke-test
two models with different angles, check the Box stays above `area.z`, and check
that changing `webots.rotation` preserves each model's relative orientation.
@@ -39,3 +39,101 @@
- Действуют настроенные ограничения суставов и TCP; симуляция не воспроизводит все защиты физического робота
- Физика не идеальна — инерция, трение и упругость приближённые
- FRI-протокол не задействован — связь идёт через Webots-драйвер ROS 2
## Спавн объектов с текстурами
В `cobot-setting.yaml` (секция `digital_twin.webots`) задайте:
```yaml
objects:
enabled: true
count: 5
models:
- path: pkg://iiwa_description/objects/hammer/hammer1.obj
rotation_deg: [0, 0, 0]
- path: pkg://iiwa_description/objects/hammer/hammer2.obj
rotation_deg: [0, 0, 0]
area:
x: [0.3, 0.7]
y: [-0.3, 0.3]
z: [0.1, 0.1]
```
При запуске Webots создаётся ровно `count` объектов: каждая модель независимо
выбирается из `models`, повторения разрешены. `enabled: false`, `count: 0` или
отсутствие секции отключает спавн. Список — разрешённые модели, а не количество
экземпляров каждой модели. Пути могут быть `pkg://`, абсолютными или относительно
файла настроек. Пока поддерживается Wavefront OBJ.
Область задаётся в метрах в системе основания робота: применяется та же пара
`webots.transform` / `webots.rotation` (ось и угол в радианах), что и при спавне
робота. Формула: `p_world = t_robot + R_robot * p_local`. Это начальная область,
а не ограничитель движения: физика затем может перемещать объекты. Перемещение
робота мышью после запуска не переносит уже созданные предметы.
Точка спавна — центр габаритов по X/Y и нижняя точка по Z. Смещение вершин
в экспортированном OBJ компенсируется автоматически; исходные файлы, UV,
масштаб (1 единица = 1 метр) сохраняется; ориентация задаётся отдельно для каждой модели. Диапазон ограничивает
эту точку, а не весь габарит. Пересечения объектов при случайном размещении
не исключаются: выбирайте достаточно просторную область.
`CadShape` загружает материалы из `mtllib` и текстуры из MTL. Сохраняйте OBJ,
MTL и PNG в исходной структуре каталогов: например, `hammer1.mtl` ссылается на
`hammer1_basecolor.png`. Весь каталог `objects` устанавливается вместе с
`iiwa_description`. Отсутствующие модели, MTL и текстуры вызывают ошибку до
первого запроса спавна. Для физики используется упрощённый габаритный Box и
масса 0.5 кг; это не точная модель инерции или захвата молотка. В MoveIt Planning
Scene эти объекты автоматически не добавляются.
Нода `object_spawner` вызывает
`/Ros2Supervisor/spawn_node_from_string` (`webots_ros2_msgs/srv/SpawnNodeFromString`)
однократно для каждого предмета. Отказ сервиса прерывает оставшийся спавн;
тайм-аут не повторяется, чтобы не создавать дубликаты. Нода завершается после
успеха. На физическом роботе она не запускается.
### Проверка в симуляции
1. Пересоберите пакеты:
`colcon build --base-paths src --packages-select iiwa_description iiwa_utils iiwa_bringup iiwa_config --symlink-install`.
2. Выполните `source install/setup.bash`, затем `cobot run local` и выберите Webots.
3. Проверьте пять узлов `spawned_object_0000` … `spawned_object_0004` в дереве сцены,
текстуры молотков и сообщение `All 5 objects spawned`.
4. Измените `transform` и `rotation`, перезапустите: область должна переместиться
и повернуться вместе с основанием робота. Для проверки начальных координат
используйте паузу симулятора до падения объектов.
5. Проверьте `count: 0`, запуск без камер и ошибку при несуществующей модели.
Справочник: [Webots CadShape](https://cyberbotics.com/doc/reference/cadshape).
### Индивидуальный поворот модели
Каждая запись `models` может содержать `path` и `rotation_deg: [X, Y, Z]`.
Углы фиксированные, в градусах; сначала применяется поворот вокруг X, затем Y,
затем Z в системе основания робота: `R_model = Rz * Ry * Rx`,
`R_world = R_robot * R_model`. Например:
```yaml
models:
- path: pkg://iiwa_description/objects/hammer/hammer1.obj
rotation_deg: [0, 0, 0]
- path: pkg://iiwa_description/objects/hammer/hammer2.obj
rotation_deg: [90, 0, 0]
- path: pkg://iiwa_description/objects/hammer/hammer3.obj
rotation_deg: [0, 0, 45]
```
В предоставленных OBJ длинная ось молотка направлена по Z: `[0, 0, 0]`
задаёт вертикальную начальную ориентацию, `[90, 0, 0]` кладёт молоток набок,
а `[0, 0, 45]` поворачивает его вокруг вертикальной оси. В обоих конфигурационных
файлах для всех моделей явно указано `[0, 0, 0]`; изменяйте каждую независимо.
Записи только с путём остаются совместимыми и означают нулевой поворот.
Поворачиваются и видимая модель, и её коллизионный Box. После поворота
пересчитывается высота: `area.z` задаёт нижнюю точку повёрнутого коллизионного
габарита в системе робота, а X/Y — его центр. Поворот модели не поворачивает
саму область спавна. Изменения применяются при следующем запуске.
Это начальная ориентация, а не фиксация: после появления гравитация и контакты
могут опрокинуть молоток. Для проверки поставьте симуляцию на паузу при спавне.
Проверьте разные углы у двух моделей, отсутствие погружения Box ниже `area.z`
и сохранение локальных углов при изменении `webots.rotation`.