-
Notifications
You must be signed in to change notification settings - Fork 2.3k
[FEATURE] get_weld_constraints API #1370
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
672a192
to
00f2534
Compare
00f2534
to
c176525
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you take inspiration of get_contacts
? i.e. return a dict instead of a raw tensor, and fetch all relevent taichi field values in a single kernel call.
@@ -5715,6 +5715,68 @@ def _kernel_delete_weld_constraint( | |||
] | |||
self.constraint_solver.ti_n_equalities[i_b] = self.constraint_solver.ti_n_equalities[i_b] - 1 | |||
|
|||
@gs.assert_built | |||
def get_weld_constraints(self, as_tensor: bool = True, to_torch: bool = True): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still wrong. If you look more closely, there is no such thing as valid_mask
in RigidSolver.get_contacts
, only in RigidEntity.get_contacts
. You should do the same here.
|
||
@ti.kernel | ||
def _kernel_collect_welds(self, buf: ti.types.ndarray()): | ||
WELD = gs.EQUALITY_TYPE.WELD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove all these variables and use their value directly in the implementation.
"obj_b": obj_b, | ||
"valid_mask": zeros((n_envs, 0), dtype=bool), | ||
} | ||
shape3 = (n_envs, stride, 3) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you follow more strictly the pattern in RigidSolver.get_contacts
? You should not pass a 3D tensor because it would allocate more memory than necessary but most importantly, it will break "C"-contiguity, which would be problematic if forwarded as input argument of another taichi kernel.
for _ in range(200): | ||
scene.step() | ||
|
||
vel1 = np.asarray(cube1.get_vel()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to call np.asarray
here
vel1 = np.asarray(cube1.get_vel()) | ||
vel2 = np.asarray(cube2.get_vel()) | ||
|
||
assert_allclose(vel1, vel2, tol=1e-7) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just do assert_allclose(cube1.get_vel(), cube2.get_vel(), tol=1e-7)
welds_single = cube1.get_weld_constraints(as_tensor=True, to_torch=False) | ||
|
||
assert_allclose( | ||
np.array([int(welds_single["obj_a"][0]), int(welds_single["obj_b"][0])]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove np.array
and int
|
||
assert_allclose( | ||
np.array([int(welds_single["obj_a"][0]), int(welds_single["obj_b"][0])]), | ||
np.array([link_a.item(), link_b.item()], dtype=np.int32), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same.
|
||
scene.build(n_envs=1) | ||
|
||
rigid = scene.sim.rigid_solver |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not define this alias. This is useless here.
@pytest.mark.parametrize("backend", [gs.cpu]) | ||
def test_get_weld_constraints_entity(show_viewer, tol): | ||
scene = gs.Scene(show_viewer=show_viewer) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to skip line here.
|
||
cube1 = scene.add_entity(gs.morphs.Box(size=(0.05,) * 3, pos=(0.0, 0.0, 0.05))) | ||
cube2 = scene.add_entity(gs.morphs.Box(size=(0.05,) * 3, pos=(0.2, 0.0, 0.05))) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and here.
Adds RigidSolver.get_weld_constraints() – returns an (N, 3) NumPy array (env_id, link1_idx, link2_idx) of all active weld constraints, enabling quick inspection and test assertions without poking internal Taichi fields.
Resolves #1365