| from __future__ import annotations |
|
|
| import numpy as np |
|
|
| from eval.dual_push_retarget_utils import ( |
| backproject_depth_to_world, |
| delta_action_from_absolute_targets, |
| estimate_dual_push_target_positions_from_front_rgbd, |
| extract_dual_push_button_positions, |
| make_bimanual_absolute_action, |
| parse_dual_push_target_colors, |
| retarget_demo_pose_to_live_button, |
| ) |
|
|
|
|
| def test_extract_dual_push_button_positions_reads_expected_slices() -> None: |
| state = np.arange(136, dtype=np.float32) |
|
|
| button0, button1, button2 = extract_dual_push_button_positions(state) |
|
|
| assert button0.tolist() == [7.0, 8.0, 9.0] |
| assert button1.tolist() == [14.0, 15.0, 16.0] |
| assert button2.tolist() == [21.0, 22.0, 23.0] |
|
|
|
|
| def test_retarget_demo_pose_to_live_button_translates_position_only() -> None: |
| demo_pose = np.array([0.4, 0.5, 0.6, 0.0, 0.0, 0.0, 1.0], dtype=np.float32) |
| demo_button = np.array([0.1, 0.2, 0.3], dtype=np.float32) |
| live_button = np.array([0.3, -0.1, 0.7], dtype=np.float32) |
|
|
| retargeted = retarget_demo_pose_to_live_button(demo_pose, demo_button, live_button) |
|
|
| np.testing.assert_allclose(retargeted[:3], np.array([0.6, 0.2, 1.0], dtype=np.float32)) |
| np.testing.assert_allclose(retargeted[3:], demo_pose[3:]) |
|
|
|
|
| def test_make_bimanual_absolute_action_packs_expected_layout() -> None: |
| right_pose = np.array([1, 2, 3, 0, 0, 0, 1], dtype=np.float32) |
| left_pose = np.array([4, 5, 6, 0, 0, 1, 0], dtype=np.float32) |
|
|
| action = make_bimanual_absolute_action(right_pose, left_pose, 1.0, 0.0) |
|
|
| assert action.shape == (18,) |
| np.testing.assert_allclose(action[:7], right_pose) |
| np.testing.assert_allclose(action[9:16], left_pose) |
| assert action[7] == 1.0 |
| assert action[8] == 1.0 |
| assert action[16] == 0.0 |
| assert action[17] == 1.0 |
|
|
|
|
| def test_delta_action_from_absolute_targets_matches_translation_and_gripper() -> None: |
| current_right = np.array([0.1, 0.2, 0.3, 0.0, 0.0, 0.0, 1.0], dtype=np.float32) |
| current_left = np.array([-0.1, 0.4, 0.2, 0.0, 0.0, 0.0, 1.0], dtype=np.float32) |
| target_right = np.array([0.15, 0.1, 0.35, 0.0, 0.0, 0.0, 1.0], dtype=np.float32) |
| target_left = np.array([-0.05, 0.5, 0.25, 0.0, 0.0, 0.0, 1.0], dtype=np.float32) |
|
|
| delta = delta_action_from_absolute_targets( |
| current_right, |
| current_left, |
| target_right, |
| target_left, |
| right_gripper_open=1.0, |
| left_gripper_open=0.0, |
| ) |
|
|
| np.testing.assert_allclose(delta[:3], np.array([0.05, -0.1, 0.05], dtype=np.float32), atol=1e-6) |
| np.testing.assert_allclose(delta[7:10], np.array([0.05, 0.1, 0.05], dtype=np.float32), atol=1e-6) |
| np.testing.assert_allclose(delta[3:6], np.zeros(3, dtype=np.float32), atol=1e-6) |
| np.testing.assert_allclose(delta[10:13], np.zeros(3, dtype=np.float32), atol=1e-6) |
| assert delta[6] == 1.0 |
| assert delta[13] == 0.0 |
|
|
|
|
| def test_delta_action_from_absolute_targets_captures_rotation_delta() -> None: |
| current_right = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], dtype=np.float32) |
| current_left = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], dtype=np.float32) |
| half_turn_z_xyzw = np.array([0.0, 0.0, np.sin(np.pi / 4.0), np.cos(np.pi / 4.0)], dtype=np.float32) |
| target_right = np.concatenate([np.zeros(3, dtype=np.float32), half_turn_z_xyzw], axis=0) |
| target_left = current_left.copy() |
|
|
| delta = delta_action_from_absolute_targets( |
| current_right, |
| current_left, |
| target_right, |
| target_left, |
| right_gripper_open=1.0, |
| left_gripper_open=1.0, |
| ) |
|
|
| np.testing.assert_allclose(delta[:3], np.zeros(3, dtype=np.float32), atol=1e-6) |
| np.testing.assert_allclose(delta[7:13], np.zeros(6, dtype=np.float32), atol=1e-6) |
| assert abs(float(delta[5])) > 1.4 |
|
|
|
|
| def test_parse_dual_push_target_colors_reads_both_targets() -> None: |
| assert parse_dual_push_target_colors("push the olive and the orange buttons") == ("olive", "orange") |
|
|
|
|
| def test_backproject_depth_to_world_handles_signed_focal_lengths() -> None: |
| depth = np.array([[0.75]], dtype=np.float32) |
| intrinsics = np.array([[-100.0, 0.0, 0.0], [0.0, -100.0, 0.0], [0.0, 0.0, 1.0]], dtype=np.float32) |
| extrinsics = np.eye(4, dtype=np.float32) |
|
|
| points = backproject_depth_to_world(depth, intrinsics, extrinsics) |
|
|
| np.testing.assert_allclose(points[0, 0], np.array([0.0, 0.0, 0.75], dtype=np.float32)) |
|
|
|
|
| def test_estimate_dual_push_target_positions_from_front_rgbd_finds_color_centers() -> None: |
| rgb = np.zeros((3, 8, 8), dtype=np.float32) |
| depth = np.full((8, 8), 0.75, dtype=np.float32) |
| rgb[:, 2:4, 1:3] = np.array([128.0, 128.0, 0.0], dtype=np.float32)[:, None, None] / 255.0 |
| rgb[:, 2:4, 5:7] = np.array([255.0, 128.0, 0.0], dtype=np.float32)[:, None, None] / 255.0 |
| intrinsics = np.array([[-100.0, 0.0, 3.5], [0.0, -100.0, 3.5], [0.0, 0.0, 1.0]], dtype=np.float32) |
| extrinsics = np.eye(4, dtype=np.float32) |
|
|
| right, left = estimate_dual_push_target_positions_from_front_rgbd( |
| rgb, |
| depth, |
| intrinsics, |
| extrinsics, |
| "push the olive and the orange buttons", |
| ) |
|
|
| assert right is not None |
| assert left is not None |
| assert right[0] > left[0] |
| np.testing.assert_allclose(right[2], 0.75, atol=1e-4) |
| np.testing.assert_allclose(left[2], 0.75, atol=1e-4) |
|
|