Skip to content

Commit 5dbe448

Browse files
committed
Fix 'delete_weld_constraint'.
1 parent e052997 commit 5dbe448

File tree

2 files changed

+75
-12
lines changed

2 files changed

+75
-12
lines changed

genesis/engine/solvers/rigid/rigid_solver_decomp.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4968,19 +4968,14 @@ def _kernel_add_weld_constraint(
49684968
self.constraint_solver.ti_n_equalities[i_b] = self.constraint_solver.ti_n_equalities[i_b] + 1
49694969

49704970
def delete_weld_constraint(self, link1_idx, link2_idx, envs_idx=None, *, unsafe=False):
4971-
_, link1_idx, _ = self._sanitize_1D_io_variables(
4972-
None, link1_idx, self.n_links, envs_idx, idx_name="links_idx", skip_allocation=True, unsafe=unsafe
4973-
)
4974-
_, link2_idx, envs_idx = self._sanitize_1D_io_variables(
4975-
None, link2_idx, self.n_links, envs_idx, idx_name="links_idx", skip_allocation=True, unsafe=unsafe
4976-
)
4977-
self._kernel_delete_weld_constraint(link1_idx, link2_idx, envs_idx)
4971+
envs_idx = self._sanitize_envs_idx(envs_idx, unsafe=unsafe)
4972+
self._kernel_delete_weld_constraint(int(link1_idx), int(link2_idx), envs_idx)
49784973

49794974
@ti.kernel
49804975
def _kernel_delete_weld_constraint(
49814976
self,
4982-
link1_idx: ti.types.ndarray(),
4983-
link2_idx: ti.types.ndarray(),
4977+
link1_idx: ti.i32,
4978+
link2_idx: ti.i32,
49844979
envs_idx: ti.types.ndarray(),
49854980
):
49864981
ti.loop_config(serialize=self._para_level < gs.PARA_LEVEL.PARTIAL)
@@ -4989,8 +4984,8 @@ def _kernel_delete_weld_constraint(
49894984
for i_e in range(self.n_equalities, self.constraint_solver.ti_n_equalities[i_b]):
49904985
if (
49914986
self.equalities_info[i_e, i_b].eq_type == gs.EQUALITY_TYPE.WELD
4992-
and self.equalities_info[i_e, i_b].eq_obj1id == link1_idx[i_b]
4993-
and self.equalities_info[i_e, i_b].eq_obj2id == link2_idx[i_b]
4987+
and self.equalities_info[i_e, i_b].eq_obj1id == link1_idx
4988+
and self.equalities_info[i_e, i_b].eq_obj2id == link2_idx
49944989
):
49954990
if i_e < self.constraint_solver.ti_n_equalities[i_b] - 1:
49964991
self.equalities_info[i_e, i_b] = self.equalities_info[

tests/test_rigid_physics.py

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,74 @@ def test_equality_weld(gs_sim, mj_sim, gs_solver):
408408
simulate_and_check_mujoco_consistency(gs_sim, mj_sim, qpos, num_steps=300, tol=tol)
409409

410410

411+
def test_dynamic_weld(show_viewer, tol):
412+
scene = gs.Scene(
413+
show_viewer=show_viewer,
414+
show_FPS=False,
415+
)
416+
plane = scene.add_entity(
417+
gs.morphs.Plane(),
418+
)
419+
cube = scene.add_entity(
420+
gs.morphs.Box(
421+
size=(0.04, 0.04, 0.04),
422+
pos=(0.65, 0.0, 0.02),
423+
),
424+
surface=gs.surfaces.Plastic(color=(1, 0, 0)),
425+
)
426+
robot = scene.add_entity(
427+
gs.morphs.MJCF(
428+
file="xml/universal_robots_ur5e/ur5e.xml",
429+
),
430+
)
431+
scene.build(n_envs=4, env_spacing=(3.0, 3.0))
432+
433+
end_effector = robot.get_link("ee_virtual_link")
434+
435+
# Compute up and down robot configurations
436+
ee_pos_up = np.array((0.65, 0.0, 0.5), dtype=gs.np_float)
437+
ee_pos_down = np.array((0.65, 0.0, 0.15), dtype=gs.np_float)
438+
qpos_up = robot.inverse_kinematics(
439+
link=end_effector,
440+
pos=np.tile(ee_pos_up, (4, 1)),
441+
quat=np.tile(np.array((0.0, 1.0, 0.0, 0.0), dtype=gs.np_float), (4, 1)),
442+
)
443+
qpos_down = robot.inverse_kinematics(
444+
link=end_effector,
445+
pos=np.tile(ee_pos_down, (4, 1)),
446+
quat=np.tile(np.array((0.0, 1.0, 0.0, 0.0), dtype=gs.np_float), (4, 1)),
447+
)
448+
449+
# move to pre-grasp pose
450+
robot.control_dofs_position(qpos_up)
451+
for i in range(120):
452+
scene.step()
453+
454+
# reach
455+
robot.control_dofs_position(qpos_down)
456+
for i in range(70):
457+
scene.step()
458+
459+
# add weld constraint and move back up
460+
scene.sim.rigid_solver.add_weld_constraint(cube.base_link.idx, end_effector.idx, envs_idx=(0, 1, 2))
461+
robot.control_dofs_position(qpos_up)
462+
for i in range(60):
463+
scene.step()
464+
cubes_pos, cubes_quat = cube.get_pos(), cube.get_quat()
465+
assert_allclose(torch.diff(cubes_quat, dim=0), 0.0, tol=1e-3)
466+
assert_allclose(torch.diff(cubes_pos[[0, 1, 2]], dim=0), 0.0, tol=tol)
467+
assert_allclose(cubes_pos[-1] - cubes_pos[0], ee_pos_down - ee_pos_up, tol=1e-2)
468+
469+
# drop
470+
scene.sim.rigid_solver.delete_weld_constraint(cube.base_link.idx, end_effector.idx, envs_idx=(0, 1))
471+
for i in range(110):
472+
scene.step()
473+
cubes_pos, cubes_quat = cube.get_pos(), cube.get_quat()
474+
assert_allclose(torch.diff(cubes_quat, dim=0), 0.0, tol=1e-3)
475+
assert_allclose(torch.diff(cubes_pos[[0, 1, 3]], dim=0), 0.0, tol=1e-2)
476+
assert_allclose(cubes_pos[2] - cubes_pos[0], ee_pos_up - ee_pos_down, tol=1e-3)
477+
478+
411479
@pytest.mark.required
412480
@pytest.mark.parametrize("xml_path", ["xml/one_ball_joint.xml"])
413481
@pytest.mark.parametrize("gs_solver", [gs.constraint_solver.CG, gs.constraint_solver.Newton])
@@ -2300,7 +2368,7 @@ def _check_entity_positions(relative, tol):
23002368
entities[(False, True)].set_dofs_velocity(door_vel, 6)
23012369
entities[(True, False)].set_dofs_velocity(door_vel)
23022370
entities[(True, True)].set_dofs_velocity(door_vel)
2303-
link_1 = np.array([entities[(True, True)].link_start], dtype=gs.np_int)
2371+
link_1 = entities[(True, True)].link_start
23042372
for key in ((False, False), (False, True)):
23052373
link_2 = entities[key].link_start
23062374
scene.rigid_solver.add_weld_constraint(link_1, link_2)

0 commit comments

Comments
 (0)