211 lines
17 KiB
Markdown
211 lines
17 KiB
Markdown
# KUKA iiwa в Genesis World
|
||
|
||
Standalone Python-приложение: стол, iiwa7 и одна или две RGB-D камеры.
|
||
ROS 2 не используется. Рабочие описания — обычные URDF с локальными meshes.
|
||
|
||
## Установка и запуск
|
||
|
||
Все Python-зависимости устанавливает uv:
|
||
|
||
```bash
|
||
uv sync --locked
|
||
uv run python run_scene.py --config configs/scene.yaml
|
||
```
|
||
|
||
Для машины без NVIDIA можно выбрать CPU-сборку PyTorch. Сохраняйте `--extra cpu`
|
||
и в следующих вызовах `uv run`, чтобы uv не переключил окружение обратно:
|
||
|
||
```bash
|
||
uv sync --extra cpu --locked
|
||
uv run --extra cpu python run_scene.py --backend cpu --headless --steps 4 --save-frames
|
||
uv run --extra cpu pytest
|
||
```
|
||
|
||
В `configs/scene.yaml` переключите `scene.mode` между `without_gripper` и
|
||
`with_gripper`. Второй режим автоматически выбирает URDF с инструментом и
|
||
добавляет камеру на нём. Верхняя камера присутствует всегда. Отдельно менять
|
||
путь URDF или `enabled` не требуется; выбор режима имеет приоритет над этими
|
||
устаревшими полями из первоначального плана.
|
||
|
||
```bash
|
||
uv run python run_scene.py --viewer
|
||
uv run python run_scene.py --headless --steps 120 --save-frames
|
||
uv run --extra cuda python run_scene.py --backend gpu --viewer
|
||
uv run pytest
|
||
IIWA_GENESIS_SMOKE=1 uv run pytest tests/test_genesis_smoke.py
|
||
```
|
||
|
||
Для управления во время viewer-запуска добавьте `--interactive`, а для
|
||
отдельного окна управления — `--control-window` (их можно использовать вместе):
|
||
|
||
```bash
|
||
uv run python run_scene.py --viewer --control-window
|
||
```
|
||
|
||
Окно содержит выбор режима, семь полей суставов A1..A7, шесть Cartesian-полей
|
||
`x y z roll pitch yaw`, ползунок скорости 0–100%, а также Send, Stop и Close.
|
||
Скорость ограничивает каждый сустав по его velocity limit из выбранного URDF;
|
||
100% использует полный limit, а 0% и кнопка Stop отменяют движение и удерживают
|
||
текущую целевую позу. Ошибка запуска окна не останавливает сцену.
|
||
|
||
При `--interactive` в терминале выберите режим и отправляйте команды; terminal
|
||
команды используют скорость 100%, а `set` использует выбранный режим:
|
||
|
||
```text
|
||
mode joints
|
||
set 0 0.2 0 1.0 0 0 0
|
||
mode cartesian
|
||
set 0.35 0 0.55 0 1.57 0
|
||
```
|
||
|
||
В режиме joints значения — A1..A7 в радианах; в режиме cartesian —
|
||
`x y z roll pitch yaw`. После выбора режима можно вводить и только числа, без `set`.
|
||
|
||
Cartesian-поза задаётся для TCP в системе координат базы робота (метры и
|
||
радианы), а не в мировой системе. Также доступны однострочные формы
|
||
`joints ...`, `cartesian ...`, `help` и `quit`. Для Cartesian-команд Genesis
|
||
решает IK и плавно ведёт суставы к целевой позе через position controller.
|
||
Для сцены без захвата используется `link7`, с захватом — `tcp`.
|
||
Команды вне суставных limits и решения IK с ошибкой положения больше 0,5 мм
|
||
или ориентации больше 0,005 рад отклоняются; предыдущее движение продолжается.
|
||
Stop удерживает последнюю отправленную контроллеру суставную цель.
|
||
За один шаг обрабатывается до 16 сообщений из каждой очереди ввода, чтобы
|
||
поток команд не блокировал физику. В прочитанной порции `quit` имеет приоритет
|
||
и завершает цикл до обработки GUI и следующего шага. Stop отменяет ожидающие
|
||
движения терминала и предшествующие ему GUI-команды в этой порции; GUI-команды
|
||
после Stop выполняются не раньше следующего шага.
|
||
|
||
Headless по умолчанию выполняет 120 шагов, viewer работает до закрытия окна,
|
||
Ctrl+C или Q/Esc в окне кадров. `output.preview` включает окна RGB и глубины.
|
||
Превью работает в отдельном процессе: оконные циклы OpenCV и Genesis не мешают
|
||
друг другу. Если показ не успевает за симуляцией, пропускаются только кадры
|
||
превью; запись на диск продолжает получать все запланированные кадры.
|
||
30 FPS — частота по времени симуляции; реальная скорость зависит от оборудования.
|
||
Headless всё равно требует рабочий OpenGL/EGL для RGB. Используется EGL, если
|
||
`PYOPENGL_PLATFORM` не задан пользователем. GPU требует совместимого драйвера;
|
||
в текущем `configs/scene.yaml` выбран `backend: gpu`. Для запуска на CPU
|
||
передайте `--backend cpu` или выберите `scene.backend: cpu`. Системный драйвер и
|
||
библиотеки OpenGL предоставляются ОС, их uv не устанавливает.
|
||
Обычные тесты проверяют URDF, конфигурацию и математику; opt-in smoke-тесты
|
||
реально строят оба мира и сохраняют RGB-D на CPU/EGL. Первичная компиляция
|
||
Genesis может занимать несколько минут. Launcher игнорирует унаследованные
|
||
Python overlays, а pytest не загружает внешние плагины автоматически.
|
||
|
||
## Конфигурация и координаты
|
||
|
||
Положения задаются в метрах, углы `euler` — в градусах, суставы и
|
||
`horizontal_fov` — в радианах. Начальные суставы проверяются по URDF limits.
|
||
Верх столешницы находится на 0,800 м, верх монтажной пластины — на 0,815 м;
|
||
поэтому основание iiwa по умолчанию расположено на `[-0.263, 0, 0.815]`.
|
||
При перемещении стола настройте положение робота согласованно.
|
||
|
||
Параметры верхней камеры заданы в мировой системе. Параметры камеры инструмента
|
||
заданы относительно `camera_optical_frame`: вперёд +Z, вверх изображения -Y.
|
||
Трансформы крепления сохранены из исходного описания. Направление оптической
|
||
оси можно уточнять через локальные `lookat` и `up` без правки URDF.
|
||
Исходный optical link расположен у начала CAD-корпуса, поэтому апертура
|
||
сенсора дополнительно смещена на `[0, 0.014, 0.027]` м: передняя плоскость
|
||
находится за корпусом толщиной 26 мм. Это геометрическое приближение,
|
||
исключающее измерение собственного корпуса, а не заводская калибровка.
|
||
Сцена использует гравитацию `[0, 0, -9.81]` м/с². У робота включена полная
|
||
компенсация гравитации и суставной position controller для удержания позы и
|
||
выполнения команд с ограниченной скоростью. Свободный инструмент подчиняется
|
||
гравитации и контактам.
|
||
При нулевых углах суставов фланец и камера инструмента направлены вверх.
|
||
Для осмотра стола этой камерой задайте соответствующую рабочую позу в `robot.joints`.
|
||
|
||
## Случайный молоток на столе
|
||
|
||
В `configs/scene.yaml` перечислите допустимые имена файлов без расширений:
|
||
|
||
```yaml
|
||
tools:
|
||
allowed: [hammer1, hammer3, hammer5]
|
||
seed: null
|
||
```
|
||
|
||
При построении сцены равновероятно выбирается **ровно один** молоток из списка.
|
||
Он остаётся тем же объектом в течение запуска. `allowed: [hammer2]` всегда
|
||
выбирает второй молоток. Список не может быть пустым; повторы, неизвестные имена
|
||
и отсутствующие OBJ/MTL отклоняются при чтении конфигурации. Файлы загружаются
|
||
из `iiwa_genesis_description/tools/hammer/`. Конфиги без раздела `tools`
|
||
используют все пять молотков.
|
||
|
||
При `seed: null` выбор модели, положения и поворота производится заново при
|
||
каждом запуске; случайный выбор может повторить предыдущую модель. Целое
|
||
неотрицательное число, например `seed: 17`, повторяет выбор и начальную позу.
|
||
Этот seed независим от `scene.seed`, используемого симуляцией и камерами.
|
||
Выбранное имя выводится в терминале и используется как имя сущности Genesis.
|
||
|
||
Молоток лежит на свободной стороне стола: весь его контур находится внутри
|
||
`X=[0.06, 0.58]`, `Y=[-0.48, 0.48]` м в системе стола, за пределами монтажной
|
||
пластины и бортиков. Положение учитывает `table.position` и `table.euler`.
|
||
Нижняя точка появляется на 5 мм выше столешницы (локальная высота 0.800 м),
|
||
затем инструмент опускается на неё под действием гравитации. Область рассчитана
|
||
на поставляемый стол; произвольные начальные позы руки, пересекающие эту область,
|
||
могут сразу привести к контакту с инструментом.
|
||
|
||
Импорт учитывает Y-up экспорт Blender `(X, Y, Z) → (X, -Z, Y)` и смещения
|
||
молотков в исходной Blender-сцене; OBJ/MTL не изменяются. Масштаб остаётся 1:1.
|
||
Все детали одного OBJ образуют одно свободное твёрдое тело с шестью степенями
|
||
свободы. Коллизии строятся по выпуклым частям геометрии с разложением вогнутых
|
||
участков, а не по одному охватывающему параллелепипеду. Молоток может падать,
|
||
сдвигаться, вращаться и сталкиваться со столом и роботом.
|
||
|
||
Плотность 3000 кг/м³ и коэффициент трения 0.65 — начальные приближения;
|
||
масса и инерция вычисляются по геометрии. Для точного цифрового двойника нужно
|
||
отдельно откалибровать распределение массы и параметры контакта. Управление
|
||
захватом и сценарии захвата этим изменением не добавляются.
|
||
|
||
В текущих MTL отсутствуют `map_Kd` и другие текстурные карты: процедурные
|
||
материалы Blender не переносятся через такой OBJ-экспорт. Genesis загружает
|
||
доступные MTL; для сохранения древесных волокон и других текстур их нужно
|
||
запечь в изображения и экспортировать с материалами.
|
||
|
||
Проверка реальных контактов всех пяти OBJ со столом (может требовать несколько
|
||
минут на первичное разложение мешей и компиляцию):
|
||
|
||
```bash
|
||
IIWA_GENESIS_SMOKE=1 uv run pytest tests/test_tool_physics.py
|
||
```
|
||
|
||
## Камеры и запись
|
||
|
||
Это **приближение D455**, использующее профиль из согласованного плана:
|
||
640×480, 30 FPS, HFOV 75°, диапазон 0,01–6 м, квантование глубины 1 мм.
|
||
RGB и depth используют одинаковую идеальную pinhole-калибровку. Не моделируются
|
||
ИК-проектор, стереосопоставление, IMU, реальные искажения и индивидуальная заводская
|
||
калибровка D455. Исходный Xacro задавал другую нижнюю границу depth — 0,52 м;
|
||
выбранные 0,01 м следуют утверждённому плану и изменяются через YAML.
|
||
|
||
Каждая камера имеет RGB-сенсор Genesis и DepthCamera raycaster. Дальность по
|
||
лучу преобразуется в optical Z. Пропуски и значения вне диапазона дают depth=0
|
||
и valid=false. Depth использует геометрию raycaster; упрощения мешей/коллизий
|
||
могут отличаться от RGB. Gaussian noise задаётся отдельно для RGB (доля 255)
|
||
и глубины (метры), выключен по умолчанию и использует фиксированный seed.
|
||
|
||
`--save-frames` или `output.save_frames` сохраняет в уникальную папку запуска:
|
||
|
||
- `overhead_000000.png` — RGB;
|
||
- `overhead_000000.npz` — float32 depth в метрах и маска valid;
|
||
- `overhead_000000.json` — intrinsics, обе extrinsics, время симуляции и профиль.
|
||
|
||
Камера инструмента использует префикс `tool`. При `output.pointcloud: true`
|
||
NPZ содержит также `xyz_optical`; невалидные точки равны NaN. Центры пикселей
|
||
располагаются в `(u+0.5, v+0.5)`, оси optical: X вправо, Y вниз, Z вперёд.
|
||
Относительный `output.directory` разрешается относительно YAML-файла.
|
||
Каждый запуск создаёт отдельный каталог, существующие записи сохраняются.
|
||
|
||
Genesis закреплён на 1.4.1, версии остальных зависимостей фиксирует `uv.lock`.
|
||
Xacro явно исключён из транзитивных зависимостей через `tool.uv.exclude-dependencies`.
|
||
Genesis 1.4.1, однако, импортирует его безусловно. Модуль приложения `runtime.py`
|
||
при импорте Genesis убирает этот единственный импорт из AST модуля загрузки URDF
|
||
и заменяет `load_xacro` явной ошибкой. Это адаптация в памяти, ограниченная
|
||
версией 1.4.1: файлы установленного Genesis не меняются, заглушка Xacro не создаётся.
|
||
Обновление Genesis требует пересмотра адаптации и повторного smoke-теста.
|
||
Экспорт описаний также выполнен без Xacro; runtime читает только plain URDF.
|
||
|
||
Документация: [Genesis cameras](https://genesis-world.readthedocs.io/en/latest/user_guide/sensing/camera_sensors.html),
|
||
[raycaster](https://genesis-world.readthedocs.io/en/latest/user_guide/sensing/raycaster.html),
|
||
[uv exclusions](https://docs.astral.sh/uv/concepts/resolution/#dependency-exclusions).
|