17 KiB
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 мм. Это геометрическое приближение,
исключающее измерение собственного корпуса, а не заводская калибровка.
Сцена использует гравитацию [0, 0, -9.81] м/с². У робота включена полная
компенсация гравитации и суставной position controller для удержания позы и
выполнения команд с ограниченной скоростью. Свободный инструмент подчиняется
гравитации и контактам.
При нулевых углах суставов фланец и камера инструмента направлены вверх.
Для осмотра стола этой камерой задайте соответствующую рабочую позу в robot.joints.
Случайный молоток на столе
В configs/scene.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 со столом (может требовать несколько минут на первичное разложение мешей и компиляцию):
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, raycaster, uv exclusions.