Skip to content

Update atom action - #432

Draft
matafela wants to merge 1 commit into
mainfrom
cj/update-atom-action
Draft

Update atom action#432
matafela wants to merge 1 commit into
mainfrom
cj/update-atom-action

Conversation

@matafela

@matafela matafela commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Description

TODO:

  • Coordinate pickment using auto-generated grasp pose.
  • Hand over atom action
  • Assemble affordance

Type of change

  • Enhancement (non-breaking change which improves an existing functionality)

Checklist

  • I have run the black . command to format the code base.
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works
  • Dependencies have been updated, if applicable.

Copilot AI review requested due to automatic review settings July 28, 2026 07:31
@matafela
matafela marked this pull request as draft July 28, 2026 07:32

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the coordinated pickment workflow to use affordance-driven (auto-generated) antipodal grasp poses, and refactors atomic-action plumbing to accept a simpler grasp target.

Changes:

  • Switched the coordinated pickment tutorial to use create_antipodal_semantics() and run the action via GraspTarget.
  • Added dual-arm grasp pose generation plumbing (Affordance.get_dual_arm_valid_grasp_poses and AntipodalGenerator.get_dual_arm_valid_grasp_poses) and refactored the generator’s filtering path.
  • Refactored PickUp trajectory assembly and rewired CoordinatedPickment to plan grasp/lift trajectories from affordance-sampled grasps.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
scripts/tutorials/atomic_action/coordinated_pickment.py Tutorial now uses create_antipodal_semantics() + GraspTarget for coordinated pickment planning.
embodichain/toolkits/graspkit/pg_grasp/antipodal_generator.py Adds dual-arm antipodal grasp selection and refactors valid-grasp filtering.
embodichain/lab/sim/sim_manager.py Minor whitespace cleanup during sim manager initialization.
embodichain/lab/sim/atomic_actions/primitives/pick_up.py Refactors trajectory construction into a helper; keeps behavior but reorganizes execution.
embodichain/lab/sim/atomic_actions/primitives/coordinated_pickment.py Changes TargetType and replumbs coordinated pickment to use affordance-driven dual-arm grasps and new planning helpers.
embodichain/lab/sim/atomic_actions/affordance.py Adds get_dual_arm_valid_grasp_poses() wrapper around the antipodal generator.
embodichain/lab/gym/utils/gym_utils.py Changes --num_envs default handling in CLI argument setup.
Comments suppressed due to low confidence (2)

embodichain/lab/sim/atomic_actions/primitives/coordinated_pickment.py:544

  • The padding loop also assumes grasp_poses_result[i] is a dict and does not filter out per-side failures (is_success=False). This can lead to shape errors when failed results carry placeholder poses/costs, or to selecting invalid grasps.
        for i in range(n_envs):
            left_result = grasp_poses_result[i]["left"]
            right_result = grasp_poses_result[i]["right"]
            if left_result is not None:

embodichain/toolkits/graspkit/pg_grasp/antipodal_generator.py:801

  • The collision-check failure path (immediately after this _collision_checker.query(...) call) returns placeholder values with inconsistent types/shapes ((4,4) pose, float open-length, cost=0). Downstream code assumes batched tensors and may treat the failure as a valid best-grasp due to the zero cost.
        is_colliding, max_penetration = self._collision_checker.query(
            object_pose,
            valid_grasp_poses,

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 788 to 792
"--num_envs",
help="The number of environments to run in parallel. "
"If not given, falls back to the gym config's `num_envs` (default 1).",
default=None,
default=1,
type=int,
Comment on lines +152 to +159
for i, obj_pose in enumerate(obj_poses):
result = self._generator.get_dual_arm_valid_grasp_poses(
object_pose=obj_pose,
approach_direction=approach_direction,
left_to_right_arm_direction=left_to_right_arm_direction,
middle_empty_ratio=middle_empty_ratio,
)
results.append(result)
Comment on lines 752 to 756
return (
False,
torch.eye(4, device=self.device),
0.0,
torch.zeros(1, device=self.device),
Comment on lines 390 to 394
class CoordinatedPickment(AtomicAction):
"""Pick and move a single object pinched by two hands."""

TargetType: ClassVar[type] = CoordinatedPickmentTarget
TargetType: ClassVar[type] = GraspTarget

Comment on lines +668 to +672
def execute(self, target: GraspTarget, state: WorldState) -> ActionResult:
left_start_qpos, right_start_qpos = self._resolve_dual_arm_start(state)
left_grasp_xpos, right_grasp_xpos = self._resolve_grasp_pose(
target.semantics, left_start_qpos, right_start_qpos
)
Comment on lines +504 to +511
for i in range(n_envs):
left_result = grasp_poses_result[i]["left"]
right_result = grasp_poses_result[i]["right"]
if left_result is None or right_result is None:
logger.log_warning(
f"Failed to find valid dual-arm grasp poses for {i}-th enviroment."
)
continue
Comment on lines +704 to +709
full_trajectory[:, :, :] = last_qpos.unsqueeze(1)

hold_trajectory = torch.empty(
(self.n_envs, 0, self.robot_dof), dtype=torch.float32, device=self.device
# pading trajectory end to match the max length
full_trajectory[:, :n_left_waypoints, self.left_arm_joint_ids] = left_arm_traj
full_trajectory[:, :n_left_waypoints, self.left_hand_joint_ids] = left_hand_traj
full_trajectory[:, :n_right_waypoints, self.right_arm_joint_ids] = (
Comment on lines 715 to 722
return ActionResult(
success=success_mask,
trajectory=full,
success=is_success,
trajectory=full_trajectory,
next_state=WorldState(
last_qpos=full[:, -1, :].clone(),
last_qpos=full_trajectory[:, -1, :].clone(),
held_object=None,
coordinated_held_object=coordinated_held_object,
coordinated_held_object=state.coordinated_held_object,
),
Comment on lines 74 to +78
PICKMENT_ASSET_ROOT = "CoordinatedPlacementAndPickment"
GRIPPER_MAX_OPEN_WIDTH = 0.080
GRIPPER_FINGER_LENGTH = 0.088
GRIPPER_ROOT_Z_WIDTH = 0.096
GRIPPER_Y_THICKNESS = 0.040
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants