选项系统#
Genesis World 通过选项对象(options objects)进行配置:它们是 gs.options.* 下的小型、带类型的参数组,传给 gs.Scene(...) 和 scene.add_entity(...)。我们没有让场景接受几十个零散的关键字参数,而是让每个关注点拥有自己的对象和自己的默认值:一个用于全局仿真器,每个物理求解器一个,一个用于查看器,每个渲染器一个。本页解释这些对象是什么、它们如何组合成一个场景,以及当同一项设置出现在两处时我们如何解析。
如果你还没有构建过场景,请先阅读 你好,Genesis World。该文在示例中顺带使用了 SimOptions 和 ViewerOptions。本页是这一用法背后的概念参考。
用选项组合场景#
场景的每个可配置组件都由一个选项对象描述。构造你关心的对象并将它们交给场景;省略的任何内容都会使用默认值。
import genesis as gs
gs.init(backend=gs.gpu)
scene = gs.Scene(
sim_options=gs.options.SimOptions(dt=0.01, gravity=(0, 0, -9.81)),
rigid_options=gs.options.RigidOptions(enable_collision=True),
viewer_options=gs.options.ViewerOptions(
camera_pos=(3.5, 0.0, 2.5),
camera_lookat=(0.0, 0.0, 0.5),
camera_fov=40,
),
show_viewer=True,
)
这些选项分为三类角色,此外还有一组逐实体选项,它们传给 add_entity 而不是场景:
全局。
SimOptions设置整个仿真的属性,耦合器选项则设置求解器之间如何交互。逐求解器。 每个物理求解器(rigid、MPM、SPH、FEM、SF、PBD)对应一个选项对象,各自只配置该求解器。
可视化。 查看器、不依赖求解器的可视化,以及渲染器。
所有选项对象共享同一个基类#
所有 gs.options.* 类都派生自 gs.options.Options,这是一个 Pydantic 模型。该基类的两个特性在实际使用中很重要:
字段带有类型,并在构造时校验。 类型错误或超出范围的值会立即抛出带有可读信息的异常,而不是等到第一次
scene.step()内部深处才报错。未知字段会被拒绝。 基类设置了
extra="forbid",因此像gravty=(0, 0, -9.81)这样拼错的参数会抛出Unrecognized attribute 'gravty',而不会被静默忽略。
你永远不要直接实例化 Options;始终使用具体的子类。每个选项类都在 API 参考 中与它所配置的组件一起记录。
求解器选项覆盖仿真器选项#
SimOptions 保存默认情况下属于全局的设置:最重要的是时间步 dt(单位:秒)和 gravity(单位:m/s²,方向为 -Z 向下)。每个求解器也会在自己的选项对象上暴露这些相同的设置,其默认值为 None。
在求解器选项上设置的值会覆盖全局 SimOptions 的值,且仅对该求解器生效;字段保持为 None 的求解器则继承全局值。
SimOptions.dt 表示一次 scene.step() 推进多少仿真时间。求解器的 dt 是它进行积分的间隔,因此必须能整除步长,且商为每步的子步数。所有活动求解器一起推进,所以某个求解器请求的子步数就是所有求解器共同采用的子步数;如果两个求解器请求不同的间隔,就会抛出异常。SimOptions.substeps 可以直接指定相同的子步数,若同时设置两者且不一致,则会抛出异常。
scene = gs.Scene(
sim_options=gs.options.SimOptions(dt=0.01), # one step advances 0.01 s
rigid_options=gs.options.RigidOptions(dt=0.005), # two substeps per step, for every solver
# mpm_options left unset -> the MPM solver, if used, integrates twice per step as well, over 0.005 s
)
同样的继承规则也适用于 gravity,每个求解器都保留自己的值,因此应从仿真该实体的求解器读回该值,例如 scene.rigid_solver.get_gravity(envs_idx)。通过 IPC 耦合各求解器的场景会把 SimOptions 的重力应用到它耦合的每个物体上,因此如果某个被耦合的求解器设置了不同的重力,就会在构建时抛出异常。只对某一个求解器有意义的设置(例如 RigidOptions.constraint_solver 或 RigidOptions.max_collision_pairs)只存在于该求解器的选项上,没有对应的全局设置。
场景级选项组#
以下每一项都是 gs.Scene(...) 的可选参数。
选项类 |
|
配置内容 |
|---|---|---|
|
全局时间步、重力、子步、可微分模式。 |
|
|
求解器之间的耦合。具体变体: |
|
|
刚体动力学:接触、碰撞、约束、积分器。 |
|
|
物质点法求解器(弹性、塑性、颗粒、流体)。 |
|
|
光滑粒子流体动力学求解器(流体、颗粒流)。 |
|
|
有限元法求解器(弹性材质)。 |
|
|
稳定流体求解器(欧拉气体仿真)。 |
|
|
基于位置的动力学求解器(布料、可变形体、液体、粒子)。 |
|
|
运动学(非动力学)实体。 |
|
|
旧版工具求解器。计划弃用。 |
|
|
独立于任何查看器或相机的可视化。 |
|
|
交互式查看器:相机位姿、分辨率、刷新率。 |
|
|
计时和 FPS 报告。 |
|
|
渲染后端: |
求解器和耦合器选项在 物理引擎参考 中与对应的求解器和耦合器一起记录;全局 SimOptions 记录在 Scene 下;查看器、可视化和渲染器选项记录在 可视化参考 中。
Note
并非每个求解器都会在每个场景中运行。只有当你添加了材质指向某个求解器的实体后,该求解器才会激活:添加刚体实体会激活刚体求解器,依此类推。未激活求解器的选项不会被使用。
逐实体选项#
add_entity 使用自己的一组选项,描述单个实体而不是场景:
franka = scene.add_entity(
morph=gs.morphs.MJCF(file="xml/franka_emika_panda/panda.xml"),
material=gs.materials.Rigid(),
surface=gs.surfaces.Default(),
)
Morph: 实体的几何形状和初始位姿。加载 morph 的方法见 你好,Genesis World,morph API 见 morph API。
材质: 实体如何响应物理力,以及由哪个求解器仿真。参见 超越刚体。
表面: 实体渲染时的外观。参见 表面与纹理。
另请参阅#
你好,Genesis World:使用这些选项的最小场景。
可视化:交互式查看器和命令行工具。
渲染:相机、图像类型、视频和渲染后端。
API 参考:每个选项类,与其所配置的组件一起记录。