希望和正在或者想要学习使用ISAAC-GYM的朋友一起有一个讨论群,尝试互帮互助,交流学习内容~
目前刚开始尝试,不知道能不能建立起来,如果有意向请私戳!!
——2023.02
PS:源于官方说明文档。本人不用的地方不做展开
1. Isaac Gym模拟
- Isaac Gym提供了一个模拟界面,可以让您创建用于训练智能代理的动态环境。
- API是面向过程和数据的,而不是面向对象的。
- 可以访问CPU或GPU张量形式的模拟数据,这些数据可以与PyTorch等常见深度学习框架共享。
- gymapi
定义了核心API,包括支持的数据类型和常量
from isaacgym import gymapi
- 所有Gym API函数都可以作为启动时获取的单一Gym对象的方法进行访问
gym = gymapi.acquire_gym()
2. 创建模拟环境
2.1 使用create_sim
sim_params = gymapi.SimParams()
sim = gym.create_sim(compute_device_id, graphics_device_id, gymapi.SIM_PHYSX, sim_params)
sim
包含物理与图形信息,用于加载资源、创建环境以及与仿真交互
参数释义:
参数 | 含义 |
---|---|
compute_device_id | 计算设备序号,选择GPU进行物理模拟 |
graphics_device_id | 图形设备序号,选择GPU进行渲染(需要任何传感器渲染可以置-1) |
gymapi.SIM_PHYSX | 指定要使用的物理后端(SIM_PHYSX 或者SIM_FLEX ) |
sim_params | 其他模拟参数 |
- 关于物理后端
SIM_PHYSX
或者SIM_FLEX
:
PHYSX | FLEX |
---|---|
后端提供健壮的刚体和关节模拟,可以在CPU或GPU上运行。它是目前唯一一个完全支持新tensor API的后端。 | 提供完全在GPU上运行的柔体和刚体模拟,但它还不完全支持tensor API。 |
- 关于sim_params :
用于配置物理模拟的详细信息,例如:
# get default set of parameters
sim_params = gymapi.SimParams()
# set common parameters
sim_params.dt = 1 / 60
sim_params.substeps = 2
sim_params.up_axis = gymapi.UP_AXIS_Z
sim_params.gravity = gymapi.Vec3(0.0, 0.0, -9.8)
# set PhysX-specific parameters
sim_params.physx.use_gpu = True
sim_params.physx.solver_type = 1
sim_params.physx.num_position_iterations = 6
sim_params.physx.num_velocity_iterations = 1
sim_params.physx.contact_offset = 0.01
sim_params.physx.rest_offset = 0.0
# set Flex-specific parameters
sim_params.flex.solver_type = 5
sim_params.flex.num_outer_iterations = 4
sim_params.flex.num_inner_iterations = 20
sim_params.flex.relaxation = 0.8
sim_params.flex.warm_start = 0.5
# create sim with these parameters
sim = gym.create_sim(compute_device_id, graphics_device_id, physics_engine, sim_params)
2.2 轴的朝向与地平面设置
- 关于轴的朝向
Isaac Gym支持y-up和 z-up 两种模拟。
重点在于在创建模拟时,调整SimParams
中的up_axis
和gravity
,例如
sim_params.up_axis = gymapi.UP_AXIS_Z
sim_params.gravity = gymapi.Vec3(0.0, 0.0, -9.8)
- 关于地平面设置
在非零重力的情况下可以设置如下:
# configure the ground plane
plane_params = gymapi.PlaneParams()
plane_params.normal = gymapi.Vec3(0, 0, 1) # z-up!
plane_params.distance = 0
plane_params.static_friction = 1
plane_params.dynamic_friction = 1
plane_params.restitution = 0
# create the ground plane
gym.add_ground(sim, plane_params)
normal
定义平面方向,并取决于上方向轴的选择:
z-up | y-up |
---|---|
(0, 0, 1) | (0, 1, 0) |
参数 | 含义 |
---|---|
distance | 平面与原点的距离 |
static_friction | 静摩擦系数 |
dynamic_friction | 动摩擦系数 |
restitution | 控制与地平面碰撞的弹性(反弹量) |
3. 资源加载
- 支持加载URDF、MJCF和USD文件格式;
- 加载资源时,可以指定资源根目录和相对于根的资源路径:
asset_root = "../../assets"
asset_file = "urdf/franka_description/robots/franka_panda.urdf"
asset = gym.load_asset(sim, asset_root, asset_file)
- 使用文件扩展名来确定资产文件格式:
扩展名 | 文件 |
---|---|
.urdf | URDF files |
.xml | MJCF files |
.usd/.usda | USD files |
Gym API特定于格式的方法:load_asset_urdf
、load_asset_mjcf
、load_asset_usd
- 想导入其他外部信息:使用参数
AssetOptions
4. 环境与执行器
- 环境由一起模拟的参与者和传感器的集合组成。环境中的参与者彼此进行物理交互。它们的状态由物理引擎维护,可以使用稍后讨论的控制API进行控制。放置在环境中的传感器(如摄像头)将能够捕获该环境中的参与者。
- Isaac Gym能够将环境的多个实例打包到单个模拟中;可以随机化每个环境中的初始条件,例如布局、演员姿势,甚至演员本身。可以随机化所有参与者的物理、视觉和控制属性。
- 在添加参与者之前,必须创建一个环境:
spacing = 2.0
lower = gymapi.Vec3(-spacing, 0.0, -spacing)
upper = gymapi.Vec3(spacing, spacing, spacing)
env = gym.create_env(sim, lower, upper, 8)
# 8表示每行8个小环境
- 要将执行器添加到环境中,必须指定源资源、所需姿势和其他一些详细信息:
pose = gymapi.Transform()
# 使用位置向量p和方向四元数r在环境局部坐标中定义执行器的位姿态
pose.p = gymapi.Vec3(0.0, 1.0, 0.0)
pose.r = gymapi.Quat(-0.707107, 0.0, 0.0, 0.707107) # 绕x轴旋转-90度
# Quat的顺序: (x, y, z, w) (将使用z向上约定定义的资源加载到使用y向上约定的模拟中时,需要进行这种旋转。)
#Isaac Gym提供了一个方便的数学助手集合,其中包括四元数实用程序,因此四元数可以以轴角度形式定义,如下所示:
pose.r = gymapi.Quat.from_axis_angle(gymapi.Vec3(1, 0, 0), -0.5 * math.pi)
actor_handle = gym.create_actor(env, asset, pose, "MyActor", 0, 1)
# "MyActor":自己给执行器的命名,需为同一环境中的所有参与者指定唯一的名称;
# 可以通过保存句柄`create_actor`来查找自己的执行器,而不使用其名称。
# 0:collision_group, 物理模拟用
# 1:collision_filter ,物理模拟用
在单个循环中初始化所有环境
# set up the env grid
num_envs = 64
envs_per_row = 8
env_spacing = 2.0
env_lower = gymapi.Vec3(-env_spacing, 0.0, -env_spacing)
env_upper = gymapi.Vec3(env_spacing, env_spacing, env_spacing)
# cache some common handles for later use
envs = []
actor_handles = []
# create and populate the environments
for i in range(num_envs):
env = gym.create_env(sim, env_lower, env_upper, envs_per_row)
envs.append(env)
height = random.uniform(1.0, 2.5)
pose = gymapi.Transform()
pose.p = gymapi.Vec3(0.0, height, 0.0)
actor_handle = gym.create_actor(env, asset, pose, "MyActor", i, 1)
actor_handles.append(actor_handle)
TIPS:
- 指定给每个参与者的冲突组对应于环境索引,这意味着来自不同环境的参与者不会在物理上相互交互。
5. 运行模拟
设置环境栅格和其他参数后,可以开始模拟。这通常在循环中完成,其中循环的每个迭代对应于一个时间步长:
while True:
# step the physics
gym.simulate(sim)
gym.fetch_results(sim, True)
6. 添加查看器
- 默认情况下,模拟不会创建任何视觉反馈窗口。
- Isaac Gym提供了一个简单的集成查看器,可以让您查看模拟中发生的情况:
cam_props = gymapi.CameraProperties()
viewer = gym.create_viewer(sim, cam_props)
# 将弹出一个带有默认尺寸的窗口,可以设置isaacgym.gymapi.CameraProperties调节尺寸
- 为了更新查看器,可以在模拟循环的每次迭代期间执行以下代码:
gym.step_graphics(sim);
gym.draw_viewer(viewer, sim, True)
step_graphics | draw_viewer |
---|---|
将模拟的可视化表示与物理状态同步 | 查看器中渲染最新快照 |
- 要使可视化更新频率与实时同步,可以在循环迭代结束时添加以下语句:
gym.sync_frame_time(sim)
#这将使模拟速率降低到实时。如果模拟运行速度低于实时速度,则此语句将无效。
- 如果希望在查看器窗口关闭时终止模拟,可以使用
query_viewer_has_closed
:
while not gym.query_viewer_has_closed(viewer):
# step the physics
gym.simulate(sim)
gym.fetch_results(sim, True)
# update the viewer
gym.step_graphics(sim);
gym.draw_viewer(viewer, sim, True)
# Wait for dt to elapse in real time.
# This synchronizes the physics simulation with the rendering rate.
gym.sync_frame_time(sim)
- 可使用F11切换查看器的全屏模式
6.1 查看器的GUI
- 创建查看器时,屏幕左侧将显示一个简单的图形用户界面。可以使用**“Tab”**键打开和关闭GUI的显示。
- GUI有4个单独的选项卡:Actors、Sim、Viewer和Perf。
选项 | 作用 |
---|---|
Actors | 提供了选择环境和该环境中的参与者的功能 |
Sim | 显示物理模拟参数 |
Viewer | 允许自定义常见的可视化选项,能够在查看实体的图形表示和物理引擎使用的物理形状之间切换 |
Perf | 显示内部测量的性能;Performance Measurement Window”(性能测量窗口)指定测量性能的帧数 |
Actors的三个子选项卡:
子选项 | 作用 |
---|---|
Bodies | 提供有关活动参与者刚体的信息。它还允许更改执行器身体的显示颜色,并切换身体轴的可视化 |
DOFs | 自由度的信息 |
Pose Override-姿势覆盖 | 使用执行器的自由度手动设置演员的位姿。启用此功能后,将使用滑块在用户界面中设置的值替代选定执行器的姿势和驱动目标。 |
6.2 自定义鼠标/键盘输入
要从查看器获取鼠标/键盘输入,可以订阅和查询动作事件。示例examples/projectiles.py
:
gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_SPACE, "space_shoot")
gym.subscribe_viewer_keyboard_event(viewer, gymapi.KEY_R, "reset")
gym.subscribe_viewer_mouse_event(viewer, gymapi.MOUSE_LEFT_BUTTON, "mouse_shoot")
...
while not gym.query_viewer_has_closed(viewer):
...
for evt in gym.query_viewer_action_events(viewer):
7. 退出
退出时,应按如下方式释放sim卡和查看器对象:
gym.destroy_viewer(viewer)
gym.destroy_sim(sim)