Isaac Gym 架构与核心概念详解

目录

  1. 核心层级结构
  2. 核心概念详解
  3. 概念关系图
  4. 工作流程
  5. 代码示例

核心层级结构

Isaac Gym 采用分层架构,从顶层到底层依次为:

Gym (gymapi.Gym)
  └── Sim (gymapi.Sim)
       └── Env (gymapi.Env)
            ├── Actor (gymapi.Actor)
            │    ├── Asset (gymapi.Asset)
            │    ├── Rigid Body (刚体)
            │    └── DOF (自由度/关节)
            ├── Sensor (传感器)
            │    ├── Camera
            │    ├── Force Sensor
            │    └── IMU
            └── Ground/Obstacles (地面/障碍物)

核心概念详解

1. Gym (Isaac Gym 实例)

定义: Isaac Gym 的最顶层接口,是整个仿真系统的入口点。

作用:

  • 管理所有仿真实例(Sim)
  • 提供创建和销毁仿真的接口
  • 管理全局资源和设备(GPU/CPU)

获取方式:

from isaacgym import gymapi
gym = gymapi.acquire_gym()

主要功能:

  • create_sim(): 创建仿真实例
  • load_asset(): 加载资产文件(URDF/MJCF)
  • create_viewer(): 创建可视化窗口
  • destroy_sim(): 销毁仿真实例

2. Sim (仿真实例)

定义: 一个独立的物理仿真世界,包含物理引擎、渲染器和所有环境。

作用:

  • 管理物理引擎(PhysX/Flex)
  • 管理渲染器
  • 包含多个并行环境(Env)
  • 执行物理计算和图形渲染

创建方式:

sim_params = gymapi.SimParams()
sim_params.dt = 1.0 / 60.0  # 时间步长
sim_params.gravity = gymapi.Vec3(0.0, 0.0, -9.81)
sim_params.physx.solver_type = 1
sim_params.use_gpu_pipeline = True

sim = gym.create_sim(
    compute_device_id=0,
    graphics_device_id=0,
    physics_engine=gymapi.SIM_PHYSX,
    sim_params=sim_params
)

主要功能:

  • simulate(): 执行物理仿真步进
  • fetch_results(): 获取仿真结果
  • step_graphics(): 更新图形渲染
  • render_all_camera_sensors(): 渲染所有相机

物理引擎选项:

  • SIM_PHYSX: NVIDIA PhysX(推荐,支持刚体和关节)
  • SIM_FLEX: NVIDIA Flex(支持软体和流体)

3. Env (环境句柄)

定义: 一个独立的仿真空间,可以包含多个演员(Actor)、传感器和障碍物。

作用:

  • 提供空间隔离(多个环境可并行运行)
  • 管理环境内的所有对象
  • 支持批量并行仿真(加速训练)

创建方式:

env_spacing = 5.0
env = gym.create_env(
    sim,
    lower=gymapi.Vec3(-env_spacing, -env_spacing, 0),
    upper=gymapi.Vec3(env_spacing, env_spacing, env_spacing),
    num_per_row=8  # 每行环境数量
)

特点:

  • 每个环境相互独立
  • 可以创建数千个并行环境
  • 适合强化学习的批量训练

4. Asset (资产)

定义: 机器人、物体或场景的模板定义,包含几何形状、物理属性、关节结构等。

作用:

  • 定义对象的结构和属性
  • 可重复使用(一个资产可创建多个演员)
  • 支持 URDF、MJCF 等格式

加载方式:

asset_root = "assets"
asset_file = "urdf/franka_description/robots/franka_panda.urdf"

asset_options = gymapi.AssetOptions()
asset_options.fix_base_link = False  # 基座是否固定
asset_options.disable_gravity = False  # 是否禁用重力
asset_options.default_dof_drive_mode = gymapi.DOF_MODE_POS  # 关节驱动模式

robot_asset = gym.load_asset(sim, asset_root, asset_file, asset_options)

资产属性:

  • 几何形状(碰撞和视觉)
  • 质量和惯性
  • 关节类型和限制
  • 材质属性(摩擦、弹性)

5. Actor (演员)

定义: 资产在环境中的实例化对象,是实际参与仿真的实体。

作用:

  • 资产的具体实例
  • 拥有独立的状态(位置、速度、关节角度等)
  • 可以被控制和交互

创建方式:

pose = gymapi.Transform()
pose.p = gymapi.Vec3(0.0, 0.0, 1.0)  # 位置
pose.r = gymapi.Quat(0.0, 0.0, 0.0, 1.0)  # 旋转(四元数)

actor_handle = gym.create_actor(
    env,
    robot_asset,
    pose,
    name="robot_0",
    group=0,  # 碰撞组
    filter=1  # 碰撞过滤器
)

