@@ -335,17 +335,79 @@ def _setup_mink(self):
335335 self .damping = 1e-3
336336 self .rate_limiter = RateLimiter (frequency = 1000 , warn = False )
337337
338+ def world_to_robot_frame (self , world_position , world_orientation ):
339+ """Transform pose from world frame to robot base frame.
340+
341+ Args:
342+ world_position: Position in world frame [x, y, z]
343+ world_orientation: Orientation in world frame [qx, qy, qz, qw]
344+
345+ Returns:
346+ Tuple of (robot_position, robot_orientation) in robot base frame
347+ """
348+ from scipy .spatial .transform import Rotation
349+
350+ # Get robot base pose in world frame
351+ base_position = self .robot .get_position ()
352+ base_orientation = self .robot .get_orientation ()
353+
354+ # Create transformation matrices
355+ base_rot = Rotation .from_quat (base_orientation )
356+ world_rot = Rotation .from_quat (world_orientation )
357+
358+ # Transform position: subtract base position and rotate
359+ relative_position = world_position - base_position
360+ robot_position = base_rot .inv ().apply (relative_position )
361+
362+ # Transform orientation: compose rotations
363+ robot_orientation = (base_rot .inv () * world_rot ).as_quat ()
364+
365+ return robot_position , robot_orientation
366+
367+ def robot_to_world_frame (self , robot_position , robot_orientation ):
368+ """Transform pose from robot base frame to world frame.
369+
370+ Args:
371+ robot_position: Position in robot base frame [x, y, z]
372+ robot_orientation: Orientation in robot base frame [qx, qy, qz, qw]
373+
374+ Returns:
375+ Tuple of (world_position, world_orientation) in world frame
376+ """
377+ from scipy .spatial .transform import Rotation
378+
379+ # Get robot base pose in world frame
380+ base_position = self .robot .get_position ()
381+ base_orientation = self .robot .get_orientation ()
382+
383+ # Create transformation matrices
384+ base_rot = Rotation .from_quat (base_orientation )
385+ robot_rot = Rotation .from_quat (robot_orientation )
386+
387+ # Transform position: rotate and add base position
388+ world_position = base_rot .apply (robot_position ) + base_position
389+
390+ # Transform orientation: compose rotations
391+ world_orientation = (base_rot * robot_rot ).as_quat ()
392+
393+ return world_position , world_orientation
394+
338395 def compute_simple_ik (self , start_joint , target_pose , arm_id = "left_arm" ):
339396 """Compute inverse kinematics using Mink.
340397
341398 Args:
342399 start_joint: Initial joint configuration (not used in current implementation)
343- target_pose: Target pose [x, y, z, qx, qy, qz, qw] in world coordinates
400+ target_pose: Target pose [x, y, z, qx, qy, qz, qw] in robot base frame
344401 arm_id: The ID of the arm, either "left_arm" or "right_arm"
345402
346403 Returns:
347404 Target joint configuration for the specified arm
348405 """
406+ # Transform target pose from robot frame to world frame for IK
407+ target_position = target_pose [:3 ]
408+ target_orientation = target_pose [3 :7 ]
409+ world_position , world_orientation = self .robot_to_world_frame (target_position , target_orientation )
410+
349411 # Set target for chassis
350412 chassis_target = mink .SE3 .from_rotation_and_translation (
351413 rotation = mink .SO3 (wxyz = xyzw_to_wxyz (self .robot .get_orientation ())),
@@ -365,22 +427,18 @@ def compute_simple_ik(self, start_joint, target_pose, arm_id="left_arm"):
365427 # Set target for posture
366428 self .tasks ["posture" ].set_target_from_configuration (self .mink_config )
367429
368- # Extract position and orientation from target pose
369- target_position = target_pose [:3 ]
370- target_orientation = target_pose [3 :7 ] # [qx, qy, qz, qw]
371-
372- # Set target for the specified arm
430+ # Set target for the specified arm using world frame pose
373431 if arm_id == "left_arm" :
374432 target = mink .SE3 .from_rotation_and_translation (
375- rotation = mink .SO3 (wxyz = xyzw_to_wxyz (target_orientation )),
376- translation = target_position
433+ rotation = mink .SO3 (wxyz = xyzw_to_wxyz (world_orientation )),
434+ translation = world_position
377435 )
378436 self .tasks ["left_arm" ].set_target (target )
379437 tasks = [self .tasks ["torso" ], self .tasks ["posture" ], self .tasks ["chassis" ], self .tasks ["left_arm" ]]
380438 elif arm_id == "right_arm" :
381439 target = mink .SE3 .from_rotation_and_translation (
382- rotation = mink .SO3 (wxyz = xyzw_to_wxyz (target_orientation )),
383- translation = target_position
440+ rotation = mink .SO3 (wxyz = xyzw_to_wxyz (world_orientation )),
441+ translation = world_position
384442 )
385443 self .tasks ["right_arm" ].set_target (target )
386444 tasks = [self .tasks ["torso" ], self .tasks ["posture" ], self .tasks ["chassis" ], self .tasks ["right_arm" ]]
@@ -513,14 +571,14 @@ def _move_left_arm_to_pose(self, target_position, target_orientation):
513571 """Move left arm to target pose with IK solving and motion control.
514572
515573 Args:
516- target_position: Target position [x, y, z]
517- target_orientation: Target orientation [qx, qy, qz, qw]
574+ target_position: Target position [x, y, z] in robot base frame
575+ target_orientation: Target orientation [qx, qy, qz, qw] in robot base frame
518576
519577 Returns:
520578 True if motion is complete, False otherwise
521579 """
522580 if not self .motion_in_progress :
523- # Prepare target pose
581+ # Prepare target pose in robot frame
524582 target_pose = np .concatenate ([target_position , target_orientation ])
525583
526584 # Solve IK and start motion
@@ -542,14 +600,14 @@ def _move_right_arm_to_pose(self, target_position, target_orientation):
542600 """Move right arm to target pose with IK solving and motion control.
543601
544602 Args:
545- target_position: Target position [x, y, z]
546- target_orientation: Target orientation [qx, qy, qz, qw]
603+ target_position: Target position [x, y, z] in robot base frame
604+ target_orientation: Target orientation [qx, qy, qz, qw] in robot base frame
547605
548606 Returns:
549607 True if motion is complete, False otherwise
550608 """
551609 if not self .motion_in_progress :
552- # Prepare target pose
610+ # Prepare target pose in robot frame
553611 target_pose = np .concatenate ([target_position , target_orientation ])
554612
555613 # Solve IK and start motion
@@ -602,7 +660,11 @@ def pick_and_place_callback(self):
602660
603661 def init_state ():
604662 """Move to initial pose"""
605- return self ._move_left_arm_to_pose ([0.5 , 0.3 , 0.7 ], [0 , 0.7071 , 0 , 0.7071 ])
663+ # Convert world frame pose to robot frame
664+ world_pos = np .array ([0.5 , 0.3 , 0.7 ])
665+ world_ori = np .array ([0 , 0.7071 , 0 , 0.7071 ])
666+ robot_pos , robot_ori = self .world_to_robot_frame (world_pos , world_ori )
667+ return self ._move_left_arm_to_pose (robot_pos , robot_ori )
606668
607669 def move_to_pre_pick_state ():
608670 """Move to pre-pick position"""
@@ -611,11 +673,19 @@ def move_to_pre_pick_state():
611673 self .cube_position = cube_state ["position" ].copy ()
612674 self .state_first_entry = False
613675
614- return self ._move_left_arm_to_pose (self .cube_position + np .array ([0 , 0 , 0.15 ]), [0 , 0.7071 , 0 , 0.7071 ])
676+ # Convert world frame pose to robot frame
677+ world_pos = self .cube_position + np .array ([0 , 0 , 0.15 ])
678+ world_ori = np .array ([0 , 0.7071 , 0 , 0.7071 ])
679+ robot_pos , robot_ori = self .world_to_robot_frame (world_pos , world_ori )
680+ return self ._move_left_arm_to_pose (robot_pos , robot_ori )
615681
616682 def move_to_pick_state ():
617683 """Move to pick position"""
618- return self ._move_left_arm_to_pose (self .cube_position + np .array ([0 , 0 , 0.03 ]), [0 , 0.7071 , 0 , 0.7071 ])
684+ # Convert world frame pose to robot frame
685+ world_pos = self .cube_position + np .array ([0 , 0 , 0.03 ])
686+ world_ori = np .array ([0 , 0.7071 , 0 , 0.7071 ])
687+ robot_pos , robot_ori = self .world_to_robot_frame (world_pos , world_ori )
688+ return self ._move_left_arm_to_pose (robot_pos , robot_ori )
619689
620690 def grasp_state ():
621691 """Grasp the object"""
@@ -631,7 +701,11 @@ def grasp_state():
631701
632702 def move_to_pre_place_state ():
633703 """Move to pre-place position"""
634- return self ._move_left_arm_to_pose (self .cube_position + np .array ([- 0.1 , 0 , 0.4 ]), [0 , 0.7071 , 0 , 0.7071 ])
704+ # Convert world frame pose to robot frame
705+ world_pos = self .cube_position + np .array ([- 0.1 , 0 , 0.4 ])
706+ world_ori = np .array ([0 , 0.7071 , 0 , 0.7071 ])
707+ robot_pos , robot_ori = self .world_to_robot_frame (world_pos , world_ori )
708+ return self ._move_left_arm_to_pose (robot_pos , robot_ori )
635709
636710 def move_to_place_state ():
637711 """Move to place position"""
@@ -640,7 +714,11 @@ def move_to_place_state():
640714 self .bin_position = bin_state ["position" ].copy ()
641715 self .state_first_entry = False
642716
643- return self ._move_left_arm_to_pose (self .bin_position + np .array ([0 , 0 , 0.3 ]), [0 , 0.7071 , 0 , 0.7071 ])
717+ # Convert world frame pose to robot frame
718+ world_pos = self .bin_position + np .array ([0 , 0 , 0.3 ])
719+ world_ori = np .array ([0 , 0.7071 , 0 , 0.7071 ])
720+ robot_pos , robot_ori = self .world_to_robot_frame (world_pos , world_ori )
721+ return self ._move_left_arm_to_pose (robot_pos , robot_ori )
644722
645723 def release_state ():
646724 """Release the object"""
0 commit comments