Link

参数

Link 通常不直接通过构造函数实例化,而是经由工厂方法Link.create或由Articulation的工厂方法内部创建。其字段含义如下:

  • articulation (Articulation, optional)
    该 link 所属的 :class:Articulation 对象。

    • 对于普通 Link,指向其所属的关节系统。
    • 对于由 :func:Link.merge 得到的「合并链接」,该字段会被置为 None(因不再有单一可引用的 articulation)。
  • name (str, optional)
    Link 的逻辑名称。

    • 对由 Articulation.create_from_physx_articulations 创建的 link,通常为去掉 articulation 前缀后的简化名称。
    • 对合并 link,可在 :func:Link.merge 中手动指定。
  • joint (ArticulationJoint, optional)
    当前 link 的父关节封装对象。

    • 对「视图/合并」link,对应的 joint 也同样是视图/合并 joint。
    • 对根 link(is_root == True),该 joint 通常为 None
  • meshes (Dict[str, List[trimesh.Trimesh]], optional)
    用户自定义 mesh 组名到 trimesh.Trimesh 列表的映射,用于缓存按需生成的可视化网格。
    例如:"handle" 分组可表示柜门把手的网格集合。

  • merged (bool, default: False)
    指示该 Link 是否由 :func:Link.merge 合并得到。

    • 若为 True,该对象管理来自多个底层 Link 的合并视图,其部分属性/语义与单一 link 略有差异(如 articulation 被清空)。

关键属性

  • pose (Pose)
    当前 link 在世界坐标系中的批量位姿。

    • 若启用 GPU 仿真(scene.gpu_sim_enabled == True),位姿会从 PhysX 的 GPU 缓冲区(cuda_rigid_body_data)中批量读取,并在 parallel_in_single_scene 模式下根据 scene.scene_offsets 做统一平移修正。
    • 若使用 CPU 仿真,则从每个底层 obj.entity_pose 构造对应的 :class:Pose 对象。
    • 支持批量赋值;在 GPU 模式下会直接写回对应的 CUDA 缓冲区。
  • per_scene_id (torch.Tensor, int32)
    每个受管 link 的逐场景分割 ID,形状为 (N,),其中 N 为管理的 link 数量。

    • 用于语义/实例分割渲染与后处理。
    • 值来源于对应 sapien entity 的 per_scene_id 字段。
  • index (torch.Tensor, int)
    每个受管 link 在其各自 articulation 中的 link 拓扑索引,形状为 (N,)

    • 注意:该索引不等同于 qpos / qvel 中的自由度索引;若需 DOF 级别索引,请使用对应 joint 的 index_q
  • is_root (torch.Tensor, bool)
    指示每个受管 link 是否为 articulation 的根 link,形状为 (N,)

    • Articulation.create_from_physx_articulations 中会断言:同一 Link 视图下的所有对象要么全为根,要么全为非根。