关系:

  • Asset → Actor: 一对多(一个资产可创建多个演员)
  • Actor → Rigid Body: 一对多(一个演员包含多个刚体)
  • Actor → DOF: 一对多(一个演员包含多个自由度)

6. Rigid Body (刚体)

定义: 演员中的单个刚性连接部件,不会发生形变。

作用:

  • 物理仿真的基本单元
  • 拥有质量、惯性、碰撞形状
  • 通过关节连接

获取方式:

# 获取演员的刚体数量
num_bodies = gym.get_actor_rigid_body_count(env, actor_handle)

# 获取刚体名称
body_names = gym.get_actor_rigid_body_names(env, actor_handle)

# 获取特定刚体的句柄
body_handle = gym.find_actor_rigid_body_handle(env, actor_handle, "link_name")

示例:

  • 机器人手臂的每个连杆是一个刚体
  • 机器人的基座是一个刚体
  • 夹爪的每个手指是一个刚体

7. DOF (自由度/关节)

定义: 连接两个刚体的关节,定义了相对运动的自由度。

作用:

  • 定义刚体间的运动约束
  • 可以被驱动和控制
  • 提供位置、速度、力矩反馈

关节类型:

  • Revolute (旋转关节): 绕轴旋转
  • Prismatic (平移关节): 沿轴平移
  • Fixed (固定关节): 无相对运动
  • Spherical (球形关节): 三自由度旋转

控制模式:

dof_props = gym.get_actor_dof_properties(env, actor_handle)

# 位置控制模式
dof_props['driveMode'].fill(gymapi.DOF_MODE_POS)
dof_props['stiffness'].fill(1000.0)  # 刚度
dof_props['damping'].fill(100.0)     # 阻尼

# 速度控制模式
dof_props['driveMode'].fill(gymapi.DOF_MODE_VEL)
dof_props['stiffness'].fill(0.0)
dof_props['damping'].fill(1000.0)

# 力矩控制模式
dof_props['driveMode'].fill(gymapi.DOF_MODE_EFFORT)

gym.set_actor_dof_properties(env, actor_handle, dof_props)

获取信息:

# 获取自由度数量
num_dofs = gym.get_asset_dof_count(robot_asset)

# 获取自由度名称
dof_names = gym.get_asset_dof_names(robot_asset)

# 获取自由度状态(位置和速度)
dof_states = gym.get_actor_dof_states(env, actor_handle, gymapi.STATE_ALL)

8. Sensor (传感器)

定义: 用于感知环境的虚拟传感器,可以附加到刚体上。

传感器类型:

8.1 Camera (相机)
# 创建相机属性
camera_props = gymapi.CameraProperties()
camera_props.width = 640
camera_props.height = 480

# 创建相机传感器
camera_handle = gym.create_camera_sensor(env, camera_props)

# 附加到刚体
local_transform = gymapi.Transform()
local_transform.p = gymapi.Vec3(0, 0, 0)
gym.attach_camera_to_body(
    camera_handle,
    env,
    body_handle,
    local_transform,
    gymapi.FOLLOW_TRANSFORM
)

# 获取图像
gym.render_all_camera_sensors(sim)
rgb_image = gym.get_camera_image(sim, env, camera_handle, gymapi.IMAGE_COLOR)
depth_image = gym.get_camera_image(sim, env, camera_handle, gymapi.IMAGE_DEPTH)
8.2 Force Sensor (力传感器)
# 创建力传感器
force_sensor_props = gymapi.ForceSensorProperties()
force_sensor_props.enable_forward_dynamics_forces = True
force_sensor_props.enable_constraint_solver_forces = True

sensor_handle = gym.create_force_sensor(env, body_handle, force_sensor_props)

# 获取力数据
forces = gym.get_sensor_force_tensor(sim)
8.3 IMU (惯性测量单元)
  • 测量加速度和角速度
  • 通常附加到机器人基座

9. 障碍物 (Obstacles)

定义: 环境中的静态或动态物体,用于创建复杂场景。

创建方式:

9.1 地面
plane_params = gymapi.PlaneParams()
plane_params.normal = gymapi.Vec3(0, 0, 1)  # 法向量
plane_params.static_friction = 1.0
plane_params.dynamic_friction = 1.0
gym.add_ground(sim, plane_params)
9.2 简单几何体
# 创建盒子资产
box_asset = gym.create_box(sim, width=1.0, height=1.0, depth=1.0)

# 创建球体资产
sphere_asset = gym.create_sphere(sim, radius=0.5)

