Files

211 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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).