Skip to content

Question about sending motion command with uncalibrated URDF #293

@Dipan-Zhang

Description

@Dipan-Zhang

Hi all,

When I'm reading the code about sending motion commands to the robot, I found out that the common practice is to compute IK with an uncalibrated URDF at the server side.

And I've tested that an uncalibrated URDF can have a motion error of ~ 15mm, which significantly affects the motion accuracy. I'm wondering if there is a specific reason for computing FK/IK with an uncalibrated URDF within the server?

An Example here, use the robot model to solve IK and get joint positions,

def grasp_open_loop(self, object_xyz: np.ndarray):
"""Grasp the object in an open loop manner. We will just move to object_xyz and close the gripper.
Args:
object_xyz (np.ndarray): Location to grasp
Returns:
bool: True if successful, False otherwise
"""
model = self.robot.get_robot_model()
xyt = self.robot.get_base_pose()
relative_object_xyz = point_global_to_base(object_xyz, xyt)
joint_state = self.robot.get_joint_positions()
# We assume the current end-effector orientation is the correct one, going into this
ee_pos, ee_rot = model.manip_fk(joint_state)
# If we failed, or if we are not servoing, then just move to the object
target_joint_positions, _, _, success, _ = self.robot_model.manip_ik_for_grasp_frame(
relative_object_xyz, ee_rot, q0=joint_state
)

Robot kinematic model initiated from uncalibrated URDF (by default):

# urdf
if not urdf_path:
manip_urdf = MANIP_STRETCH_URDF
else:
manip_urdf = os.path.join(urdf_path, "stretch.urdf")
self.manip_mode_urdf_path = os.path.join(root, manip_urdf)

I found out there exists a better solution to directly call goto_ee_pose (which already exists in manip.py) and solve the Ik from the robot side with calibrated URDF

@enforce_enabled
def goto_ee_pose(
self,
pos: List[float],
quat: Optional[List[float]] = None,
relative: bool = False,
world_frame: bool = False,
blocking: bool = True,
debug: bool = False,
initial_cfg: np.ndarray = None,
) -> bool:
"""Command gripper to pose
Does not rotate base.
Cannot be used in navigation mode.
Args:
pos: Desired position
quat: Desired orientation in quaternion (xyzw)
relative: Whether specified pose is relative to current pose
world_frame: Infer poses in world frame instead of base frame
blocking: Whether command blocks until completion
initial_cfg: Preferred (initial) joint state configuration
"""
full_body_cfg = self.solve_ik(pos, quat, relative, world_frame, initial_cfg, debug)
if full_body_cfg is None:
print("Warning: Cannot find an IK solution for desired EE pose!")
return False
joint_pos = self._extract_joint_pos(full_body_cfg)
self.goto_joint_positions(joint_pos, blocking=blocking, debug=debug)
# Debug print
if debug and blocking:
pos, quat = self.get_ee_pose()
print(f"Achieved EE pose: pos={pos}; quat={quat}")
print("=======================")
return True

In this way, we can get rid of all the FK/ IK computation on the server side and all the thresholding of motion errors, and leave them all to be taken care of at ROS/ robot side

Look forward to your feedback!

Best,
Anran

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions