刚体约束#
约束(constraint)把两个刚性连杆联系在一起,让求解器维持它们之间的某种几何关系:点重合、相对位姿固定,或关节值耦合。大多数约束在模型文件中一次性声明,并在整个仿真过程中保持有效。其中一种——weld 约束——可以在仿真运行期间添加和删除,因此吸盘夹爪能够抓起物体再把它放开。
完整的可运行示例是 examples/rigid/suction_cup.py:一台 Franka 机械臂伸向立方体,把它焊接到手上,抬起并移动,然后释放。
运行时的 weld 约束#
weld 约束把两个连杆钉在一起,使它们的相对位姿冻结在你添加约束那一瞬间的取值上:全部六个自由度,平移和旋转都包括在内。它就是用来模拟吸盘或磁性夹爪的那种可开关约束:末端执行器够到物体时接合它,松手时删除它。
该 API 位于刚体求解器上,而不是实体上,因为 weld 耦合的是分属两个不同实体的连杆。在场景构建完成后通过 scene.sim.rigid_solver 访问:
rigid = scene.sim.rigid_solver
link_cube = cube.get_link("box_baselink").idx
link_franka = franka.get_link("hand").idx
rigid.add_weld_constraint(link_cube, link_franka)
参数是全局连杆索引(整数),而不是连杆或实体句柄。用 entity.get_link(name).idx 可以从连杆取得索引。两个连杆的先后顺序无关紧要。
删除约束即可释放物体:
rigid.delete_weld_constraint(link_cube, link_franka)
传入你焊接时用的那两个连杆索引。一旦释放,物体重新受接触和重力的作用,因此除非有东西支撑,否则它会掉下来。
Note
weld 不会让两个连杆瞬间吸附在一起,所以要在焊接之前把末端执行器移动到与物体接触的位置,否则物体会以约束接合时的偏移量悬在空中。
应用于部分环境#
在 并行仿真 中,两个调用都接受 envs_idx 参数,用来选择 weld 作用于哪些环境。省略它则作用于所有环境:
scene.build(n_envs=4)
rigid.add_weld_constraint(link_cube, link_franka, envs_idx=(0, 1, 2))
rigid.delete_weld_constraint(link_cube, link_franka, envs_idx=(0, 1))
两个连杆索引在各个环境之间是相同的;不同的只是环境的选择。
为动态约束预留额度#
运行时的 weld 从一个在场景构建之前就确定好大小的固定池中分配。这个池容纳 max_dynamic_constraints 个 weld(默认 8),在 gs.options.RigidOptions 上设置:
scene = gs.Scene(
rigid_options=gs.options.RigidOptions(max_dynamic_constraints=16),
)
Warning
池已满时再添加 weld 不会有任何效果:求解器会记录一条警告并忽略该请求,而不是抛出异常。如果夹爪悄无声息地抓不住物体,请检查是否释放了过期的 weld,以及 max_dynamic_constraints 是否足以容纳同时持有的数量。
查询活动的 weld#
get_weld_constraints 以按字段为键的张量字典返回当前活动的 weld。link_a 和 link_b 保存被焊接的连杆索引;force 保存约束力。每一项都按环境批处理,形状为 (n_envs, n_welds_max, ...):
welds = rigid.get_weld_constraints() # dict with keys "link_a", "link_b", "force"
传入 to_torch=False 得到 NumPy 数组,或传入 as_tensor=False 得到逐环境的元组,而不是填充过的批次。
约束类型#
Genesis World 支持四种等式约束。weld 和 screw 是你在运行时添加的,connect 和 joint 则来自模型中的 <equality> 块——当 Genesis World 加载 MJCF 或 URDF 时读取它。
类型 |
约束内容 |
声明位置 |
运行时 API |
|---|---|---|---|
Connect |
每个连杆上的一个点重合(3 个自由度),相当于球关节。 |
MJCF |
— |
Weld |
相对位姿完全固定(6 个自由度)。 |
MJCF,或 |
|
Screw |
相对运动被限制为绕第一根连杆某根轴的螺旋运动(5 个自由度),可选行程限制和干摩擦。 |
|
|
Joint |
一个关节的值按多项式与另一个关节的值关联;当模型只指定单个关节时,则保持在一个恒定偏移上。 |
MJCF、URDF |
— |
add_screw_constraint 接受第一根连杆自身坐标系中的轴,以及以米为单位的每整圈行程 pitch。pitch 为 0 得到旋转运动,为无穷大得到移动(prismatic)运动。约束生效期间两个连杆不再相互碰撞,并且在 requires_grad=True 时暂不支持:
rigid.add_screw_constraint(link_bolt, link_nut, axis=(0.0, 0.0, 1.0), pitch=0.003, limit=(-0.02, 0.0))
connect 或 joint 约束随其所属模型一起进入仿真。没有运行时 API 可以添加或删除它;请改为编辑模型文件的 equality 段。