🔒 约束#
Genesis 支持用于操作任务(如吸盘抓取)的运行时约束。
Weld 约束#
Weld 约束将两个 link 刚性连接在一起(6 DOF 约束)。
添加 Weld 约束#
import genesis as gs
import numpy as np
scene = gs.Scene()
franka = scene.add_entity(gs.morphs.MJCF(file="franka.xml"))
cube = scene.add_entity(gs.morphs.Box(pos=(0.65, 0, 0.02), size=(0.04, 0.04, 0.04)))
scene.build()
# 获取 link 句柄
rigid = scene.sim.rigid_solver
end_effector = franka.get_link("hand")
cube_link = cube.base_link
# 创建约束数组
link_cube = np.array([cube_link.idx], dtype=gs.np_int)
link_franka = np.array([end_effector.idx], dtype=gs.np_int)
# 添加 weld 约束(吸盘接合)
rigid.add_weld_constraint(link_cube, link_franka)
移除 Weld 约束#
# 释放物体
rigid.delete_weld_constraint(link_cube, link_franka)
吸盘示例#
# 移动到物体
qpos = franka.inverse_kinematics(link=end_effector, pos=np.array([0.65, 0.0, 0.13]))
franka.control_dofs_position(qpos[:-2], motors_dof)
for _ in range(50):
scene.step()
# 连接(吸盘开启)
rigid.add_weld_constraint(link_cube, link_franka)
# 抬起
qpos = franka.inverse_kinematics(link=end_effector, pos=np.array([0.65, 0.0, 0.28]))
franka.control_dofs_position(qpos[:-2], motors_dof)
for _ in range(100):
scene.step()
# 放置
qpos = franka.inverse_kinematics(link=end_effector, pos=np.array([0.4, 0.2, 0.13]))
franka.control_dofs_position(qpos[:-2], motors_dof)
for _ in range(100):
scene.step()
# 释放(吸盘关闭)
rigid.delete_weld_constraint(link_cube, link_franka)
多环境约束#
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))
Connect 约束#
Connect 约束强制执行仅位置重合(3 DOF),允许相对旋转。
<!-- 在 MJCF/URDF 中 -->
<equality>
<connect name="ball_joint" body1="link_1" body2="link_2" anchor="0 0 1" />
</equality>
查询活动约束#
constraints = rigid.get_weld_constraints()
print(constraints) # 活动约束对
约束属性#
Weld: 完整 6-DOF 约束(平移 + 旋转)
Connect: 3-DOF 约束(仅平移)
即时: 无受力限制或顺应性
运行时: 可以动态添加/移除