@@ -2170,34 +2170,34 @@ def test_terrain_size(show_viewer, tol):
21702170
21712171
21722172@pytest .mark .required
2173- @pytest .mark .parametrize ("backend" , [gs .cpu ])
2174- def test_get_weld_constraints_basic (show_viewer , tol ):
2175- scene = gs .Scene (show_viewer = show_viewer )
2176-
2177- cube1 = scene .add_entity (gs .morphs .Box (size = (0.05 ,) * 3 , pos = (0.0 , 0.0 , 0.05 )))
2178- cube2 = scene .add_entity (gs .morphs .Box (size = (0.05 ,) * 3 , pos = (0.2 , 0.0 , 0.05 )))
2179-
2180- scene .build (n_envs = 1 )
2181-
2182- rigid = scene .sim .rigid_solver
2183-
2184- link_a = torch .tensor ([cube1 .base_link .idx ], dtype = gs .tc_int , device = gs .device )
2185- link_b = torch .tensor ([cube2 .base_link .idx ], dtype = gs .tc_int , device = gs .device )
2186-
2187- rigid .add_weld_constraint (link_a , link_b )
2188- scene .step ()
2173+ @pytest .mark .merge_fixed_links (False )
2174+ @pytest .mark .parametrize ("model_name" , ["pendulum" ])
2175+ @pytest .mark .parametrize ("gs_solver" , [gs .constraint_solver .CG ])
2176+ @pytest .mark .parametrize ("gs_integrator" , [gs .integrator .Euler ])
2177+ def test_jacobian (gs_sim , tol ):
2178+ pendulum = gs_sim .entities [0 ]
2179+ angle = 0.7
2180+ pendulum .set_qpos (np .array ([angle ], dtype = np .float64 ))
2181+ gs_sim .scene .step ()
21892182
2190- welds = rigid . get_weld_constraints ( as_tensor = True , to_torch = False )
2183+ link = pendulum . get_link ( "PendulumArm_0" )
21912184
2192- env_id = 0 if "env" not in welds else int (welds ["env" ][0 ])
2185+ p_local = np .array ([0.05 , - 0.02 , 0.12 ], dtype = np .float64 )
2186+ J_o = pendulum .get_jacobian (link ).cpu ().numpy ()
2187+ J_p = pendulum .get_jacobian (link , p_local ).cpu ().numpy ()
21932188
2194- row = np .array (
2195- [env_id , int (welds ["obj_a" ][0 ]), int (welds ["obj_b" ][0 ])],
2196- dtype = np .int32 ,
2189+ c , s = np .cos (angle ), np .sin (angle )
2190+ Rx = np .array ([[1 , 0 , 0 ], [0 , c , - s ], [0 , s , c ]], dtype = np .float64 )
2191+ r_world = Rx @ p_local
2192+ r_cross = np .array (
2193+ [[0 , - r_world [2 ], r_world [1 ]], [r_world [2 ], 0 , - r_world [0 ]], [- r_world [1 ], r_world [0 ], 0 ]], dtype = np .float64
21972194 )
2198- ref = np .array ([0 , link_a .item (), link_b .item ()], dtype = np .int32 )
21992195
2200- assert_allclose (row , ref , tol = tol )
2196+ lin_o , ang_o = J_o [:3 , 0 ], J_o [3 :, 0 ]
2197+ lin_expected = lin_o - r_cross @ ang_o
2198+
2199+ assert_allclose (J_p [3 :, 0 ], ang_o , tol = tol )
2200+ assert_allclose (J_p [:3 , 0 ], lin_expected , tol = tol )
22012201
22022202
22032203@pytest .mark .required
0 commit comments