From cdae71e2bc9965808aca71b9b4da1c5bd4836424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=B0=D0=BD=D0=B8=D0=B8=D0=BB=20=D0=93=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=B0=D1=80=D1=8C?= Date: Sun, 8 Nov 2026 12:53:14 +1000 Subject: [PATCH] docs: clarify validation across reference control tasks --- .../2026-11-08-grant-reference-control.md | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/docs/superpowers/plans/2026-11-08-grant-reference-control.md b/docs/superpowers/plans/2026-11-08-grant-reference-control.md index 7ac8f78..ee96e4b 100644 --- a/docs/superpowers/plans/2026-11-08-grant-reference-control.md +++ b/docs/superpowers/plans/2026-11-08-grant-reference-control.md @@ -1,6 +1,6 @@ # План реализации эталонного управления Grant -> **Для агента-разработчика:** выполняйте задачи по порядку. Используйте навык superpowers:subagent-driven-development либо superpowers:executing-plans. Отмечайте выполненные шаги в чекбоксах. +> **Для агента-разработчика:** выполняйте задачи по порядку, отмечайте выполненные шаги в чекбоксах. **Цель:** обеспечить воспроизводимое эталонное движение робота во всех 20 экспериментах Grant и добавить к существующей команде запуска режимы `view` и `execute`. @@ -16,7 +16,7 @@ - Весь новый исполняемый код, конфигурация, launch, тесты и документация пакета размещаются в `src/iiwa_experement/`. OBJ/MTL использовать из `src/iiwa_description/objects/grant/`. Постоянный `patron` остаётся на роботе. - `mode:=view` — режим по умолчанию; робот не движется. `mode:=execute` начинает движение только после `scene_ready`, готовности контроллера, MoveIt и supervisor, появления свежего состояния робота и задержки 3,0 секунды симуляционного времени. - Запуск только в Webots: в включаемом bringup остаётся `simulate:=true`. Не отправлять эталонные траектории на физический робот через FRI. -- Винты не вставляются и не затягиваются. Робот подносит винт к конкретному отверстию, отпускает его виртуальному оператору, после чего винт удаляется из сцены, а отверстие остаётся пустым. В эталонных маршрутах нет `seat_screw`, `tighten` и затяжного инструмента. +- Винты не вставляются и не затягиваются. Робот подносит винт к конкретному отверстию, отпускает его виртуальному оператору, после чего винт удаляется из сцены, а отверстие остаётся пустым. В эталонных маршрутах робот берёт затяжной инструмент и дотягивает винты, предварительно наживлённые человеком. Считается, что человек установил винты неплотно; окончательную затяжку выполняет робот. - Перемещения к инструментам, извлечение инструмента, перенос люка и винтов, посадка люка, проход соплом вдоль контура и подход к отверстиям выполняются реальными траекториями робота. Без движения меняются только состояние захвата и состояние передачи винта оператору. - Единицы: метры и радианы. Явно задавать преобразования `world`, `base_link`, `patron`, `tcp`, точки крепления и рабочего кончика инструмента. Использовать активный TF/настройки, а не координаты основания, переписанные из текста. - Перед каждым движением в MoveIt должны быть все препятствия и прикреплённые объекты; обновление сцены подтверждается до планирования. Контакт допускается только для нужного инструмента и цели на нужном этапе. @@ -45,13 +45,22 @@ | `iiwa_experement/runtime_config.py`, `launch/experiment.launch.py`, `setup.py`, `package.xml`, `doc/README.md` | Режимы запуска, зависимости, исполняемые файлы и инструкция | | `test/test_*.py` | Проверки контрактов, геометрии, запуска, состояний, сцены MoveIt и маршрутов | -## Особое внимание при проверке +## Проверки по всем задачам -1. В `view` не создаётся клиент движения и не отправляется траектория; проверка в задаче 9. -2. `scene_ready=true` без свежих `/joint_states` и подтверждённой сцены MoveIt не запускает задержку и движение; задачи 4 и 9. -3. Ошибка крепления в Webots или обновления MoveIt останавливает маршрут до следующего движения; задачи 3 и 4. -4. Повторный захват после `grasp_failed` использует текущую позу объекта и не расходует винт дважды; задачи 5 и 8. -5. Передача происходит только у указанного отверстия и только с винтом на магнитном инструменте; отверстие остаётся пустым; задачи 3, 7 и 8. +Каждая задача ниже содержит собственные тесты и проверку результата. Таблица показывает, какой результат проверяется сразу после задачи; задача 10 повторяет проверки в полных прогонах Webots. + +| Задача | Что проверить | +| --- | --- | +| 1. Контракт опытов | Все 20 заданий согласованы с передачей винта; в 11–20 по десять винтов, нет затяжки | +| 2. Геометрия | Инструмент крепится на конце `patron`; позы люка, контура и отверстий меняются вместе с объектами | +| 3. Supervisor | Захват и отпускание меняют состояние одного нужного объекта; при ошибке состояние не меняется | +| 4. MoveIt | Геометрия препятствий и прикреплённых объектов совпадает с Webots и подтверждена сервером движения | +| 5. Движение | Устаревшие `/joint_states`/TF, неподтверждённая сцена и отказ action блокируют следующую траекторию | +| 6. Люк и герметик | Робот действительно переносит люк и ведёт сопло по нужным участкам; объекты не скачут к цели | +| 7. Винты | Винт переносится магнитом к заданному отверстию и передаётся оператору; отверстие остаётся пустым | +| 8. Маршруты | Все 20 последовательностей различаются по задаче; `grasp_failed` использует текущую позу и одну повторную попытку | +| 9. Запуск | `view` не создаёт клиента движения, `execute` ждёт готовности и заданной задержки перед первым движением | +| 10. Итог | Все 20 прогонов проверены в Webots; сбои останавливают небезопасное продолжение | --- @@ -82,15 +91,15 @@ ### Задача 3. Добавить supervisor для захвата и перемещения объектов -**Файлы:** изменить `worlds/grant/iiwa-grant.wbt`, `iiwa_experement/webots_nodes.py`, `test/test_world.py`, `test/test_webots_nodes.py`; создать `iiwa_experement/grant_supervisor.py`, `iiwa_experement/object_state.py`, `test/test_object_state.py`, `test/test_grant_supervisor.py`; обновить `setup.py` и зависимости в `package.xml`. +**Файлы:** изменить `worlds/grant/iiwa-grant.wbt`, `iiwa_experement/webots_nodes.py`, `launch/experiment.launch.py`, `test/test_world.py`, `test/test_webots_nodes.py`, `test/test_launch.py`; создать `iiwa_experement/grant_supervisor.py`, `iiwa_experement/object_state.py`, `test/test_object_state.py`, `test/test_grant_supervisor.py`; обновить `setup.py` и зависимости в `package.xml`. **Интерфейс:** добавить в мир второй `Robot { name "GrantAttachmentSupervisor" supervisor TRUE controller "" }`. Встроенный `/Ros2Supervisor` продолжает создавать объекты. Сервис `/iiwa_experement/object_command` использует `webots_ros2_msgs/srv/SetString`: в JSON-поле `value` передаются `request_id`, `op`, `object`, `target`, `expected_state`. Топик `/iiwa_experement/object_state` типа `std_msgs/msg/String` публикует JSON с возрастающим номером версии, фактической позой, владельцем объекта и `last_request_id`. Команды: `attach_tool`, `dock_tool`, `grab_cap`, `place_cap`, `grab_screw`, `handoff_screw`, `inspect`. - [ ] **Шаг 1. Написать проверки автомата состояний.** Начальные состояния `tool=none`, `cap=free|installed|absent`, 10 доступных винтов. Запрещены захват без нужного инструмента, второй инструмент, второй переносимый объект, неверное отверстие и повторная передача. Переданный винт расходуется, отверстие остаётся `empty`. Отклонённая команда не меняет версию состояния. - [ ] **Шаг 2. Убедиться, что тесты падают.** `pytest -q src/iiwa_experement/test/test_object_state.py src/iiwa_experement/test/test_grant_supervisor.py`. - [ ] **Шаг 3. Сделать объекты адресуемыми.** У каждого управляемого `Solid` должен быть устойчивый `DEF` и прежнее поле `name`. Добавить невидимый внешний supervisor, сохранив стол, основного робота и встроенный `Ros2Supervisor`. Обновить тест мира: в шаблоне есть только один новый supervisor Robot, а iiwa и детали по-прежнему не предустановлены. -- [ ] **Шаг 4. Реализовать внешний контроллер.** Использовать отдельное имя Robot и шаблон окружения `Ros2SupervisorLauncher` (`WEBOTS_CONTROLLER_URL`, `WEBOTS_HOME`). После `scene_ready` найти объекты, получить фактическую позу `patron`/`tcp` из Webots либо проверенной TF-цепи. На каждом шаге Webots пересчитывать позу удерживаемого объекта по калиброванному преобразованию. Менять `locked`/физику только там, где это нужно. Во время переноса объект следует за роботом и не переносится скачком к цели. Публиковать новое состояние после подтверждения Webots; при недоступной позе или объекте отказывать. -- [ ] **Шаг 5. Проверить модуль и выполнить пробу Webots с одним инструментом и люком.** Инструмент совпадает с концом `patron` при движении; люк следует за присоской; при возврате инструмент попадает в исходное гнездо; остальные винты неподвижны. +- [ ] **Шаг 4. Реализовать и подключить внешний контроллер.** Использовать отдельное имя Robot и шаблон окружения `Ros2SupervisorLauncher` (`WEBOTS_CONTROLLER_URL`, `WEBOTS_HOME`); добавить его процесс к существующему launch без автоматических команд движения. После `scene_ready` найти объекты, получить фактическую позу `patron`/`tcp` из Webots либо проверенной TF-цепи. На каждом шаге Webots пересчитывать позу удерживаемого объекта по калиброванному преобразованию. Менять `locked`/физику только там, где это нужно. Во время переноса объект следует за роботом и не переносится скачком к цели. Публиковать новое состояние после подтверждения Webots; при недоступной позе или объекте отказывать. +- [ ] **Шаг 5. Проверить модуль и выполнить пробу Webots без движения робота.** Supervisor находит `tcp` и все объекты начальной сцены, публикует их позы и отклоняет захват инструмента, когда робот ещё далеко от гнезда. Захват и следование инструмента при реальном движении проверить после задач 4–6, когда готовы сцена столкновений и адаптер движения. - [ ] **Шаг 6. Зафиксировать supervisor и автомат состояний.** ### Задача 4. Отразить мир Webots в сцене MoveIt @@ -126,7 +135,7 @@ - [ ] **Шаг 1. Написать тесты последовательностей.** Взятие инструмента: `дом/безопасная высота→точка над гнездом→осевое опускание→крепление→осевое извлечение`; возврат — обратный маршрут. Люк: `над люком→опускание→захват→подъём→перенос над корпусом→совмещение→опускание до посадки→отпускание→отход`. Люк должен двигаться вместе с TCP, без скачка к корпусу. Сопло проходит реальные 3D-участки четырёх сторон и смежные углы на рабочей высоте; сторона считается выполненной только после успешного движения. - [ ] **Шаг 2. Убедиться, что тест падает.** `pytest -q src/iiwa_experement/test/test_operations.py`. - [ ] **Шаг 3. Реализовать операции через калиброванные фреймы.** Позы TCP вычислять по целевой позе рабочего кончика. Подходить и отходить вдоль локальной оси цели; безопасную высоту переноса вычислять по габаритам переносимого объекта и препятствий. Перед захватом/отпусканием проверять фактическую близость и состояние. В 5 выполнить первую смещённую посадку и одну корректировку. В 9/20 хранить последнюю подтверждённую точку герметика и продолжать от неё. -- [ ] **Шаг 4. Проверить модули и выполнить пробы Webots для 1, 6, 9, 10.** Убедиться, что движутся робот, инструмент, люк и сопло, а объект не скачет к цели. +- [ ] **Шаг 4. Проверить отдельные операции в Webots через проверочный клиент.** Убедиться, что движутся робот, инструмент, люк и сопло, а объект не скачет к цели. Полные опыты 1, 6, 9 и 10 прогнать в задаче 10 после подключения эталонного исполнителя. - [ ] **Шаг 5. Зафиксировать операции.** ### Задача 7. Реализовать магнитный захват и передачу винта @@ -138,7 +147,7 @@ - [ ] **Шаг 1. Написать тесты.** Можно выбрать любой из десяти доступных винтов. Взятый винт следует за рабочим концом магнита. Подход к отверстию выполняется по его оси. Передача запрещена, если винт не удерживается или фактическая поза TCP вне допуска у нужного отверстия. Успешная передача удаляет только один винт из Webots и MoveIt, оставляет отверстие пустым, другие винты — в лотке. - [ ] **Шаг 2. Убедиться, что тесты падают.** `pytest -q src/iiwa_experement/test/test_operations.py src/iiwa_experement/test/test_object_state.py`. - [ ] **Шаг 3. Реализовать маршрут робота.** `над выбранным винтом→осевое опускание→захват→осевой подъём→перенос на безопасной высоте→над отверстием→совмещение осей→короткое опускание до точки передачи→отпускание оператору→осевой отход`. Не опускать винт внутрь люка или корпуса. Между отверстиями проходить через проверенную безопасную область, не перемещаться поперёк люка на контактной высоте. -- [ ] **Шаг 4. Проверить Webots для 11, 12, 14.** Робот и винт движутся вместе; сначала видны десять винтов, исчезают только переданные. +- [ ] **Шаг 4. Проверить отдельную операцию передачи в Webots через проверочный клиент.** Робот и винт движутся вместе; сначала видны десять винтов, исчезает только переданный. Полные опыты 11, 12 и 14 прогнать в задаче 10. - [ ] **Шаг 5. Зафиксировать передачу винтов.** ### Задача 8. Описать 20 эталонных маршрутов и восстановление