ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

AttributeError: 'tuple' object has no attribute 'serialize' - after attempting to execute a plan

asked 2021-04-27 10:47:43 -0500

meowatthemoon gravatar image

Hello.

I'm using moveit's move_group_interface in Python 3 and ROS Noetic. I'm trying to save a plan (trajectory), then load it and execute.

    pose_goal = geometry_msgs.msg.Pose()
    pose_goal.orientation.x = 0
    pose_goal.orientation.y = 0.7071068
    pose_goal.orientation.z = 0
    pose_goal.orientation.w = 0.7071068
    pose_goal.position.x = x
    pose_goal.position.y = y
    pose_goal.position.z = z

    self.move_group.set_pose_target(pose_goal)
    plan = self.move_group.plan()

    file_path =  'plan.yaml'
    with open(file_path, 'w') as file_save:
            yaml.dump(plan, file_save, default_flow_style=True)

    with open(file_path, 'r') as file_open:
            loaded_plan = yaml.load(file_open)
    self.move_group.execute(loaded_plan)

The execute line outputs:

    AttributeError: 'tuple' object has no attribute 'serialize'

Even if I replace the execute(loaded_plan ) with execute(plan) it still outputs the same error which leads me to believe the error is not in the saving/loading part.

Robot: Universal Robot 5 (UR5) Interface: moveit/move_group_interface in Pyhon

Thanks

edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted
3

answered 2021-04-27 11:04:49 -0500

gvdhoorn gravatar image

updated 2021-04-27 11:13:01 -0500

The return value of move_group.plan() may be yaml.dump(..)-able, but the yaml.load(..)-ed version of that is just a dict, not an actual Plan instance.

move_group.execute(..) does not take a dict, hence the error message when it tries to use whatever you're passing it as a Plan.

From the move_group.py documentation:

 def plan(self, joints=None):
     """Return a tuple of the motion planning results such as
     (success flag : boolean, trajectory message : RobotTrajectory,
      planning time : float, error code : MoveitErrorCodes)"""
     if type(joints) is JointState:
         self.set_joint_value_target(joints)

     elif type(joints) is Pose:
         self.set_pose_target(joints)

     elif joints is not None:
         try:
             self.set_joint_value_target(self.get_remembered_joint_values()[joints])
         except MoveItCommanderException:
             self.set_joint_value_target(joints)

     (error_code_msg, trajectory_msg, planning_time) = self._g.plan()

     error_code = MoveItErrorCodes()
     error_code.deserialize(error_code_msg)
     plan = RobotTrajectory()
     return (
         error_code.val == MoveItErrorCodes.SUCCESS,
         plan.deserialize(trajectory_msg),
         planning_time,
         error_code,
     )

Note how the return value is a tuple, with at least one element being a RobotTrajectory instance.

You might be able to transform one of the members of the dict you yaml.load(..) into a RobotTrajectory instance again using something like rospy_message_converter, but no guarantees.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2021-04-27 10:47:43 -0500

Seen: 1,908 times

Last updated: Aug 18 '21