Основы симуляции и робототехники
В этой главе собраны базовые понятия симуляции и робототехники, которые помогают глубже разобраться в технических деталях ManiSkill: что такое поза, как использовать кватернионы, что такое Actor и Articulation и т. д.
Основные термины и соглашения
- Поза (Pose): сочетание положения и ориентации объекта в трёхмерном пространстве. В ManiSkill/SAPIEN поза состоит из трёхмерного положения и четырёхмерного кватерниона.
- Кватернион (Quaternion): математический инструмент, который часто используется для описания поворота и ориентации; состоит из четырёх чисел. ManiSkill/SAPIEN использует кватернионы в формате wxyz. Подробнее о представлении поворотов в симуляции см. в этой статье.
- Ось Z — «вверх»: в ManiSkill/SAPIEN ось Z считается стандартным направлением «вверх». Поэтому такой предмет, как бокал, стоящий прямо, имеет длинную ось вдоль оси Z.
Объекты симуляции
Для симуляции твёрдых тел, то есть предметов, которые практически не деформируются (деревянный брусок, компьютер, стена и т. д.), ManiSkill/SAPIEN предоставляет два основных типа объектов: Actor и Articulation.
В процессе симуляции обычно начинают с этапа реконфигурации, на котором все объекты загружаются в симуляционную среду. После загрузки задаются позы всех объектов и выполняется их инициализация.
Actor
Actor — обычно «цельный» объект: при внешнем воздействии он движется как единое целое и не деформируется. Например, бейсбольная бита, стакан, стена — всё это можно считать Actor. У Actor есть такие свойства:
- Поза (pose): положение и ориентация объекта в трёхмерном пространстве. Положение задаётся в метрах.
- Линейная скорость (linear velocity): скорость поступательного движения по осям x, y, z, в метрах в секунду.
- Угловая скорость (angular velocity): угловая скорость вокруг осей x, y, z, в радианах в секунду.
В симуляции Actor состоит из двух основных элементов: формы коллизий и визуальной формы.
Форма коллизий:
Форма коллизий определяет, как объект физически взаимодействует в симуляции. Actor может состоять из нескольких выпуклых форм коллизий.
Стоит отметить, что у Actor не обязательно есть форма коллизий: это могут быть «призрачные» объекты, которые нужны только для визуальной индикации и не участвуют в физическом взаимодействии.
Визуальная форма:
Визуальная форма определяет внешний вид объекта при рендеринге, но не влияет на физическую симуляцию.
Типы Actor: динамический, кинематический, статический
Actor бывает трёх типов:
- Динамический (Dynamic): такие Actor полностью участвуют в физической симуляции. При приложении внешней силы они реагируют по законам физики.
- Кинематический (Kinematic): такие Actor участвуют в физической симуляции частично. При приложении внешней силы они не деформируются и не смещаются. Однако динамические объекты, которые с ними взаимодействуют, испытывают реакцию. По сравнению с динамическими Actor кинематические занимают меньше ресурсов CPU/GPU и симулируются быстрее.
- Статический (Static): похож на кинематический, но после загрузки в симуляционную среду его позу изменить нельзя. Он занимает меньше ресурсов CPU/GPU и симулируется быстрее. Стены, пол, шкафы обычно моделируют как кинематические или статические Actor, потому что в реальности они обычно не двигаются и не разрушаются.
В зависимости от задачи некоторые объекты может понадобиться сделать динамическими. Например, при моделировании задачи «переложить чашку со стола на полку» чашка должна быть динамическим Actor, а полка может быть кинематическим или статическим Actor.
Articulation (сочленённый механизм)
Articulation состоит из звеньев (Links) и суставов (Joints). В ManiSkill/SAPIEN каждые два звена соединены суставом. Articulation обычно задаётся через XML или древовидную структуру, чтобы описывать сложные механизмы. Например, шкаф, холодильник и автомобиль можно считать Articulation.
Звенья (Links)
Звенья похожи на Actor: у них те же свойства, их можно симулировать и манипулировать ими. Отличие в том, что звено обязательно связано с другим звеном определённым суставом.
Суставы (Joints)
Суставы бывают трёх основных типов: фиксированные, вращательные и призматические.
- Фиксированный сустав (Fixed Joint): соединяет два звена так, что их взаимное положение остаётся неизменным. Это полезно при описании Articulation, потому что звенья, связанные фиксированным суставом, по сути можно рассматривать как единое целое.
- Вращательный сустав (Revolute Joint): похож на шарнир; соединённые звенья могут вращаться вокруг оси сустава.
- Призматический сустав (Prismatic Joint): соединённые звенья могут скользить вдоль оси сустава.
Пример
Рассмотрим шкаф. У него есть основание, верхний ящик и нижняя дверца, то есть три звена.
- Нижний ящик соединён с основанием призматическим суставом, который позволяет ящику скользить в определённом направлении.
- Нижняя дверца соединена с основанием вращательным суставом, который позволяет двери поворачиваться вокруг оси.
Понимая эти базовые понятия, можно глубже участвовать в разработке ManiSkill и применении, создавая более сложные и реалистичные сцены симуляции.
Симуляция на GPU
ManiSkill использует PhysX для физической симуляции на GPU. Этот подход отличается от традиционной симуляции на CPU; подробности ниже. Рекомендуется прочитать этот раздел, чтобы разобраться в основах GPU-симуляции и принципах проектирования ManiSkill; это поможет писать более эффективный код и строить оптимизированные GPU-параллельные задачи.
Сцены и подсцены
В рамках GPU-параллелизации на GPU можно одновременно симулировать тысячи задач. В ManiSkill/SAPIEN это реализовано так: все Actor и Articulation помещаются в одну сцену PhysX, а для каждой задачи в этой сцене создаётся небольшое рабочее пространство, которое называется подсцена.
Подсцены устроены так, что при чтении, например, поз Actor данные автоматически переводятся в систему координат относительно центра подсцены, а не всей сцены PhysX. На рисунке показано, как организованы 64 подсцены. Расстояние между подсценами задаётся параметром sim_config.spacing в конфигурации симуляции, который можно указать при построении задачи.
SAPIEN позволяет размещать подсцены в любых местах, но ManiSkill обычно выбирает квадратную компоновку с фиксированным параметром расстояния. Важно учитывать: если объекты одной подсцены выходят за пределы её рабочего пространства, это может повлиять на другие подсцены. Пользователи часто сталкиваются с этим при симуляции больших сцен (например, домов или открытых пространств): если параметр расстояния задан слишком маленьким, объекты подсцены 0 могут взаимодействовать с объектами подсцены 1.
Жизненный цикл GPU-симуляции
В ManiSkill для создания, сброса и продвижения среды используется Gym API. Процесс env.reset включает однократную реконфигурацию и затем шаги инициализации:
- Реконфигурация: загрузка объектов (Actor, Articulation, источников света) в сцену, то есть их появление в начальных позах.
- Вызов
physx_system.gpu_init()для инициализации всех буферов памяти GPU и настройки групп рендеринга для параллельного рендеринга. - Инициализация всех Actor и Articulation (задание поз, значений qpos и т. д.).
- Выполнение
physx_system.gpu_apply_*, чтобы сохранить данные, инициализированные на шаге 3, в буферы GPU и подготовить симуляцию. - Выполнение
physx_system.gpu_update_articulation_kinematics()для обновления данных Articulation (например, поз звеньев), чтобы их можно было получить. - Выполнение
physx_system.gpu_fetch_*для обновления соответствующих буферов GPU и формирования наблюдений.
В коде переменная physx_system доступна как env.scene.px.
Процесс env.step включает многократное выполнение таких шагов для обработки действия и формирования результата:
- Получить действие пользователя (при необходимости обрезать его).
- Обработать действие и преобразовать его в управляющие сигналы (например, положения или скорости суставов) для агента.
- Выполнить
physx_system.gpu_apply_articulation_target_positionиphysx_system.gpu_apply_articulation_target_velocity, чтобы применить цели из шага 2. - Выполнить
physx_system.step(), чтобы продвинуть симуляцию. - Выполнить
physx_system.gpu_fetch_*, чтобы обновить буферы GPU и сформировать наблюдения. - Вернуть данные шага: наблюдения, награду, флаги завершения, флаги обрыва и прочую информацию.
Организация данных на GPU
Твёрдотельные данные каждого жёсткого Actor и каждого звена Articulation в каждой подсцене (поза (7D), линейная скорость (3D) и угловая скорость (3D)) плотно упакованы в physx_system.cuda_rigid_body_data, образуя большую матрицу. Её организация такая:
[Данные Actor 1] [Данные Actor 2] ... [Данные звена 1 Articulation 1] [Данные звена 2 Articulation 1] ... [Данные звена M Articulation N]
Тем, кто напрямую работает с буферами GPU, полезно понимать такую организацию. В остальных случаях эти детали обрабатываются автоматически при использовании API ManiSkill.
Стоит учитывать, что такая организация буферов GPU может не выглядеть интуитивно (например, каждые k строк не обязательно относятся к одной подсцене): это компромисс ради производительности. Например, ниже показано, как организованы данные, если сцена PhysX содержит 3 жёстких Actor (красным) и 3 Articulation с разным числом звеньев и степеней свободы (DOF) (зелёным). SAPIEN дополняет число строк для каждого Articulation до максимального числа степеней свободы среди всех Articulation в сцене PhysX.
Принципы проектирования ManiSkill
Пакетировать всё
ManiSkill рассчитан на параллельную симуляцию как на CPU, так и на GPU. Причина в том, что для некоторых задач даже в неиндустриальных условиях GPU-симуляция не обязательно быстрее, чем использование большего числа CPU. Поэтому почти весь код ManiSkill предоставляет данные пользователю в пакетном виде (размер пакета = число параллельных сред), а симуляция на CPU с размером пакета 1 рассматривается как частный случай.
Управление объектами и представлениями
ManiSkill можно рассматривать как Python-интерфейс к SAPIEN.
Контроллеры / пространство действий
Контроллер — это интерфейс между пользователем/политикой и роботом. Каждый раз, когда в среде делается шаг и передаётся действие, оно отправляется выбранному контроллеру, который переводит его в управляющие сигналы робота. На самом низком уровне все роботы в симуляции управляются через управление положением или скоростью суставов: фактически задаётся, в какую позицию или с какой скоростью должен прийти каждый сустав.
Например, контроллер arm_pd_ee_delta_pose принимает на вход относительное перемещение концевого эффектора и с помощью обратной кинематики переводит входное действие в целевые положения суставов робота. Робот использует PD-регулятор, чтобы приводить двигатели в нужные целевые положения суставов.
В ManiSkill есть несколько важных моментов о контроллерах:
- Контроллер определяет пространство действий задачи.
- У робота могут быть независимые контроллеры для разных групп суставов. Пространство действий — это конкатенация пространств действий всех контроллеров.
- У одного робота может быть несколько доступных наборов контроллеров.
Далее подробно описан каждый встроенный контроллер и его функции.
Passive (пассивный)
from mani_skill.agents.controllers import PassiveControllerConfig
Этот контроллер позволяет зафиксировать заданные суставы так, чтобы действие на них не влияло. Например, в среде CartPole шарнирный сустав робота CartPole делают пассивным, то есть разрешают управлять только скольжением коробки.
PD Joint Position (PD-положение сустава)
from mani_skill.agents.controllers import PDJointPosControllerConfig
С помощью PD-регулятора действием задаётся положение указанных суставов.
PD EE (концевой эффектор) Pose (поза)
from mani_skill.agents.controllers import PDEEPoseControllerConfig
Этот контроллер существует в вариантах по позе и по положению и позволяет более интуитивно управлять концевым эффектором робота (или любым звеном цепи). Настройка по умолчанию выбрана как наиболее интуитивная, но предусмотрены и другие варианты.
Чтобы понять, как он работает, сначала нужно знать три связанные системы координат:
- Мировая система координат.
- Система координат корневого звена.
- Система координат концевого эффектора/звена.
На схеме эти системы координат показаны RGB-осями: красная — ось X, зелёная — ось Y, синяя — ось Z. Целевое управляемое звено — виртуальное звено, которое задаёт точку управления инструментом (TCP); это простое смещение от звена концевого эффектора, поэтому его начало находится между двумя пальцами захвата. Обратите внимание: в ManiSkill/SAPIEN ось Z обычно считается естественным направлением «вверх-вниз», что отличается от некоторых других симуляторов.
В этом контроллере перемещение и вращение концевого эффектора управляются раздельно. Это значит, что действие для перемещения не влияет на действие для поворота концевого эффектора. Таким образом получаем 6 степеней управления: 3 для трёхмерного перемещения и 3 для вращения.
Контроллер поддерживает два режима: инкрементный (относительный) и абсолютный. На каждом шаге среды при заданном действии ManiSkill вычисляет новую целевую позу концевого эффектора, а затем с помощью обратной кинематики находит действия над суставами, которые лучше всего достигают этой позы. Конфигурация контроллера определяет, как вычисляется новая целевая поза.
Инкрементный режим
Этот режим включён по умолчанию и настраивается через свойство use_delta. Он позволяет пользователю передавать действия, которые задают приращения позы концевого эффектора для движения к цели. Есть четыре комбинации систем координат, которые возникают из двух вариантов для перемещения и двух вариантов для вращения. Система координат задаётся свойством frame; имена формируются по правилу:
# Правило именования: <frame>_translation:<frame>_rotation
# Ниже четыре возможные комбинации систем координат
"body_translation:root_aligned_body_rotation",
"root_translation:root_aligned_body_rotation",
"body_translation:body_aligned_body_rotation",
"root_translation:body_aligned_body_rotation",
# Комбинация по умолчанию
"root_translation:root_aligned_body_rotation"
Перемещение
В этом контроллере пользователь задаёт приращения по осям X, Y и Z (если не нормированы, в метрах), которые означают расстояние перемещения по каждой из этих осей. Затем с помощью обратной кинематики определяются действия над суставами, которые дают нужное перемещение.
В ManiSkill определены две системы координат для позиционного перемещения: корневая и системы координат тела. Перемещение в каждой из этих систем получается, если задать соответствующие измерения действия больше нуля, а остальные — равными нулю.
Вращение
Для вращения пользователь задаёт приращения поворота по осям X, Y и Z (если не нормированы, в радианах), которые означают углы поворота вокруг каждой из осей. Они обрабатываются как углы Эйлера XYZ и внутри переводятся в кватернионы. Затем с помощью обратной кинематики определяются действия над суставами, которые дают нужный поворот.
В ManiSkill реализованы два типа управления вращением, которые обычно считаются наиболее интуитивными и часто используются в реальных роботах: выравнивание одной системы координат относительно другой с сохранением её ориентации. Поддерживаются два варианта: выравнивание по корневому звену и выравнивание по телу. Выравнивание A по B означает поворот в системе координат, которая имеет ту же ориентацию, что и A, но то же положение, что и B. Оба варианта вращения показаны ниже через задание соответствующих измерений действия больше нуля, а остальных — равными нулю.
Режимы наблюдения
Пространство наблюдений
Режим наблюдения определяет пространство наблюдений. Все задачи ManiSkill получают режим наблюдения (obs_mode) как входной параметр при вызове gym.make(env_id, obs_mode=...).
Обычно наблюдение организовано в виде словаря (пространство наблюдений — gym.spaces.Dict).
Есть три исходных режима наблюдения: state_dict (привилегированное состояние), sensor_data (сырые данные датчиков, например необработанные визуальные данные) и state+sensor_data (и то и другое). state — это уплощённая версия state_dict. rgb+depth, rgb+depth+segmentation (или любая комбинация rgb, depth, segmentation) и pointcloud — это постобработка sensor_data для удобного представления визуальных данных. state_dict+rgb вернёт привилегированное непроуплощённое состояние и визуальные данные, модальности можно смешивать по необходимости.
Ниже подробно описаны формы непакетированных данных. Обычно возвращаемые данные всегда имеют измерение пакета, кроме случая CPU-симуляции, когда данные возвращаются как тензоры torch. Кроме того, для некоторых значений указан тип данных.
state_dict
Наблюдение — словарь состояния. Обычно он содержит привилегированную информацию, например позы объектов. Для мягкотелых задач этот режим не поддерживается.
agent: проприоцепция робота (значение, возвращаемое функцией_get_obs_agentзадачи).qpos: текущие положения суставов, форма [nq], гдеnq— число степеней свободы.qvel: текущие скорости суставов, форма [nq].controller: состояние контроллера, которое зависит от используемого контроллера; обычно пустой словарь.
extra: словарь информации, специфичной для задачи, например позиции цели, позиция концевого эффектора. Это значение, возвращаемое функцией_get_obs_extraзадачи.
state
state — уплощённая версия state_dict. Пространство наблюдений — gym.spaces.Box.
sensor_data
Помимо agent и extra, вводятся sensor_data и sensor_param. Сейчас есть только датчики типа камеры. Камеры различаются в зависимости от используемого шейдера. Шейдер по умолчанию называется minimal: это самый быстрый и экономный по памяти вариант. Выбранный шейдер определяет, какие данные сохраняются в этом режиме наблюдения. Ниже описан сырой формат данных при шейдере minimal. Подробнее о том, как настраивать датчики и камеры, см. раздел sensors.
-
sensor_data: данные, полученные датчиками, сконфигурированными в среде.-
{sensor_uid}:Если данные получены с камеры:
Color: форма [H, W, 4], тип данныхtorch.uint8илиnp.uint8. Значения RGB+Alpha.PositionSegmentation: форма [H, W, 4], тип данныхtorch.int16илиnp.int16. Первые три измерения — координаты (x, y, z) в миллиметрах. Последнее измерение — идентификатор сегментации; подробнее см. раздел «Данные сегментации».
-
-
sensor_param: параметры каждого датчика, зависящие от его типа.-
{sensor_uid}:Если
sensor_uidсоответствует камере:cam2world_gl: форма [4, 4], преобразование из системы координат камеры в мировую (соглашение OpenGL/Blender).extrinsic_cv: форма [4, 4], внешние параметры камеры (соглашение OpenCV).intrinsic_cv: форма [3, 3], внутренние параметры камеры (соглашение OpenCV).
-
rgb+depth+segmentation
Можно запрашивать различные комбинации текстур в режиме наблюдения, просто соединяя нужные изображения (rgb, depth, segmentation, albedo, normal и т. д.) знаком +. Например, формат данных rgb+depth+segmentation такой же, как в режиме sensor_data, но все данные от камер заменяются следующей структурой:
-
sensor_data:-
{sensor_uid}:Если данные получены с камеры:
rgb: форма [H, W, 3], тип данныхtorch.uint8илиnp.uint8. RGB-изображение.depth: форма [H, W, 1], тип данныхtorch.int16илиnp.uint16. Единица — миллиметры. Значение 0 означает недопустимый пиксель (за пределами максимальной дальности камеры).segmentation: форма [H, W, 1], тип данныхtorch.int16илиnp.uint16. Подробнее см. раздел «Данные сегментации».
-
Обратите внимание, что эти данные не масштабированы и не нормированы в [0, 1] или [-1, 1], чтобы экономить память. Поэтому, если вы собираетесь обучаться на данных RGB, глубины или сегментации, масштабируйте их перед обучением.
ManiSkill по умолчанию гибко поддерживает разные комбинации данных RGB, глубины и сегментации: rgb, depth, segmentation, rgb+depth, rgb+depth+segmentation, rgb+segmentation и depth+segmentation. Модальности изображений, которые не выбраны, в наблюдение не включаются, что экономит память и пропускную способность GPU.
Ниже пример RGBD-изображений с двух камер:
Рисунок: RGBD-изображения с двух камер; показан вид робота Fetch в сцене из набора данных ReplicaCAD.
Режим pointcloud в ManiSkill
Режим наблюдения pointcloud даёт представление облака точек, объединяющее данные с нескольких камер; это подходит для задач, которым нужна пространственная геометрия.
pointcloud:xyzw: форма [N, 4], тип данныхtorch.float32илиnp.float32. Облако точек, объединённое со всех камер, в однородных координатах.w=0— точка на бесконечности (за пределами максимальной дальности камеры),w=1— все остальные точки.rgb: форма [N, 3], тип данныхtorch.uint8илиnp.uint8. Цвета соответствующих точек облака.segmentation: форма [N, 1], тип данныхtorch.int16илиnp.int16. Идентификатор сегментации каждой точки, показывающий, к какому объекту или области она относится. Подробнее см. раздел «Данные сегментации».
Учтите, что сами данные облака точек не содержат больше информации, если не указано иное.
Ниже пример данных облака точек с двух камер в сцене ReplicaCAD:
Рисунок: данные облака точек с двух камер; показан вид робота Fetch в сцене из набора данных ReplicaCAD.
Чтобы быстро увидеть визуализацию облака точек, выполните:
python -m mani_skill.examples.demo_vis_pcd -e "PushCube-v1"
Это покажет данные облака точек в задаче «PushCube-v1».
Данные сегментации
В ManiSkill каждому объекту при загрузке автоматически присваивается идентификатор сегментации (свойство per_scene_id объекта sapien.Entity). Чтобы узнать, какой Actor или звено соответствует каждому идентификатору, выполните такой код:
import gymnasium as gym
import mani_skill.envs
from mani_skill.utils.structs import Actor, Link
env = gym.make("PushCube-v1", obs_mode="rgbd")
for obj_id, obj in sorted(env.unwrapped.segmentation_id_map.items()):
if isinstance(obj, Actor):
print(f"{obj_id}: Actor, имя - {obj.name}")
elif isinstance(obj, Link):
print(f"{obj_id}: Link, имя - {obj.name}")
Обратите внимание: идентификатор 0 обычно обозначает далёкий фон.
Чтобы быстро увидеть визуализацию данных сегментации, выполните:
python -m mani_skill.examples.demo_vis_segmentation -e "PushCube-v1" # Нарисовать всю сегментацию
python -m mani_skill.examples.demo_vis_segmentation -e "PushCube-v1" --id cube # Показать только объект с именем "cube"
Это помогает понять и проанализировать сегментацию объектов в среде.
Датчики и камеры
На этой странице подробно описано, как использовать и настраивать датчики и камеры ManiSkill во время выполнения и в определениях задач и сред. В ManiSkill датчик — это «устройство», которое может захватывать определённые модальности данных. Сейчас поддерживается только тип датчика «камера».
Камеры
Камеры в ManiSkill могут захватывать данные нескольких разных модальностей и текстур. По умолчанию ManiSkill ограничивает их значениями rgb, depth, position (из него выводится глубина) и segmentation. Внутри ManiSkill использует SAPIEN как высокооптимизированную систему рендеринга, которая отображает разные модальности данных через шейдеры. Полную конфигурацию камеры можно найти в {py:class}mani_skill.sensors.camera.CameraConfig.
Для каждого шейдера есть предустановленная конфигурация, которая формирует данные в виде изображений; обычно из-за высокой оптимизации они имеют не очень удобный формат. ManiSkill использует систему конфигурации шейдеров на Python, чтобы привести эти разные шейдеры к более удобным текстурным форматам, таким как rgb и depth. Подробнее о том, какие текстуры генерируются каждым шейдером, см. раздел Шейдеры и текстуры.
В каждой среде ManiSkill есть 3 категории камер (хотя некоторые могут быть пустыми): датчики для наблюдения агента или политики; human_render_cameras для высококачественной записи видео для людей; и одна камера наблюдения, которую использует GUI-приложение для рендеринга среды.
При создании среды во время выполнения можно передать переопределения для этих камер. Например, следующий код переключает камеру для рендеринга человеку на шейдер трассировки лучей для фотореалистичного рендеринга, меняет ширину и высоту камер-датчиков на 320 и 240 и изменяет поле зрения (FOV) камеры наблюдения:
gym.make("PickCube-v1",
sensor_configs=dict(width=320, height=240),
human_render_camera_configs=dict(shader_pack="rt"),
viewer_camera_configs=dict(fov=1),
)
Эти переопределения действуют на всю категорию: sensor_configs=dict(width=320, height=240) меняет ширину и высоту каждой камеры-датчика, но не влияет на камеру для людей и камеру наблюдения.
Чтобы переопределить конкретную камеру, её можно указать по имени. Например, чтобы у камеры-датчика camera_0 были другие ширина и высота:
gym.make("PickCube-v1",
sensor_configs=dict(camera_0=dict(width=320, height=240)),
)
Теперь все остальные камеры-датчики сохранят ширину и высоту по умолчанию, а у camera_0 будут заданные параметры.
Такие специфические настройки полезны тем, кто хочет настроить рендеринг или сформировать наблюдения политики под свои задачи.
Шейдеры и текстуры
Ниже перечислены шейдеры, доступные в ManiSkill:
| Имя шейдера | Доступные текстуры | Описание |
|---|---|---|
| minimal | rgb, depth, position, segmentation | Самый быстрый шейдер с минимальным расходом памяти GPU. Фон всегда чёрный (обычно это цвет окружающего света) |
| default | rgb, depth, position, segmentation, normal, albedo | Баланс между скоростью и доступностью текстур |
| rt | rgb, depth, position, segmentation, normal, albedo | Шейдер, оптимизированный для фотореалистичного рендеринга трассировкой лучей |
| rt-med | rgb, depth, position, segmentation, normal, albedo | То же, что rt, но работает быстрее при немного меньшем качестве |
| rt-fast | rgb, depth, position, segmentation, normal, albedo | То же, что rt-med, но работает быстрее при немного меньшем качестве |
Ниже перечислены текстуры, доступные в ManiSkill. Обратите внимание: если не указано иное, все данные не масштабированы и не нормированы.
| Текстура | Форма | Тип данных | Описание |
|---|---|---|---|
| rgb | [H, W, 3] | torch.uint8 | Красный, зелёный и синий каналы изображения. Диапазон 0–255 |
| depth | [H, W, 1] | torch.int16 | Глубина в миллиметрах |
| position | [H, W, 4] | torch.int16 | Координаты x, y, z (в миллиметрах); 4-й канал такой же, как в данных сегментации |
| segmentation | [H, W, 1] | torch.int16 | Маска сегментации: уникальное целое число ID для каждого объекта |
| normal | [H, W, 3] | torch.float32 | Компоненты x, y, z нормали |
| albedo | [H, W, 3] | torch.uint8 | Красный, зелёный и синий каналы альбедо. Диапазон 0–255 |
Воспроизводимость и генерация случайных чисел
Как и многие симуляторы, ManiSkill использует генератор случайных чисел (RNG), чтобы рандомизировать всё в среде: геометрию объектов, позы объектов, текстуры и т. д. Эта рандомизация обычно происходит при сбросе среды.
Однако рандомизация усложняет воспроизводимость, особенно когда демонстрации генерируются на одном компьютере, а воспроизводятся на другом, и особенно при использовании GPU-симуляции или параллельных сред: обычно один seed определяет рандомизацию в каждой среде.
Есть два способа обеспечить воспроизводимость траекторий и демонстраций: зерновой RNG для пакета и состояния среды. Обычно нужно лишь гарантировать воспроизводимость случайных чисел при реконфигурации/загрузке среды (которая определяет, какие объекты и текстуры загружаются в среду) и при инициализации эпизода (которая определяет начальные положения и скорости объектов).
Воспроизводимость через RNG
Чтобы решить эту задачу, ManiSkill рекомендует использовать объект _batched_episode_rng среды, который является экземпляром BatchedRNG. Этот пакетный RNG работает так же, как np.random.RandomState, но теперь все выходные данные имеют дополнительное измерение пакета, равное числу параллельных сред. Кроме того, пакетный RNG инициализирует seed каждой параллельной среды из списка seed. Теперь генерация RNG детерминирована независимо от числа параллельных сред. При необходимости _batched_episode_rng[i] вернёт RNG i-й среды, чтобы выполнять выборку только для неё.
Когда пользователь вызывает env.reset(seed=x), если x — целое число, первая параллельная среда инициализируется seed x, а остальные получают seed, сгенерированные случайно на основе x. Для полной воспроизводимости пользователь может вызвать env.reset(seed=[x1, x2, ..., xn]): тогда список seed определит RNG каждой параллельной среды. Если вызвать env.reset() без seed, для каждой параллельной среды будет сгенерирован случайный seed.
У этого подхода есть недостаток: генерация RNG сейчас медленнее, чем пакетная генерация случайных чисел напрямую стандартными функциями torch/numpy. Поэтому рекомендуем использовать пакетный RNG эпизодов как минимум при реконфигурации среды (в ML-рабочих процессах реконфигурация среды во время обучения происходит нечасто). Инициализацию эпизода (которая происходит один раз за эпизод) можно обрабатывать следующим методом, использующим состояние среды.
Воспроизводимость через состояние среды
Состояние среды включает углы суставов, скорости суставов, позы, скорости всех объектов и т. д. Оно не включает такие детали, как текстуры объектов, фиксированные позы камер или жёсткость контроллеров робота.
Детали вроде геометрии и текстур объектов детерминированы при одинаковом seed, если их рандомизировать через объект _batched_episode_rng, описанный выше.
Для других типов состояния, которые входят в состояние среды, для обеспечения воспроизводимости можно сохранить эти состояния и задать их после создания среды. Если использован тот же seed, чтобы все объекты были одинаковыми, то установка состояния среды гарантирует, что объекты окажутся на правильных местах.