KUKA iiwa в Genesis World
Standalone Python-приложение: стол, iiwa7 и одна или две RGB-D камеры. ROS 2 не используется. Рабочие описания — обычные URDF с локальными meshes.
Установка и запуск
Все Python-зависимости устанавливает uv:
uv sync --locked
uv run python run_scene.py --config configs/scene.yaml
Для машины без NVIDIA можно выбрать CPU-сборку PyTorch. Сохраняйте --extra cpu
и в следующих вызовах uv run, чтобы uv не переключил окружение обратно:
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 не требуется; выбор режима имеет приоритет над этими
устаревшими полями из первоначального плана.
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 (их можно использовать вместе):
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 использует выбранный режим:
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 мм. Это геометрическое приближение,
исключающее измерение собственного корпуса, а не заводская калибровка.
Сцена использует нулевую гравитацию и суставной position controller для
удержания позы и выполнения команд с ограниченной скоростью.
При нулевых углах суставов фланец и камера инструмента направлены вверх.
Для осмотра стола этой камерой задайте соответствующую рабочую позу в robot.joints.
Камеры и запись
Это приближение 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, raycaster, uv exclusions.