# Симуляция (Webots) **Webots** — симулятор роботов с открытым исходным кодом. В LWC используется как цифровой двойник робота KUKA LBR IIWA 7: позволяет разрабатывать и отлаживать алгоритмы управления без доступа к физическому роботу. ## Ключевые особенности - Симулятор использует те же ROS 2 топики и интерфейсы, что и реальный робот - Мир симуляции задаётся в `cobot-setting.yaml` → `digital_twin.webots.world` - Для запуска: `cobot run --simulate` ## Перемещение за TCP В этом режиме цифрового двойника целевая поза робота задаётся перетаскиванием маркера рабочей точки инструмента (TCP) прямо в окне Webots. 1. Включите `digital_twin.tcp_gizmo.enabled: true` в `cobot-setting.yaml` и запустите `cobot run --simulate`. 2. Дождитесь завершения других движений. Для первой проверки удобно перейти в именованную позицию `work` обычной командой. 3. Выберите маркер TCP в Webots. Удерживая левую кнопку мыши, тяните за стрелку перемещения или ручку вращения. Во время редактирования цели робот стоит. 4. Отпустите кнопку: контроллеру отправится одна полная траектория, а не поток action-целей при перетаскивании. 5. Дождитесь завершения движения перед следующим переносом. При недостижимой цели или столкновении на проверяемом пути маркер возвращается к фактическому TCP. Обычные команды координат, joints и файлы управления остаются доступны и имеют приоритет перед новым перетаскиванием. Уже начатое движение гизмы завершается до выполнения ожидающей обычной команды, в том числе если ожидание длится больше двух секунд. ### Инструмент и скорость Маркер следует за фреймом `tcp` активного инструмента: у `patron` это рабочий торец патрона, без инструмента — фланец. При смене инструмента примените выбор через `cobot robot-setup`, пересоберите проект и перезапустите симуляцию. В моделях новых инструментов задавайте `tcp` в рабочей точке. `max_linear_speed` (м/с) и `max_angular_speed` (рад/с) задают верхние пределы. На коротких перемещениях есть разгон и торможение; ограничения суставов также могут снизить скорость. Интерполяция в суставах достигает заданной позы TCP, но не гарантирует прямолинейный декартов путь. Для отключения задайте `digital_twin.tcp_gizmo.enabled: false` и перезапустите систему. Все параметры описаны в [справочнике конфигурации](../configuration.md). `command_timeout` проверяет возраст поступившей цели: отпускание мыши определяется напрямую, настройка времени ожидания не требуется. ### Если маркер возвращается или не реагирует - Дождитесь завершения обычной команды или уже начатой траектории гизмы перед новым перетаскиванием. - При отказе смотрите строку `TCP gizmo rejected target: ...` в выводе запуска. Попробуйте небольшое смещение из достижимой позы, например `work`. - При отсутствии или устаревании обратной связи перемещение недоступно. Проверьте, что симуляция работает и `/joint_states` обновляется. ## Отличия от реального робота - Действуют настроенные ограничения суставов и 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`.