# 创建为演员
obstacle_pose = gymapi.Transform()
obstacle_pose.p = gymapi.Vec3(2.0, 0.0, 0.5)
obstacle_handle = gym.create_actor(env, box_asset, obstacle_pose, "obstacle", 0, 1)
9.3 复杂障碍物
# 从 URDF/MJCF 加载
obstacle_asset = gym.load_asset(sim, asset_root, "urdf/table.urdf", asset_options)
obstacle_handle = gym.create_actor(env, obstacle_asset, pose, "table", 0, 1)

10. 物理引擎 (Physics Engine)

定义: 负责计算物体的运动、碰撞和约束。

PhysX 参数:

sim_params.physx.solver_type = 1  # TGS solver
sim_params.physx.num_position_iterations = 4  # 位置迭代次数
sim_params.physx.num_velocity_iterations = 1  # 速度迭代次数
sim_params.physx.contact_offset = 0.02  # 接触偏移
sim_params.physx.rest_offset = 0.001  # 静止偏移
sim_params.physx.use_gpu = True  # 使用 GPU 加速

功能:

  • 刚体动力学计算
  • 碰撞检测和响应
  • 关节约束求解
  • 接触力计算

11. 渲染器 (Renderer)

定义: 负责生成可视化图像和传感器数据。

功能:

  • 场景渲染(查看器)
  • 相机图像生成(RGB、深度、分割)
  • 光照和材质

渲染流程:

# 1. 步进物理
gym.simulate(sim)
gym.fetch_results(sim, True)

# 2. 更新图形
gym.step_graphics(sim)

# 3. 渲染相机
gym.render_all_camera_sensors(sim)

# 4. 绘制查看器
gym.draw_viewer(viewer, sim, True)

概念关系图

概念关系图


工作流程

1. 初始化流程

# 步骤 1: 获取 Gym 实例
gym = gymapi.acquire_gym()

# 步骤 2: 配置仿真参数
sim_params = gymapi.SimParams()
sim_params.dt = 1.0 / 60.0
sim_params.gravity = gymapi.Vec3(0.0, 0.0, -9.81)

# 步骤 3: 创建仿真
sim = gym.create_sim(0, 0, gymapi.SIM_PHYSX, sim_params)

# 步骤 4: 添加地面
gym.add_ground(sim, gymapi.PlaneParams())

# 步骤 5: 加载资产
robot_asset = gym.load_asset(sim, asset_root, asset_file, asset_options)

# 步骤 6: 创建环境
env = gym.create_env(sim, lower, upper, num_per_row)

# 步骤 7: 创建演员
actor_handle = gym.create_actor(env, robot_asset, pose, "robot", 0, 1)

# 步骤 8: 创建传感器
camera_handle = gym.create_camera_sensor(env, camera_props)
gym.attach_camera_to_body(camera_handle, env, body_handle, transform, mode)

# 步骤 9: 准备仿真
gym.prepare_sim(sim)

2. 仿真循环

while not done:
    # 1. 设置控制指令
    gym.set_dof_position_target_tensor(sim, position_targets)
    # 或
    gym.set_dof_velocity_target_tensor(sim, velocity_targets)
    
    # 2. 步进物理仿真
    gym.simulate(sim)
    gym.fetch_results(sim, True)
    
    # 3. 更新图形
    gym.step_graphics(sim)
    
    # 4. 渲染传感器
    gym.render_all_camera_sensors(sim)
    
    # 5. 获取状态
    gym.refresh_dof_state_tensor(sim)
    gym.refresh_actor_root_state_tensor(sim)
    
    # 6. 获取传感器数据
    rgb_image = gym.get_camera_image(sim, env, camera_handle, gymapi.IMAGE_COLOR)
    depth_image = gym.get_camera_image(sim, env, camera_handle, gymapi.IMAGE_DEPTH)
    
    # 7. 渲染查看器(可选)
    if viewer:
        gym.draw_viewer(viewer, sim, True)
        gym.sync_frame_time(sim)

3. 清理流程

# 销毁查看器
if viewer:
    gym.destroy_viewer(viewer)

# 销毁仿真
gym.destroy_sim(sim)

代码示例

完整示例:创建机器人环境

from isaacgym import gymapi
from isaacgym import gymutil
import numpy as np

# 1. 初始化 Gym
gym = gymapi.acquire_gym()

# 2. 配置仿真参数
sim_params = gymapi.SimParams()
sim_params.dt = 1.0 / 60.0
sim_params.substeps = 2
sim_params.up_axis = gymapi.UP_AXIS_Z
sim_params.gravity = gymapi.Vec3(0.0, 0.0, -9.81)

# PhysX 参数
sim_params.physx.solver_type = 1
sim_params.physx.num_position_iterations = 4
sim_params.physx.num_velocity_iterations = 1
sim_params.physx.use_gpu = True
sim_params.use_gpu_pipeline = True

# 3. 创建仿真
sim = gym.create_sim(0, 0, gymapi.SIM_PHYSX, sim_params)

