Robot / tests /test_task_nullspace.py
Duc Do
Upload 254 files
6686473 verified
Raw
History Blame Contribute Delete
2.73 kB
import numpy as np
import pytest
from llm_panda.task_nullspace import (
CylinderTaskManifold,
BoxTaskManifold,
TaskManifoldFactory
)
def _get_spatial_velocity_fd(manifold, u, du, delta=1e-6):
"""Compute finite difference spatial twist for testing."""
T_plus = manifold.get_transform(u + du * delta)
T_minus = manifold.get_transform(u - du * delta)
# spatial velocity [v; w] such that T_plus = T_minus * exp(twist * 2 * delta)
# roughly, T_dot = (T_plus - T_minus) / (2 * delta)
# Spatial velocity in base frame:
# v = p_dot
# [w]_x = R_dot * R^T
R_plus = T_plus[:3, :3]
R_minus = T_minus[:3, :3]
p_plus = T_plus[:3, 3]
p_minus = T_minus[:3, 3]
v = (p_plus - p_minus) / (2 * delta)
R_dot = (R_plus - R_minus) / (2 * delta)
# mid R is approx R_minus
R_mid = manifold.get_transform(u)[:3, :3]
w_cross = R_dot @ R_mid.T
w = np.array([w_cross[2, 1], w_cross[0, 2], w_cross[1, 0]])
return np.concatenate([v, w])
def test_cylinder_manifold_jacobian():
# Random object pose
T_obj = np.eye(4)
T_obj[:3, 3] = [0.1, 0.2, 0.3]
# Rotate 90 deg around X
T_obj[:3, :3] = np.array([
[1, 0, 0],
[0, 0, -1],
[0, 1, 0]
])
T_offset = np.eye(4)
T_offset[:3, 3] = [0, 0, 0.05]
manifold = TaskManifoldFactory.create_manifold("cylinder", T_obj, {"height": 0.2}, T_offset)
# Check bounds
bounds = manifold.get_bounds()
assert len(bounds) == 2
assert bounds[0] == (-0.1, 0.1)
u = np.array([0.05, np.pi/4])
J_analytical = manifold.get_transform_jacobian(u)
# Finite difference for z
v_z_fd = _get_spatial_velocity_fd(manifold, u, np.array([1.0, 0.0]))
# Finite difference for theta
v_theta_fd = _get_spatial_velocity_fd(manifold, u, np.array([0.0, 1.0]))
J_fd = np.column_stack([v_z_fd, v_theta_fd])
np.testing.assert_allclose(J_analytical, J_fd, atol=1e-5)
def test_box_manifold_jacobian():
T_face = np.eye(4)
T_face[:3, 3] = [0.5, -0.2, 0.1]
T_offset = np.eye(4)
T_offset[:3, 3] = [0, 0.02, 0.05]
manifold = TaskManifoldFactory.create_manifold("box", T_face, {"width": 0.1, "height": 0.2}, T_offset)
u = np.array([0.02, -0.03, np.pi/3])
J_analytical = manifold.get_transform_jacobian(u)
J_u_fd = _get_spatial_velocity_fd(manifold, u, np.array([1.0, 0.0, 0.0]))
J_v_fd = _get_spatial_velocity_fd(manifold, u, np.array([0.0, 1.0, 0.0]))
J_theta_fd = _get_spatial_velocity_fd(manifold, u, np.array([0.0, 0.0, 1.0]))
J_fd = np.column_stack([J_u_fd, J_v_fd, J_theta_fd])
np.testing.assert_allclose(J_analytical, J_fd, atol=1e-5)