@@ -157,9 +157,9 @@ def _shift_jacobian_to_tool_kernel(
157157
158158@wp .kernel
159159def _null_space_projector_kernel (
160- jacobian_tool_world : wp .array3d [
160+ jacobian_tool : wp .array3d [
161161 float
162- ], # (robot_count, 6, max_dofs) columns are twists about the tool point, in world coords
162+ ], # (robot_count, 6, max_dofs) columns are per-DOF twists about the tool point, in the caller's task frame
163163 jacobian_pinv_transpose : wp .array3d [
164164 float
165165 ], # (robot_count, 6, max_dofs) either pseudo-inverse-transpose variant; zero beyond dof_count
@@ -171,6 +171,11 @@ def _null_space_projector_kernel(
171171):
172172 """The null-space projector, ``N = I - J^T @ jacobian_pinv_transpose``.
173173
174+ Frame-agnostic: ``jacobian_tool`` and ``jacobian_pinv_transpose`` just
175+ need to be expressed in the same frame as each other, whatever that is
176+ (e.g. world for differential IK, the operational frame for hybrid
177+ force/motion control).
178+
174179 A joint torque built as ``N @ M @ a``, for any joint acceleration ``a``
175180 and the joint-space mass matrix ``M``, produces zero task-space
176181 acceleration — but only when ``jacobian_pinv_transpose`` is the
@@ -193,7 +198,7 @@ def _null_space_projector_kernel(
193198
194199 total = float (0.0 )
195200 for k in range (6 ):
196- total += jacobian_tool_world [robot_idx , k , row ] * jacobian_pinv_transpose [robot_idx , k , col ]
201+ total += jacobian_tool [robot_idx , k , row ] * jacobian_pinv_transpose [robot_idx , k , col ]
197202 null_space_projector [robot_idx , row , col ] = identity_entry - total
198203
199204
@@ -291,20 +296,26 @@ def _apply_spatial_matrix_kernel(
291296@wp .kernel
292297def _task_matrix_times_jacobian_kernel (
293298 task_matrix : wp .array3d [float ], # (robot_count, 6, 6) symmetric task-space matrix, e.g. a 6x6 inverse
294- jacobian_tool_world : wp .array3d [
299+ jacobian_tool : wp .array3d [
295300 float
296- ], # (robot_count, 6, max_dofs) columns are twists about the tool point, in world coords
301+ ], # (robot_count, 6, max_dofs) columns are per-DOF twists about the tool point, in the caller's task frame
297302 dof_count : wp .array [wp .int32 ], # (robot_count,) number of controlled DOFs for each robot
298303 # outputs
299- result : wp .array3d [float ], # (robot_count, 6, max_dofs) = task_matrix @ jacobian_tool_world ; zero beyond dof_count
304+ result : wp .array3d [float ], # (robot_count, 6, max_dofs) = task_matrix @ jacobian_tool ; zero beyond dof_count
300305):
301- """Multiply a 6x6 task-space matrix by a tool-point Jacobian, ``result = task_matrix @ jacobian_tool_world``."""
306+ """Multiply a 6x6 task-space matrix by a tool-point Jacobian, ``result = task_matrix @ jacobian_tool``.
307+
308+ Frame-agnostic: ``task_matrix`` and ``jacobian_tool`` just need to be
309+ expressed in the same frame as each other, whatever that is (e.g. world
310+ for differential IK, the operational frame for hybrid force/motion
311+ control).
312+ """
302313 robot_idx , row , col = wp .tid ()
303314 if col >= dof_count [robot_idx ]:
304315 return
305316 total = float (0.0 )
306317 for task_axis in range (6 ):
307- total += task_matrix [robot_idx , row , task_axis ] * jacobian_tool_world [robot_idx , task_axis , col ]
318+ total += task_matrix [robot_idx , row , task_axis ] * jacobian_tool [robot_idx , task_axis , col ]
308319 result [robot_idx , row , col ] = total
309320
310321
0 commit comments