# 4. 添加地面
plane_params = gymapi.PlaneParams()
plane_params.normal = gymapi.Vec3(0, 0, 1)
gym.add_ground(sim, plane_params)

# 5. 加载机器人资产
asset_root = "assets"
asset_file = "urdf/franka_description/robots/franka_panda.urdf"

asset_options = gymapi.AssetOptions()
asset_options.fix_base_link = True
asset_options.disable_gravity = False
asset_options.default_dof_drive_mode = gymapi.DOF_MODE_POS

robot_asset = gym.load_asset(sim, asset_root, asset_file, asset_options)

# 6. 创建环境
num_envs = 4
envs = []
actors = []

env_spacing = 2.0
for i in range(num_envs):
    # 创建环境
    env = gym.create_env(
        sim,
        gymapi.Vec3(-env_spacing, -env_spacing, 0),
        gymapi.Vec3(env_spacing, env_spacing, env_spacing),
        int(np.sqrt(num_envs))
    )
    envs.append(env)
    
    # 创建机器人演员
    pose = gymapi.Transform()
    pose.p = gymapi.Vec3(0, 0, 0)
    pose.r = gymapi.Quat(0, 0, 0, 1)
    
    actor = gym.create_actor(env, robot_asset, pose, f"robot_{i}", i, 1)
    actors.append(actor)
    
    # 设置 DOF 属性
    dof_props = gym.get_actor_dof_properties(env, actor)
    dof_props['driveMode'].fill(gymapi.DOF_MODE_POS)
    dof_props['stiffness'].fill(1000.0)
    dof_props['damping'].fill(100.0)
    gym.set_actor_dof_properties(env, actor, dof_props)

# 7. 创建相机(在第一个环境)
camera_props = gymapi.CameraProperties()
camera_props.width = 640
camera_props.height = 480

camera_handle = gym.create_camera_sensor(envs[0], camera_props)
camera_pos = gymapi.Vec3(2, 2, 2)
camera_target = gymapi.Vec3(0, 0, 0)
gym.set_camera_location(camera_handle, envs[0], camera_pos, camera_target)

# 8. 创建查看器
viewer = gym.create_viewer(sim, gymapi.CameraProperties())
gym.viewer_camera_look_at(viewer, None, gymapi.Vec3(3, 3, 2), gymapi.Vec3(0, 0, 0))

# 9. 准备仿真
gym.prepare_sim(sim)

# 10. 仿真循环
frame = 0
while not gym.query_viewer_has_closed(viewer):
    # 设置目标位置(简单的正弦波运动)
    for i, (env, actor) in enumerate(zip(envs, actors)):
        target_pos = np.sin(frame * 0.01 + i * np.pi / 2) * 0.5
        dof_states = gym.get_actor_dof_states(env, actor, gymapi.STATE_ALL)
        dof_states['pos'][0] = target_pos
        gym.set_actor_dof_states(env, actor, dof_states, gymapi.STATE_POS)
    
    # 步进仿真
    gym.simulate(sim)
    gym.fetch_results(sim, True)
    
    # 更新图形
    gym.step_graphics(sim)
    gym.render_all_camera_sensors(sim)
    
    # 渲染查看器
    gym.draw_viewer(viewer, sim, True)
    gym.sync_frame_time(sim)
    
    # 每 100 帧保存一次图像
    if frame % 100 == 0:
        rgb_image = gym.get_camera_image(sim, envs[0], camera_handle, gymapi.IMAGE_COLOR)
        print(f"Frame {frame}: RGB image shape = {rgb_image.shape}")
    
    frame += 1

# 11. 清理
gym.destroy_viewer(viewer)
gym.destroy_sim(sim)

关键要点总结

层级关系

  1. GymSimEnvActorRigid Body/DOF
  2. 一个 Gym 可以管理多个 Sim
  3. 一个 Sim 可以包含多个 Env(并行仿真)
  4. 一个 Env 可以包含多个 Actor
  5. 一个 Actor 由多个 Rigid Body 和 DOF 组成

资产与演员

  • Asset: 模板定义(可重用)
  • Actor: 资产的实例(有状态)
  • 关系:Asset → Actor(一对多)

传感器

  • 传感器附加到 Rigid Body
  • 传感器数据通过 Gym API 获取
  • 需要调用 render_all_camera_sensors() 更新相机数据

控制模式

  • 位置控制 (DOF_MODE_POS): 适合精确定位
  • 速度控制 (DOF_MODE_VEL): 适合轮式机器人
  • 力矩控制 (DOF_MODE_EFFORT): 适合力控制任务

GPU 加速

  • 物理计算可以在 GPU 上运行
  • 张量操作使用 PyTorch 接口
  • 支持批量并行仿真(数千个环境)

参考资源

更多推荐