ManiSkill 工具库深度指南:任务构建、场景管理、几何计算与 RL 训练基础设施
【免费下载链接】ManiSkillManipulation Skill Framework, an open source GPU parallelized robotics simulator and benchmark项目地址: https://gitcode.com/GitHub_Trending/ma/ManiSkill
本指南系统梳理 ManiSkill 项目mani_skill/utils工具库的完整能力:从任务与场景构建(Actor/Articulation Builder、SceneBuilder 及各类预置场景)、几何工具、环境 Wrapper、可视化,到针对 GPU 并行仿真优化的通用工具(张量/字典操作、gymnasium 适配与资产下载)。读者将掌握在 ManiSkill 中快速构建自定义任务、复用预置场景、适配主流 RL 库(如 Stable Baselines 3)并完成训练、评估与数据采集的完整工程化路径。
一、工具库全景:一个围绕 GPU 并行仿真的基础设施层
mani_skill/utils/README.md开篇即点明该目录的定位:"各种帮助 ManiSkill 正常工作的函数与工具,同时帮助你构建自己的任务、在其上训练并进行评估"。它并非一个独立模块,而是贯穿环境构建、仿真控制、观测处理、RL 训练与可视化全链路的基础设施层。
整个目录(mani_skill/utils)的顶层结构如下:
building/—— 构建任务/场景的全部实用代码,包括从多种数据集加载资源(actor、articulation、URDF/MJCF)与用于随机化任务初始化的函数;scene_builder/——SceneBuilder类及若干预置场景构建器:标准桌面场景、ReplicaCAD 场景、以及通过 HSSD 数据集支持的 AI2THOR 场景;geometry/—— 几何工具,从基本形状采样到获取 articulation/actor 的轴对齐包围盒;wrappers/—— 环境包装器,提供视频/回合录制、修改观测空间,以及将环境 API 适配为 RL 库(如 Stable Baselines 3)开箱即用的形式;visualization/—— 可视化工具;gym_utils.py—— 用于 gymnasium/gym API 的各种工具;common.py—— 大量通用工具,包括常用于奖励函数、成功判定的函数,以及嵌套字典操作;- 此外还有
structs/(管理 SAPIEN 的 CPU/GPU 数据的结构体)、download_asset.py/download_demo.py(资产与演示数据下载)、sapien_utils.py(SAPIEN 相关辅助)、registration.py(环境注册)、tree.py/io_utils.py/logging_utils.py等辅助文件。
下文按 README 所述主线逐一深入,并结合源码验证其实现细节。
二、building/:任务与场景构建的底层积木
building/是"构建任务"这一核心诉求的直接落点。从 building/init.py 可以看到其对外导出的核心 API:
ActorBuilder—— 灵活构建单个 actor(刚体实体);ArticulationBuilder—— 构建带关节的 articulation(机械臂、夹具、抽屉等);MJCFLoader/URDFLoader—— 从 MuJoCo MJCF / URDF 描述文件加载机器人或复合物体;get_articulation_builder—— 按数据类型获取对应 articulation 构建器。
2.1 ActorBuilder:同时支持 CPU 与 GPU 仿真
actor_builder.py 中的ActorBuilder直接继承 SAPIEN 的ActorBuilder,其核心改动正如类注释所言:"修改 build 函数以支持一批场景(batch of scenes)并返回一批 Actor"。这使其天然服务于 ManiSkill 的 GPU 并行多环境(Vectorized Env)范式。
关键能力包括:
set_scene(scene)绑定ManiSkillScene,set_scene_idxs(...)指定在哪些子场景中构建该物体(默认在所有 env 中构建);build_dynamic(name)/build_kinematic(name)/build_static(name)三种刚体类型便捷入口;set_allow_overlapping_plane_collisions(v):在 GPU 多子场景并行时,默认只保留一个平面碰撞形状(否则会显著拖慢仿真),仅在确实需要时开启;build()强制要求唯一非空名称,并会将初始位姿广播到所有场景;在parallel_in_single_scene(单场景内并行)模式下自动叠加scene_offsets,实现多物体紧凑排布;add_plane_repeated_visual(...)程序化生成带纹理重复的地面网格(类似 MuJoCo 的texrepeat),无需外部资源文件。
从源码还可观察到两个工程细节:其一,未设置初始位姿时会打印告警,提示"不合理的初始位姿可能拖慢仿真";其二,碰撞形状支持 plane/box/capsule/cylinder/sphere/convex_mesh/nonconvex_mesh/multiple_convex_meshes 等多种类型,其中multiple_convex_meshes可配合coacd参数自动对网格做凸分解。
2.2 ArticulationBuilder:关节机构的一站式构建
articulation_builder.py 中的ArticulationBuilder同样继承自 SAPIEN,通过create_link_builder(parent)逐级构建关节链,并支持disable_self_collisions(为相关碰撞组设置掩码位以避免自碰撞)与set_scene_idxs多场景构建。它屏蔽了 SAPIEN 私有的build_entities,强制走build()流程以保证场景注册与状态管理正确。
2.3 加载器与预置物体
building/还提供两类资源加载入口:
urdf_loader.py/mjcf_loader.py:分别把 URDF 与 MuJoCo XML 解析为 ManiSkill 的 articulation 构建流程,这是仓库内大量机器人(如 panda、so100)进入仿真的统一途径;- actors/common.py 与 actors/ycb.py:提供常用物体的 actor 构建函数(含 YCB 数据集物体),配合
mani_skill/utils/assets/data.py中的DATA_GROUPS与DATA_SOURCES元数据即可按需下载。
三、scene_builder/:可跨任务复用的场景构建器
README 明确指出scene_builder/围绕SceneBuilder类组织,并提供了标准桌面、ReplicaCAD、AI2THOR(经 HSSD 数据集)等预置场景构建器。这正是 ManiSkill 实现"场景与任务解耦、跨任务复用"的机制。
3.1 SceneBuilder 基类的两阶段协议
scene_builder.py 定义了SceneBuilder基类,其核心是一个两阶段抽象:
build(build_config_idxs):只负责把物体构建进场景(创建 actor/articulation builder),不初始化位姿、qpos、速度——对应env.reset(seed=seed, options=dict(reconfigure=True))时触发的场景重建;initialize(env_idx, init_config_idxs):负责初始化场景,如设置所有物体的位姿、改变 articulation/机器人 的 qpos,对应常规env.reset()。
围绕这两阶段,基类提供了配套的状态与机制:
build_configs/init_configs:场景配置列表(可为字典、JSON 文件路径或其他数据),供重建/初始化时索引或采样,从而实现场景级随机化;sample_build_config_idxs()/sample_init_config_idxs():默认按torch.randint在每个环境独立采样配置下标,开发者可按需覆写以定制随机化策略;scene_objects/movable_objects/articulations:分别记录构建出的全部 Actor(含静态/运动学)、动态 Actor 子集与 Articulation,其中movable_objects常用于任务初始化时查询可移动物体;navigable_positions:为移动机器人提供每环境的可通行位置(例如从 navmesh 加载),方便初始化;- 类属性
robot_init_qpos_noise(默认 0.02)与robot_initial_pose控制机器人初始 qpos 噪声与初始位姿;builds_lighting声明场景构建器是否自带光照。
3.2 注册机制:按字符串 UID 使用场景构建器
registration.py 提供了register_scene_builder(uid, override=False)装饰器,把自定义SceneBuilder子类注册进全局REGISTERED_SCENE_BUILDERS字典,之后即可通过字符串 UID 直接引用。该文件同时定义了SceneBuilderSpecdataclass 封装构建器类,为未来扩展元数据预留了空间。这与任务/机器人注册(registration.py)保持了一致的"装饰器注册 + 字符串寻址"风格。
3.3 仓库内预置场景构建器
scene_builder/目录下的预置实现与 README 描述一一对应:
- table/:标准桌面场景,是绝大多数 tabletop 任务(如 PickCube、StackCube)的基础;
- replicacad/:ReplicaCAD 场景,面向具身智能研究的高保真室内环境;
- ai2thor/:基于 AI2THOR 风格与 HSSD 数据集构建的室内场景,支持移动机器人与导航任务(ManiSkill-HAB 等);
- 此外还有 robocasa/、kitchen_counter/ 与 control/(控制类场景),共同构成场景库。
四、geometry/:几何采样、姿态计算与包围盒
geometry/提供纯几何函数,是任务初始化随机化(物体/机器人位姿采样)与物理量计算(包围盒、角度距离)的数学基础,包含 geometry.py、rotation_conversions.py、trimesh_utils.py 与 bounding_cylinder.py 四个文件。
从 geometry.py 源码可确认以下函数族:
- 采样类:
sample_on_unit_sphere(rng)(用正态分布拒绝采样保证球面均匀分布)、sample_on_unit_circle(rng),用于在球面/圆周上随机取方向; - 向量/旋转类:
rotation_between_vec(a, b)(返回从向量 a 转到 b 的 scipy Rotation)、angle_between_vec(a, b)、rotate_2d_vec_by_angle(vec, theta); - 四元数转换类:
wxyz_to_xyzw(q)与xyzw_to_wxyz(q),处理 SAPIEN(wxyz)与常见库(xyzw)之间的四元数约定差异; - 姿态度量类:
angle_distance(q0, q1)计算两个sapien.Pose之间的归一化角度距离; - 包围盒类:
get_axis_aligned_bbox_for_articulation(art)与get_axis_aligned_bbox_for_actor(actor),遍历碰撞形状的顶点并变换到世界坐标系求 AABB,是确定物体占位、避免初始重叠的核心函数。
结合common.py中的compute_angle_between/quat_diff_rad(支持 torch 批量张量),可以推断出:CPU 侧场景构建常用geometry/的 numpy 版本,而 GPU 并行环境内的批量计算则走common.py的 torch 版本,二者形成互补。
五、wrappers/:开箱即用的环境增强与 RL 适配
README 强调wrappers/提供三类能力:录制视频/回合、修改观测空间、把环境 API 适配成 RL 库(如 Stable Baselines 3)开箱即用。从 wrappers/init.py 可确认当前公开的全部包装器:
| 包装器 | 文件 | 作用 |
|---|---|---|
ActionRepeatWrapper | action_repeat.py | 动作重复(每个动作执行 k 步),减少决策频率 |
CachedResetWrapper | cached_reset.py | 缓存 reset 结果以加速并行采样 |
FlattenActionSpaceWrapper/FlattenObservationWrapper/FlattenRGBDObservationWrapper | flatten.py | 展平动作/观测空间,适配需要一维向量输入的算法 |
FrameStack | frame_stack.py | 观测帧堆叠,为策略提供时序信息 |
CPUGymWrapper | gymnasium.py | 把 GPU 并行的 ManiSkill 环境包装为经典单环境 gymnasium 接口 |
RecordEpisode | record.py | 录制回合视频/轨迹 |
| (另有) | visual_encoders.py | 视觉编码器辅助(如视觉观测预处理) |
其中CPUGymWrapper正是"RL 库开箱即用"的关键:它把 ManiSkill 的多环境批量接口折叠成标准gymnasium.Env,从而可直接接入 Stable Baselines 3 等框架(仓库 examples/baselines/stable_baselines3/example.py 提供了完整示例)。对于 GPU 并行训练,vector/wrappers 下还提供ManiSkillVectorEnv及 sb3 专用 vector wrapper,与gym_utils.find_max_episode_steps_value中检测ManiSkillVectorEnv的逻辑相呼应。
六、visualization/:渲染、贴图与视频导出
visualization/init.py 对外提供:
display_images(...)(jupyter_utils.py):在 Jupyter Notebook 中内联展示多张图片,便于交互式调试观测;images_to_video(...)(misc.py):把一帧帧渲染图合成视频文件,是生成演示视频、训练过程回放的基础;put_text_on_image(...)/put_info_on_image(...)/tile_images(...):在图像上叠加文本/环境信息、将多图拼接为网格图;ImageRenderer(renderer.py):离屏渲染器,可在无窗口环境(如服务器、CI)中渲染画面。
仓库自带的UbuntuSansMono-Regular.ttf字体文件用于保证文本叠加在任意环境下的显示一致性。
七、gym_utils.py:gymnasium 生态的适配与规范化
gym_utils.py 是面向 gymnasium/gym 生态的工具集,重点解决观测/动作空间处理与归一化问题,并内建了 gymnasium 1.x 的版本探测(IS_GYMNASIUM_1)。核心函数包括:
find_max_episode_steps_value(env):递归穿透各种 wrapper(SyncVectorEnv、ManiSkillVectorEnv、普通 wrapper 链)与env.spec,寻找回合最大步数——这是 GPU 仿真下正确实现 TimeLimit 的前提;对AsyncVectorEnv会显式抛NotImplementedError;extract_scalars_from_info(info, blacklist=(), batch_size=1):从env.step返回的 info 字典中递归抽取标量指标(跳过 None、字符串与黑名单键),并支持 batch 模式(batch_size>1时对每环境抽取一列),常用于日志记录与指标上报;clip_and_scale_action(action, low, high)/inv_scale_action(...):把动作裁剪到 [-1, 1] 并按 [low, high] 范围线性缩放(及其逆变换),是控制器与策略之间动作规范化的标准做法;normalize_action_space(action_space):将任意 Box 动作空间归一化为 [-1, 1];get_dtype_bounds(dtype):求 numpy 类型的取值范围(浮点/整型/布尔),供构建空间使用;convert_observation_to_space(observation, prefix="", unbatched=False):把(可能嵌套的)观测样本递归转换为 gymnasium 空间对象,并特别用spaces.Dict保留键的插入顺序(避免 Dict 默认排序导致的空间错位)。
八、common.py:奖励函数、成功判定与嵌套字典的"瑞士军刀"
README 特别强调 common.py 包含"大量相当通用的工具,尤其是奖励函数、成功判定与嵌套字典操作"。通读源码(417 行)可将其划分为四个功能族:
8.1 张量 / numpy / 批量数据转换
batch(...)/unbatch(...):为数据整体添加/移除首维(batch 维度),对字典则递归作用于每个叶子节点,对(1,)形状的 numpy 数组会item()解包标量;to_tensor(array, device=None):把任意序列/字典递归映射为 torch 张量;device为 None 时跟随 physx GPU 是否开启;自动把float64降为float32(GPU 物理仿真默认精度)、把uint16/uint32安全提升为int32/int64;to_cpu_tensor(...)/to_numpy(array, dtype=None):CPU 张量 / numpy 互转,同样递归处理嵌套字典。
8.2 字典操作
torch_clone_dict(data):递归克隆字典中所有 torch 张量,避免训练时意外共享内存;dict_merge(dct, merge_dct):原地递归合并字典(同名嵌套字典深合并);merge_dicts(ds, asarray=False):将多个同构字典按键合并(支持asarray=True时 np.concatenate 拼接),并断言各键长度一致;append_dict_array(x1, x2):把 x2 追加到 x1 之后(尽量原地),自动处理"批量模式单环境多出的长度为 1 的维度";index_dict_array(x1, idx, inplace=True):按切片索引字典内所有数组;flatten_dict_keys(d, prefix=""):把嵌套字典按键路径(如"a/b/c")展开为一维字典。
8.3 状态展平与向量度量
flatten_state_dict(state_dict, use_torch=False, device=None):递归把嵌套状态字典水平拼接为一个向量(torch 或 numpy),若某值 ndim > 2 则抛AssertionError;由于 Python 3.7+ 字典保序,拼接顺序确定——这是把结构化观测喂给 MLP 策略的标准路径;normalize_vector/np_normalize_vector:向量归一化(范数小于eps=1e-6时置 0 以规避除零);compute_angle_between/np_compute_angle_between:向量夹角(弧度),torch 版本支持批量;quat_diff_rad(a, b):两个四元数之间的弧度差,先归一化、夹取点积到 [-1, 1] 保证数值稳定,返回形状 (N,)——这是旋转误差类奖励函数的核心实现,其向量化写法与 GPU 并行多环境天然契合。
这些函数在仓库任务中被大量复用:例如基于 rotation_conversions.py 的姿态变换与quat_diff_rad共同支撑了旋转对齐奖励,而to_tensor/batch则是所有观测处理管线(见 mani_skill/envs/utils/observations)的地基。
九、配套设施:资产下载、注册、日志与结构体
README 虽未逐项展开,但工具库中还包含几个支撑性模块,对实际使用至关重要:
- download_asset.py:资产下载入口。支持按"asset UID"(如具体环境 ID)、资产组或
all下载全部资产;提供-l/--list(按scene、robot、task_assets、objects分类列出可下载 UID)、-y/--non-interactive(跳过交互提示,MS_SKIP_ASSET_DOWNLOAD_PROMPT=1亦可)、-o/--output-dir等参数;下载时会做 SHA-256 校验,支持 Hugging Face dataset 快照下载与 zip 自动解压、统一顶层目录; - download_demo.py:按环境 ID 下载演示轨迹数据;
- registration.py:环境注册表(
register_env),支撑env_id字符串到环境类的映射与max_episode_steps等元数据管理; - logging_utils.py:统一日志封装(
logger),支持终端彩色输出、文件落盘与进程间日志同步; - sapien_utils.py:SAPIEN 对象与 ManiSkill 结构体之间的桥接辅助(如
get_articulation_kinematics等,共 477 行); - structs/:README 描述其为"管理 SAPIEN CPU/GPU 数据的 dataclass/structs 集合,用于抽象掉繁琐的 GPU 内存管理代码",其中的
Pose、Actor、Articulation等结构体(如 pose.py、actor.py)是全部构建与仿真代码的公共类型基础。
十、实战组合:从自定义任务到 RL 训练的最小闭环
综合上述模块,可以勾勒出一条完整的实践链路(对应仓库 minimal_template.py 与 examples/baselines 中的训练示例):
- 构建场景:继承
SceneBuilder,在build()中用ActorBuilder/ArticulationBuilder构建物体,在initialize()中结合 geometry/ 的采样函数随机化位姿;若使用桌面、ReplicaCAD 或 AI2THOR 场景,直接复用 scene_builder/ 下的预置实现,并用@register_scene_builder(uid)注册; - 编写任务:在自定义
BaseEnv子类中,用 common.py 的quat_diff_rad、to_tensor等实现奖励与成功判定,用convert_observation_to_space生成观测空间; - 下载资产:首次运行前用
python -m mani_skill.utils.download_asset <env_id>(等价于python mani_skill/utils/download_asset.py <uid>)拉取所需数据集; - 包装与训练:训练脚本中按需叠加
RecordEpisode、FrameStack、FlattenObservationWrapper等 wrappers;单环境经典 RL 库(SB3)使用CPUGymWrapper,GPU 并行训练则直接使用原生 vector 环境(参考 ppo.py); - 可视化与回放:用
images_to_video、display_images生成演示/训练过程视频,用 trajectory/replay_trajectory.py 回放录制的回合数据。
结语
mani_skill/utils是 ManiSkill"GPU 并行化机器人仿真"能力的工程底座:building/与scene_builder/负责把资源高效变为可并行仿真的世界,geometry/与common.py提供数学与数据结构地基,wrappers/与gym_utils.py打通与主流 RL 生态的接口,visualization/与下载工具则覆盖了从数据获取到结果展示的完整工作流。无论你是要构建一个全新的自定义任务、复用一个室内场景,还是把 ManiSkill 环境接入现有 RL 框架,本指南所述的模块与源码路径都可作为直接的检索与上手入口。
【免费下载链接】ManiSkillManipulation Skill Framework, an open source GPU parallelized robotics simulator and benchmark项目地址: https://gitcode.com/GitHub_Trending/ma/ManiSkill
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考