Rigid-body constraints#
A constraint ties two rigid links together so the solver keeps a geometric relationship between them: coincident points, a fixed relative pose, or coupled joint values. Most constraints are declared once in a model file and hold for the whole simulation. One kind, the weld constraint, can be added and removed while the simulation runs, which is what makes it the tool for modeling a suction gripper picking up and releasing an object.
This page covers the runtime weld API on the rigid solver, and how the file-declared constraint types relate to it.
The complete runnable example is examples/rigid/suction_cup.py: a Franka arm reaches a cube, welds it to the hand, lifts and moves it, then releases.
Weld constraints at runtime#
A weld constraint pins two links so their relative pose is frozen at the values they have the instant you add it: all six degrees of freedom, translation and rotation. It is the constraint you toggle to model suction or a magnetic gripper: engage it when the end-effector reaches the object, delete it to let go.
The API lives on the rigid solver, not on an entity, because a weld couples links that belong to two different entities. Reach it through scene.sim.rigid_solver after the scene is built:
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)
The arguments are global link indices (integers), not link or entity handles. Get an index from a link with entity.get_link(name).idx. The order of the two links does not matter.
Deleting the constraint releases the object:
rigid.delete_weld_constraint(link_cube, link_franka)
Pass the same two link indices you welded. Once released, the object is governed by contact and gravity again, so it will fall unless something supports it.
Note
A weld records the relative pose at the moment it is added; it does not snap the links together. Move the end-effector into contact with the object before welding, or the object will hang in the air at whatever offset it had when the constraint engaged.
Applying to a subset of environments#
In a parallel simulation, both calls take an envs_idx argument to select which environments the weld applies to. Omit it to apply to all environments:
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))
The two link indices are the same across environments; only the environment selection differs.
Budgeting for dynamic constraints#
Runtime welds draw from a fixed pool sized before the scene is built. The pool holds max_dynamic_constraints welds (default 8), set on gs.options.RigidOptions:
scene = gs.Scene(
rigid_options=gs.options.RigidOptions(max_dynamic_constraints=16),
)
Warning
Adding a weld once the pool is full has no effect: the solver logs a warning and ignores the request rather than raising. If a gripper silently fails to hold its object, check that you have released stale welds and that max_dynamic_constraints is large enough for the number held at once.
Querying active welds#
get_weld_constraints returns the welds currently active, as a dictionary of tensors keyed by field. link_a and link_b hold the welded link indices; force holds the constraint force. Each is batched over environments, with shape (n_envs, n_welds_max, ...):
welds = rigid.get_weld_constraints() # dict with keys "link_a", "link_b", "force"
Pass to_torch=False for NumPy arrays, or as_tensor=False to get a per-environment tuple instead of a padded batch.
Constraint types#
Genesis World supports three equality-constraint types. Weld is the only one you add at runtime; the other two are read from a model’s <equality> block when it is loaded from MJCF or URDF.
Type |
Constrains |
Declared in |
Runtime API |
|---|---|---|---|
Connect |
A point on each link to coincide (3 DoF), a ball joint. |
MJCF |
— |
Weld |
Relative pose fully fixed (6 DoF). |
MJCF, or |
|
Joint |
One joint’s value tied to another’s by a polynomial. |
MJCF, URDF |
— |
A connect or joint constraint enters the simulation with its host model. There is no runtime API to add or remove it; edit the model file’s equality section instead.
See also#
Control your robot: joint-level position, velocity, and force control.
Inverse kinematics and motion planning: the IK solving and path planning the suction example uses to reach the object.