An actionlib example – robot arm client

Let's go back to the previous chapter and run our robot arm Gazebo example that we built:

$ roslaunch robot_description mobile_manipulator_gazebo_xacro.launch

Now, in another Terminal, run $ rostopic list. Do you see anything interesting? Look at the following screenshot:

Robot arm Gazebo ROS topics

Do you see a list of topics that end with /goal, /cancel, /result, /status, and /feedback? That's an ROS action implementation.

joint_trajectory_controller is used for executing joint space trajectories on a list of given joints. The trajectories to the controller are sent by means of the control_msgs::FollowJointTrajectoryAction action interface in the follow_joint_trajectory namespace of the controller. FollowJointTracjectoryAction is a result of position_controllers/JointTrajectoryController, which we called as the arm_controller plugin.

You can find more information about this at http://wiki.ros.org/joint_trajectory_controller. The FollowJointTrajectoryAction definition can be found here: http://docs.ros.org/api/control_msgs/html/action/FollowJointTrajectory.html.

As a result of the arm_controller plugin call, the FollowJointTrajectory action server is already implemented as part of the Gazebo node. You can see that the topics ending with /result, /status, and /feedback are published by the Gazebo node (alias, the robot) and the topics ending with /goal and /cancel are being subscribed to by the robot. Hence, to move the robot arm, we need to send a goal to the action server that's been implemented. Let's learn how to send goals to our robot arm via an action client implementation. Have a look at the following function for an action client implementation

  • Before getting into the code, let's create the chapter_4_ws workspace and arm client package using the following commands:
$ initros1
$ mkdir -p /chapter_4_ws/src
$ cd ~/chapter_4_ws/src
$ catkin_init_workspace
$ catkin_create_pkg arm_client
$ cd ~/chapter_4_ws/src/arm_client

Let's break down the code into chunks and try to understand it. The following lines of code are the necessary import statements for using ROS functions, the action library, and ROS messages:

import rospy
import actionlib
from std_msgs.msg import Float64
from trajectory_msgs.msg import JointTrajectoryPoint
from control_msgs.msg import JointTrajectoryAction, JointTrajectoryGoal, FollowJointTrajectoryAction, FollowJointTrajectoryGoal

In our main program, we initialize our node and client and send the goal. We're using SimpleActionClient in our example. We call the server name, arm_controller/follow_joint_trajectory, which is a result of the ros_controller plugin and its message type. We then wait for a response from the server. Once the response is received, the move_joint function is executed:

if __name__ == '__main__':
rospy.init_node('joint_position_tester')
client = actionlib.SimpleActionClient('arm_controller/follow_joint_trajectory', FollowJointTrajectoryAction)
client.wait_for_server()
move_joint([-0.1, 0.210116830848170721, 0.022747275919015486, 0.0024182584123728645, 0.00012406874824844039])

The move_joint() function accepts the angle values of each joint and sends them as a trajectory to the robot arm. As you may recall from the previous chapter, we published some information to the /arm_controller/follow_joint_trajectory/command topic. We need to pass the same information via the FollowJointTrajectoryGoal() message, which needs joint_names, points (that is, joint values), and the time to move the arm to a specified trajectory:

def move_joint(angles):
goal = FollowJointTrajectoryGoal()
goal.trajectory.joint_names = ['arm_base_joint', 'shoulder_joint','bottom_wrist_joint' ,'elbow_joint', 'top_wrist_joint']
point = JointTrajectoryPoint()
point.positions = angles
point.time_from_start = rospy.Duration(3)
goal.trajectory.points.append(point)

The following line of code is used to send a goal via the client. This function will send the goal until the goal is complete. You can also define a timeout here and wait until the timeout is exceeded:

client.send_goal_and_wait(goal)

The preceding example of the SimpleActionClient implementation supports only one goal at a time. This is an easy to use wrapper for the user.

You can test the preceding code using the following steps:

  1. In one Terminal, open the robot Gazebo file using the following command:
$ cd ~/chapter_3_ws/
$ source devel/setup.bash
$ roslaunch robot_description mobile_manipulator_gazebo_xacro.launch
  1. In another Terminal, run the action client file to see the robot arm move. You can do this with the following command:
$ cd ~/chapter_4_ws/
$ source devel/setup.bash
$ rosrun arm_client arm_action_client.py

You should see that the arm moves to the given position in the code.

Now, let's look at another example.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.144.197