主要方法

  • Link.create(physx_links, scene, scene_idxs) (classmethod)
    从一组底层 physx.PhysxArticulationLinkComponent 创建一个批量管理的 Link 对象。

    • 参数
      • physx_links (List[physx.PhysxArticulationLinkComponent]):要封装的一组底层 link 组件(通常为多个并行环境中“相同语义”的 link)。
      • scene (ManiSkillScene):当前场景封装对象,用于访问 PhysX 系统与仿真配置。
      • scene_idxs (torch.Tensor):每个底层 link 对应的子场景索引(用于多场景并行管理)。
    • 返回:新的 Link 实例,具备 GPU 相关索引和刚体数据引用。
  • Link.merge(links, name=None) (classmethod)
    将一组 Link 对象合并为一个「视图 link」,用于统一访问多个 articulation/link 视图的数据。

    • 若所有参与合并的 link 都不是根 link,则会同时:
      • 合并对应的 :class:ArticulationJoint 和 :class:Articulation 对象;
      • 通过 :func:ArticulationJoint.create 构造合并后的 joint,并维护正确的 joint_index / active_joint_index 映射。
    • 合并后的 link 会:
      • 累积 _objs / _scene_idxs
      • 若指定 name,则将 merged_link.name = namemerged_link.joint.name = f"{name}_joints"
      • articulation 置为 None,并将 merged 标记为 True
  • render_shapes (property)
    返回当前 Link 管理的每个底层 link 对象的渲染形状列表(列表的列表)。

    • 对每个底层 obj.entity,通过 find_component_by_type(RenderBodyComponent) 获取其 render_shapes
    • 若某个实体未绑定渲染组件,则跳过。
  • get_visual_meshes(to_world_frame=True, first_only=False)
    基于 render_shapes 构造每个 link 的合并可视化网格(trimesh.Trimesh)。

    • 目前实现中结果未做缓存或预优化,频繁调用可能较慢。
    • 内部通过 get_render_shape_meshes + merge_meshes 合成单个 Trimesh
  • generate_mesh(filter, mesh_name)
    按给定过滤函数生成并缓存 mesh:

    • 参数
      • filter (Callable[[physx.PhysxArticulationLinkComponent, sapien.render.RenderShape], bool]):用于选择哪些 RenderShape 会被加入 mesh。
      • mesh_name (str):mesh 组的逻辑名称,将被用作 self.meshes 的键。
    • mesh_name 已存在,则直接返回缓存结果;否则按过滤条件构造新 mesh、存入 self.meshes[mesh_name] 并返回。
  • bbox(filter)
    根据过滤条件为每个受管 link 构造其合并 mesh 的包围盒(trimesh.primitives.Box)。

    • 过程与 generate_mesh 类似,但最终返回 mesh 的 bounding_box
  • set_collision_group_bit(group, bit_idx, bit)
    批量设置所有受管刚体中所有 collision shape 的某个碰撞组 bit。

    • 参数
      • group (int):要修改的碰撞组索引(在 ManiSkill 中通常使用 group == 2 来控制 link 之间的自碰撞屏蔽,以加速仿真)。
      • bit_idx (int):要修改的 bit 下标。
      • bit (int | bool):要写入的 bit 值(0/1False/True)。
    • 内部直接操作 SAPIEN/PhysX 的 collision_groups 数组。
  • set_collision_group(group, value)
    将所有 collision shape 的某个碰撞组整体设置为给定数值 value

    • 适合在高级任务中一次性重设整组碰撞关系。
  • set_pose(arg1) / pose 的 setter
    设置批量 link 的世界位姿。

    • 支持传入 :class:Posesapien.Pose 或数组类型(见 to_sapien_pose / vectorize_pose)。
    • GPU 模式下会考虑 parallel_in_single_scene,按 scene_offsets 将外部世界坐标转换为内部偏移坐标后再写入 cuda_rigid_body_data
  • get_articulation()
    返回当前 link 所属的 :class:Articulation 对象(若为合并 link,则通常为 None)。

  • get_index()
    返回 :attr:index,即每个受管 link 在其 articulation 拓扑中的索引。

  • get_joint()
    返回当前 link 对应的 :class:ArticulationJoint 封装对象。

  • get_name()
    返回 link 的逻辑名称(self.name)。


使用示例

from mani_skill.utils.structs import Articulation, Link

# 假设已从 ManiSkillScene 中获取到一个 Articulation 视图
articulation: Articulation = scene.articulation_views["robot"]

# 通过名称查找特定 Link
ee_link: Link = articulation.links_map["end_effector"]

# 读取/修改位姿(支持并行环境批量操作)
pose = ee_link.pose                     # Pose, shape: (N, 7) 或等价封装
new_pose = pose.clone()
new_pose[..., 2] += 0.1                 # 将末端执行器整体抬高 0.1 m
ee_link.pose = new_pose                 # 写回 GPU/CPU 仿真

# 基于渲染信息生成可视化 mesh,并缓存到 "handle" 分组
def handle_filter(link_comp, render_shape):
    # 用户可根据 name、材质、tag 等条件自定义过滤器
    return "handle" in render_shape.name

handle_meshes = ee_link.generate_mesh(handle_filter, mesh_name="handle")

# 调整碰撞组,屏蔽该 link 与其它 link 的自碰撞以提升仿真速度
ee_link.set_collision_group_bit(group=2, bit_idx=0, bit=False)
Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