Skip to content

Commit 73ff212

Browse files
committed
better image - less reactive controller.
1 parent fd58359 commit 73ff212

3 files changed

Lines changed: 20 additions & 11 deletions

File tree

3.56 KB
Loading

newton/_src/controllers/impl/_common.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ def _shift_jacobian_to_tool_kernel(
157157

158158
@wp.kernel
159159
def _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
292297
def _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

newton/examples/controllers/example_controller_differential_ik.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
JOINT_TARGET_KE = 3000.0
8484
JOINT_TARGET_KD = 100.0
8585

86-
BANDWIDTH = 20.0
86+
BANDWIDTH = 5.0
8787
# Empirically tuned against this example's continuous velocity-based control
8888
# loop (see IkMethod.ADAPTIVE_DAMPING).
8989
ADAPTIVE_DAMPING_MIN = 0.02
@@ -202,8 +202,6 @@ def __init__(self, viewer, args):
202202
wp.transform(*body_q_np[ur10_tool_body].tolist()) * ur10_tool_site_transform,
203203
wp.transform(*body_q_np[planar_tool_body].tolist()) * planar_tool_site_transform,
204204
]
205-
# Only the planar arm's gizmo is axis-restricted -- Franka's and
206-
# UR10's keep the default full 6-DOF widget (None = every axis).
207205
self.gizmo_axes = [
208206
{"translate": None, "rotate": None},
209207
{"translate": None, "rotate": None},

0 commit comments

Comments
 (0)