How to know when each point in the trajectory was executed?

asked 2023-06-22 13:24:59 -0500

arisigor gravatar image

updated 2023-06-26 14:25:06 -0500

I'm new to ROS. I wrote the code below to execute a trajectory using SimpleActionClient. I need to know when each point in the trajectory was executed while the trajectory is being executed. I thought to use the feedback callback from action client's send_goal method, but it's never called. The done_cb and active_cb are called, but not feedback_cb. Then, I thought since each point has time_from_start field I could listen to /feedback_states topic (see list of topics below) and check the the time_from_start field (see the feedback_state output below). But, it's always 0.

What am I doing wrong? Or, even better, is this how to get what I need or is there another better way?

UPDATE1

Just to clarify, I want to control the Yaskawa hc10 robot from ROS AND be able to know what trajectory point it's currently executing. After the research I saw that I should use motoman driver. I found some python example and continued from there. So, the first part seems to work. But, now I need to make the second part to work. To do that I decided to check the time_from_start field from the message from /feedback_states topic since I assign time_from_start to each point when I build the trajectory object. But, when I do rostopic echo /joint_states I can see that time_from_start is always 0 and doesn't have the values I assigned.

Therefore, I decided a different approach - listen to joint_states topic and do the following:

  • I consider 6-joint values as a vector.
  • Now, I have the target point (6-joint values) that I want the robot to reach and current positions that I receive from joint_states topic. Therefore,

For each received point:

  • Calculate distance between current point and target point (numpy.norm(current_point - target_point))
  • As the arm approaches the target point, the distance (norm) value should decrease. If current distance is greater than previous distance, I consider that it has reached the target point.

Does this make sense? I'll post the issues I have with this approach if needed, unless you already know what can be the issues.

Code

client = actionlib.SimpleActionClient('/joint_trajectory_action', FollowJointTrajectoryAction)
        if not client.wait_for_server(rospy.Duration(5.0)):
            raise RuntimeError("Action server not available!")

def _create_trajpoint(self, joint_positions, time_from_start, velocities) -> JointTrajectoryPoint:
        point = JointTrajectoryPoint()
        point.positions = joint_positions
        point.time_from_start = rospy.Duration(time_from_start)
        point.velocities = velocities

        return point

def _execute_trajectory(self, traj):
        self._send_trajectory_to_controller(traj)
        self._wait_for_traj_to_complete()

    def _send_trajectory_to_controller(self, traj):
        print("Sending trajectory")

        goal = FollowJointTrajectoryGoal()
        goal.trajectory = traj

        self._action_client.send_goal(goal, feedback_cb=my_feedback_cb, done_cb=my_done_cb, active_cb=my_active_cb)
        self._action_client.wait_for_result(rospy.Duration(2.0))

        print("Trajectory sent")

    def _wait_for_traj_to_complete(self):
        print('Waiting for trajectory to complete')

        wait_time = 0.1
        no_motion_total = 0
        no_motion_timeout = 1
        traj_state = self._action_client.get_state()
        while traj_state == actionlib.GoalStatus.ACTIVE:
            rospy.sleep(wait_time)

            traj_state = self._action_client.get_state()
            robot_status = self.get_robot_status()
            if robot_status.in_motion.val == 0: 
                no_motion_total += wait_time
                if no_motion_total > no_motion_timeout:
                    raise RuntimeError(f'Robot hasn\'t moved for {no_motion_timeout} sec. TrajState={traj_state}')
            else:
                no_motion_total = 0

        if traj_state == actionlib ...
(more)
edit retag flag offensive close merge delete

Comments

Quick note: I don't believe you can. From the messages you show, this looks like motoman_driver. Due to how caching works on the MotoROS1 side (it has an internal queue, and the underlying Yaskawa controller code has yet another internal queue), you can't rely on what the driver tells you -- at least not about the state of the action server. What you could do is look at the joint_states topic and derive progress from that. That's non-trivial though, as "loops" in a trajectory would make comparisons difficult.

I'm sorry there isn't something nicer to write, but I believe it's a fundamental limitation of how the system is implemented (and technically, any driver / robot controller with (an) internal queue(s) would make really knowing how much of a trajectory has been executed impossible, not just in the case of Yaskawa. I only know of Staubli ...(more)

gvdhoorn gravatar image gvdhoorn  ( 2023-06-22 14:30:41 -0500 )edit

Btw, if you're specifically interested in detecting whether the robot has moved or not, the robot_status topic carries that information.

gvdhoorn gravatar image gvdhoorn  ( 2023-06-22 14:33:14 -0500 )edit

What about /feedback_states or /joint_trajectory_action/feedback topics? Why only the positions in actual section is filled but all other is empty? What's the point of these topics then if they don't report data?

arisigor gravatar image arisigor  ( 2023-06-22 14:45:00 -0500 )edit

You'd have to ask the original developers I'm afraid. I can't answer that.

gvdhoorn gravatar image gvdhoorn  ( 2023-06-22 14:45:49 -0500 )edit

sorry, do you know where would I ask? I thought ROS community is the place to ask.

arisigor gravatar image arisigor  ( 2023-06-22 14:53:37 -0500 )edit

That would be a post on ros-industrial/motoman/discussions. Note though: motoman_driver is really old, almost 12 years now. Only one of the original developers would maybe respond, and I don't know whether he'd still remember.

gvdhoorn gravatar image gvdhoorn  ( 2023-06-22 14:55:58 -0500 )edit

Can I ask what's your recommendation to control the Yaskawa from ROS? Yaskawa have a dedicated driver, but it's not free. If I use ROS, what's my alternative to motoman_driver?

arisigor gravatar image arisigor  ( 2023-06-22 15:01:46 -0500 )edit

Yaskawa have a dedicated driver, but it's not free

I'm not sure I understand what you mean by this. Which product are you referring to?

If I use ROS, what's my alternative to motoman_driver?

I would not know of an alternative.

gvdhoorn gravatar image gvdhoorn  ( 2023-06-22 15:05:13 -0500 )edit