19 KiB
Интеграция графов LLM в штатный запуск cobot
Для код-агента. Реализуй задачи по порядку в ветке
experementпо текущей рабочей копии. Здесь описаны изменения и критерии приёмки.
После cobot run робот должен принимать готовый JSON-граф LLM и перемещать установленный оператором инструмент в нужную точку. Обычный Webots использует digital_twin.webots.world, а запуск контроллера использует FRI. Опыты Grant по-прежнему запускаются в Webots через существующие launch-файлы с явным номером опыта. Внешний клиент вызывает LLM и отправляет готовый граф.
| Запуск | Исполнитель | Источник контекста для LLM |
|---|---|---|
cobot run local или cobot run docker → «Симулятор Webots» |
Базовые перемещения через штатный MoveIt | iiwa_scene_context публикует снимок базовой сцены |
cobot run local или cobot run docker → «Контроллер» |
Те же перемещения через штатный MoveIt и FRI при включении в YAML | Именованные позиции и телеметрия робота через штатные интерфейсы |
ros2 launch iiwa_llm_plan_executor planner.launch.py experiment_id:=20 |
Существующие навыки Grant | Существующий scene_json от Grant Supervisor |
Для первой версии предлагаю поддержать именованную позицию и явную TCP-позу, включать исполнение графов на физическом роботе отдельной настройкой и покрыть обе среды cobot run. Навыки захвата, переноса объектов, стыковки инструмента и технологических операций входят только в профиль Grant. На физическом роботе scene_json пока отсутствует. Имя инструмента, его TCP, коллизионная модель и нагрузка берутся из действующей конфигурации робота и контроллера.
1. Подключить узлы к штатному запуску
- Добавить в
cobot-setting.yamlиsrc/iiwa_config/config/setting.yamlодинаковый блокllm_planner. В блок входятenabled: true,hardware_enabled: falseиvelocity_scale: 0.10. Значение масштаба0.10служит начальным значением для Webots. Для физического прогона оператор задаёт согласованное значение. Вsrc/iiwa_utils/iiwa_utils/setting_loader.pyдобавить типизированное чтение блока, строгие булевы значения и конечный масштаб в диапазоне(0, 1]. Отсутствие блока в старом YAML означает выключенную интеграцию. При выключенномenabledштатный запуск работает независимо отhardware_enabled. - Создать
src/iiwa_llm_plan_executor/launch/cobot.launch.pyс аргументамиsetting,simulate,rviz. Включитьiiwa_bringup/iiwa.launch.pyодин раз с теми же аргументами. Приenabled: trueиsimulate: trueдобавитьscene_contextиllm_plan_executorв базовом режиме сuse_sim_time: true. Приsimulate: falseи двух включённых флагах добавить только исполнитель сuse_sim_time: false. В обоих режимах использовать настройки и пути штатного bringup. Проверять конфигурацию до создания процессов. - Использовать общий конструктор команды запуска в
cobot/commands/run.pyдля_run_localи_run_docker. Сохранить меню, подключение ROS overlay, передачуsimulate, монтированиеcobot-setting.yamlи остановку дочернего дерева. Для устаревшей сборки вывести командуcobot rebuild --symlink-installилиcobot docker-setupи вернуть ошибку запуска. - Объявить зависимости нового launch в
src/iiwa_llm_plan_executor/package.xmlи проверить установку черезsetup.py. Оставить направление зависимости от нового launch кiiwa_bringup. Обратная зависимость образует циклiiwa_bringup → iiwa_llm_plan_executor → iiwa_experement → iiwa_bringup. Существующиеplanner.launch.pyиexperiment.launch.pyпродолжают включать низкоуровневый bringup и свои узлы Grant. - Тесты в
cobot/test/иsrc/iiwa_llm_plan_executor/test/покрывают матрицу Webots/FRI × флаги, старый и неверный YAML, аргументы local/Docker и единственный экземпляр контроллера, MoveIt иiiwa_web. При запуске обычного Webots отсутствуют процессыscene_spawner,grant_supervisorиreference_runner. Для существующего launch Grant сохранить прежние тесты, включая отказ приsimulate:=false.
2. Принимать базовые графы без сцены Grant
- В
src/iiwa_llm_plan_executor/iiwa_llm_plan_executor/{node,engine,validator,skills}.pyвыделить режимbaseс собственными проверками и двумя навыками. Сохранить общий разбор JSON, публикацию оригинала,run_id, повторную отправку, один активный запуск, статус, журнал и отмену. Сценозависимые проверки ревизии, владения и готовности оставить в режиме Grant. Вbaseопределять готовность по актуальному полному/joint_states, готовности штатного сервера движения и активному контроллеру. Проверять состояние перед запуском графа и перед каждым шагом. Выход FRI из рабочего состояния, потеря обратной связи или недоступный контроллер прерывают граф и запрещают следующий шаг. Учитывать уже реализованную обработкуCOMMANDING_ACTIVEвiiwa_controller. - Сохранить формат
status,entry,plan,transitionsи интерфейс/iiwa_llm_plan_executor/submit_plan(iiwa_msgs/srv/SubmitPlan). Дляmove_to_namedполеtargetзадаёт имяgroup_stateиз активного SRDF дляplanning.planning_group. Дляmove_to_poseтребовать ровно шесть чиселx,y,zв метрах иa,b,cв радианах вparams. Углы задаются в порядке ZYX по соглашению KUKA ABC, фрейм фиксированbase_link, TCP-линк берётся изplanning.pose_link. Для обоих навыковobjectпустой. Уmove_to_poseполеtargetтакже пустое. Имена, числа, допустимые поля и переходы проверить для всех узлов при приёме. Отклонять неизвестные команды, ссылки на объекты Grant,NaN/Inf, внешние фреймы и попытки переопределить масштаб скорости. Публиковать результат шагаsuccessилиmotion_failedпо результату сервера. Дляmotion_failedразрешать только переход вoperator_requiredилиreplan_required. При отсутствии такого перехода завершать граф какfailedс причиной. - Передавать TCP-цель в штатный action
cobot/move_to_pose(iiwa_msgs/action/MoveToPose). Для именованного движения добавить отменяемыйcobot/move_to_named_pose(iiwa_msgs/action/MoveToNamed) вsrc/iiwa_planning/scripts/move_to_pose_server.pyиsrc/iiwa_msgs. Вынести существующее планирование именованной цели изcobot/move_to_namedв общий участок, чтобы оба интерфейса использовали SRDF, Pilz PTP, лимиты иMotionSerialiser. Штатный сервис сохраняет контракт. Для TCP-цели применять настроенный планировщик и масштаб, согласованные с MoveIt. Успех шага требует успешного результата action, включая выполнение траектории контроллером. - Подключить отмену графа к goal handle MoveIt и штатной остановке. Проверить окно между отправкой цели и получением goal handle, потерю контроллера и повторный submit после отмены.
POST /stopдолжен остановить граф, отправленный через ROS, HTTP или MCP. Текущий_active_run_idвsrc/iiwa_web/iiwa_web/planner.pyучитывает только HTTP-запросы. Источник активного запуска и его отмены должен находиться в executor. Штатный/cobot/stopдолжен инвалидировать активную операцию и ожидающие шаги графа. В базовом режиме графы и обычные запросы MoveIt проходят через одну сериализацию. Проверить, что прямой HTTP-ввод траекторий не перебивает активный граф. - Добавить тесты базового графа с подменой ROS action-сервера. Покрыть успешные именованную и TCP-цели, отсутствие
scene_jsonна FRI, отказ при неизвестном имени и некорректных координатах,not_readyпри устаревших суставах, ошибку контроллера, отмену до принятия цели и в процессе исполнения, дубликат и параллельный запуск. Прогнать существующие тесты Grant иtest_motion_priority.py.
3. Выдавать честный scene_json в базовом Webots
- В
src/iiwa_scene_context/iiwa_scene_context/{node,snapshot}.pyдобавить режимbase. Источник актуальности базового снимка —/joint_statesи TF изbase_linkк настроенному TCP, если трансформ доступен. Публиковать тип базового профиля, метку времени, наблюдаемое состояние, доступные базовые навыки и имена поз из активного SRDF. В пустом мире набор наблюдаемых объектов задачи пуст. У базового снимка нет номера опыта. Отсутствующие данные о камерах, объектах и установленном инструменте обозначать явно. Сцена без объектов задачи не подтверждает отсутствие препятствий для MoveIt. - Сохранить
/iiwa_scene_context/get_scene, QoSRELIABLE/TRANSIENT_LOCALдля/iiwa_scene_context/scene_jsonи действующий формат Grant. Базовый контекст не подписывается на/iiwa_experement/object_stateи не ждёт/iiwa_experement/scene_ready. Возвращать понятный отказ до первого валидного состояния и при его устаревании. Для FRI сервис сцены не запускается, а HTTP/MCP сообщает, чтоscene_jsonдоступен только в Webots. Маршруты отправки, статуса и отмены работают при включённомweb.enabledв обоих режимах. - Тесты проверяют свежесть и содержимое пустой сцены без Grant, достоверность источников полей и неизменный контракт сцены опыта. Проверить, что пропажа базового
scene_jsonсама по себе не блокирует допустимую команду при наличии актуальной телеметрии и готового MoveIt.
4. Собрать и проверить запуск из установленных пакетов
- В обоих
docker/jazzy/{ros-iiwa7,ros-iiwa7-webots}/Dockerfileдобавить исходникиiiwa_experement,iiwa_scene_contextиiiwa_llm_plan_executorв контекст передrosdepиcolcon. Проверить зависимости изpackage.xmlи доступность launch, конфигов и ROS-интерфейсов в release-образах после удаленияsrc. Docker для контроллера не требует приложения Webots. Черезcobot docker-setupсобрать оба образа. Проверитьcobot run dockerна новом Webots-образе и стенде FRI с имитацией аппаратуры. - С ROS 2 Jazzy запустить
cobot rebuild --symlink-install, подключитьinstall/setup.bashи выполнитьcolcon test --base-paths srcиcolcon test-result --verbose. Для общего запускаpytestпо нескольким пакетам использовать--import-mode=importlibиз-за совпадающих имёнtest_launch.py. Сверить результаты с исходным состоянием рабочей копии, включая незакоммиченныйsrc/iiwa_msgs/srv/SubmitPlan.srv. - В обычном Webots запустить
cobot run local→ «Симулятор Webots». Проверить один набор штатных узлов и базовый снимок черезros2 service call /iiwa_scene_context/get_scene std_srvs/srv/Trigger '{}'. Сначала отправить отклоняемый граф и убедиться, что контроллер не получил цель. Затем отправить разрешённую именованную цель и допустимую TCP-цель, выбранную для установленной модели и сцены. Для обеих сверить/plan,/status, фактическую позу иcompleted. Отдельно проверить отмену, общий stop и чистое завершение по Ctrl-C. Повторить на Docker. Проверить, что ручной запуск Grant сexperiment_id:=20отдаёт прежнюю сцену и принимает прежний граф. - Для FRI сначала проверить ветку запуска с имитацией action-сервера и контроллера либо с тестовым FRI-стендом из
src/iiwa_controller/test/. Убедиться, что нет Webots и сервиса сцены, выключенная настройка исключает executor, а при включении граф до готовности возвращаетnot_ready. Физическую приёмку выполнять с оператором после проверки сети, активного режима FRI, лимитов, модели инструмента, Load Data и рабочего пространства. Начать с одной заранее проверенной именованной позиции на согласованной скорости. В отчёте указать отдельно результаты Webots, FRI-имитации и физической проверки. - Описать операторский запуск и примеры графов в
src/iiwa_llm_plan_executor/doc/README.md, контракт базовой сцены вsrc/iiwa_scene_context/docs/interfaces.mdи настройки вdoc/lwc-doc/docs/getting-started/configuration{,.en}.md.
Пример тела POST /planner/runs для Webots. Перед запуском проверьте, что work есть в активном SRDF и применим к текущей сцене.
{
"run_id": "base-webots-1",
"response": {
"status": "ready",
"entry": "go",
"plan": [{
"id": "go",
"skill": "move_to_named",
"target": "work",
"transitions": [
{"event": "success", "next": "completed"},
{"event": "motion_failed", "next": "operator_required"}
]
}]
}
}
Ссылки для реализации
- Проектные контракты по запуску, API и остановке. Deployment, External API, Motion arbitration.
- Документация ROS 2 Jazzy по вложенным launch-файлам и зависимостям. Launch, rosdep.