Go to the documentation of this file.00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <time.h>
00004 #include <ros/ros.h>
00005 #include <pr2_controllers_msgs/JointTrajectoryAction.h>
00006 #include <pr2_controllers_msgs/JointTrajectoryControllerState.h>
00007 #include <actionlib/client/simple_action_client.h>
00008 #include <kinematics_msgs/GetPositionIK.h>
00009 #include <kinematics_msgs/GetPositionFK.h>
00010 #include <pr2_laban_gazebo_demo/ExecuteCartesianIKTrajectory.h>
00011 #include <vector>
00012
00013 #define MAX_JOINT_VEL 0.5 //in radians/sec
00014
00015 static const std::string ARM_IK_NAME = "/pr2_right_arm_kinematics/get_ik";
00016 typedef actionlib::SimpleActionClient<pr2_controllers_msgs::
00017 JointTrajectoryAction> TrajClient;
00018
00019 class IKTrajectoryExecutor{
00020
00021 private:
00022 ros::NodeHandle node;
00023 ros::ServiceClient ik_client;
00024 ros::ServiceServer service;
00025 pr2_controllers_msgs::JointTrajectoryGoal goal;
00026 kinematics_msgs::GetPositionIK::Request ik_request;
00027 kinematics_msgs::GetPositionIK::Response ik_response;
00028 TrajClient *action_client;
00029
00030 public:
00031 IKTrajectoryExecutor(){
00032
00033
00034 ik_client = node.serviceClient<kinematics_msgs::GetPositionIK>
00035 (ARM_IK_NAME, true);
00036
00037
00038 ROS_INFO("Waiting for services to be ready");
00039 ros::service::waitForService(ARM_IK_NAME);
00040 ROS_INFO("Services ready");
00041
00042
00043
00044 action_client = new TrajClient("r_arm_controller/joint_trajectory_action", true);
00045
00046
00047 while(ros::ok() && !action_client->waitForServer(ros::Duration(5.0))){
00048 ROS_INFO("Waiting for the joint_trajectory_action action server to come up");
00049 }
00050
00051
00052 service = node.advertiseService("execute_cartesian_ik_trajectory",
00053 &IKTrajectoryExecutor::execute_cartesian_ik_trajectory, this);
00054
00055
00056
00057 goal.trajectory.joint_names.push_back("r_shoulder_pan_joint");
00058 goal.trajectory.joint_names.push_back("r_shoulder_lift_joint");
00059 goal.trajectory.joint_names.push_back("r_upper_arm_roll_joint");
00060 goal.trajectory.joint_names.push_back("r_elbow_flex_joint");
00061 goal.trajectory.joint_names.push_back("r_forearm_roll_joint");
00062 goal.trajectory.joint_names.push_back("r_wrist_flex_joint");
00063 goal.trajectory.joint_names.push_back("r_wrist_roll_joint");
00064
00065 }
00066
00067 ~IKTrajectoryExecutor(){
00068 delete action_client;
00069 }
00070
00071
00072
00073
00074
00075
00076
00077 bool run_ik(geometry_msgs::PoseStamped pose, double start_angles[7],
00078 double solution[7], std::string link_name){
00079
00080 kinematics_msgs::GetPositionIK::Request ik_request;
00081 kinematics_msgs::GetPositionIK::Response ik_response;
00082
00083 ik_request.timeout = ros::Duration(5.0);
00084 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_shoulder_pan_joint");
00085 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_shoulder_lift_joint");
00086 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_upper_arm_roll_joint");
00087 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_elbow_flex_joint");
00088 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_forearm_roll_joint");
00089 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_wrist_flex_joint");
00090 ik_request.ik_request.ik_seed_state.joint_state.name.push_back("r_wrist_roll_joint");
00091
00092 ik_request.ik_request.ik_link_name = link_name;
00093
00094 ik_request.ik_request.pose_stamped = pose;
00095 ik_request.ik_request.ik_seed_state.joint_state.position.resize(7);
00096
00097 for(int i=0; i<7; i++) ik_request.ik_request.ik_seed_state.joint_state.position[i] = start_angles[i];
00098
00099 ROS_INFO("request pose: %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f", pose.pose.position.x, pose.pose.position.y, pose.pose.position.z, pose.pose.orientation.x, pose.pose.orientation.y, pose.pose.orientation.z, pose.pose.orientation.w);
00100
00101 bool ik_service_call = ik_client.call(ik_request,ik_response);
00102 if(!ik_service_call){
00103 ROS_ERROR("IK service call failed!");
00104 return 0;
00105 }
00106 if(ik_response.error_code.val == ik_response.error_code.SUCCESS){
00107 for(int i=0; i<7; i++){
00108 solution[i] = ik_response.solution.joint_state.position[i];
00109 }
00110 ROS_INFO("solution angles: %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f",
00111 solution[0],solution[1], solution[2],solution[3],
00112 solution[4],solution[5],solution[6]);
00113 ROS_INFO("IK service call succeeded");
00114 return 1;
00115 }
00116 ROS_INFO("IK service call error code: %d", ik_response.error_code.val);
00117 return 0;
00118 }
00119
00120
00121
00122 void get_current_joint_angles(double current_angles[7]){
00123 int i;
00124
00125
00126 pr2_controllers_msgs::JointTrajectoryControllerStateConstPtr state_msg =
00127 ros::topic::waitForMessage<pr2_controllers_msgs::JointTrajectoryControllerState>
00128 ("r_arm_controller/state");
00129
00130
00131 for(i=0; i<7; i++){
00132 current_angles[i] = state_msg->actual.positions[i];
00133 }
00134 }
00135
00136
00137
00138
00139 bool execute_joint_trajectory(std::vector<double *> joint_trajectory){
00140 int i, j;
00141 int trajectorylength = joint_trajectory.size();
00142
00143
00144 double current_angles[7];
00145 get_current_joint_angles(current_angles);
00146
00147
00148 goal.trajectory.points.resize(trajectorylength+1);
00149
00150
00151 goal.trajectory.points[0].positions.resize(7);
00152 goal.trajectory.points[0].velocities.resize(7);
00153 for(j=0; j<7; j++){
00154 goal.trajectory.points[0].positions[j] = current_angles[j];
00155 goal.trajectory.points[0].velocities[j] = 0.0;
00156 }
00157
00158
00159 goal.trajectory.points[0].time_from_start = ros::Duration(0.25);
00160
00161
00162 double time_from_start = 0.25;
00163 for(i=0; i<trajectorylength; i++){
00164 goal.trajectory.points[i+1].positions.resize(7);
00165 goal.trajectory.points[i+1].velocities.resize(7);
00166
00167
00168
00169 for(j=0; j<7; j++){
00170 goal.trajectory.points[i+1].positions[j] = joint_trajectory[i][j];
00171 goal.trajectory.points[i+1].velocities[j] = 0.0;
00172 }
00173
00174
00175
00176 double max_joint_move = 0;
00177 for(j=0; j<7; j++){
00178 double joint_move = fabs(goal.trajectory.points[i+1].positions[j]
00179 - goal.trajectory.points[i].positions[j]);
00180 if(joint_move > max_joint_move) max_joint_move = joint_move;
00181 }
00182 double seconds = max_joint_move/MAX_JOINT_VEL;
00183 ROS_INFO("max_joint_move: %0.3f, seconds: %0.3f", max_joint_move, seconds);
00184 time_from_start += seconds;
00185 goal.trajectory.points[i+1].time_from_start =
00186 ros::Duration(time_from_start);
00187 }
00188
00189
00190 goal.trajectory.header.stamp = ros::Time::now() + ros::Duration(0.25);
00191
00192 ROS_INFO("Sending goal to joint_trajectory_action");
00193 action_client->sendGoal(goal);
00194
00195 action_client->waitForResult();
00196
00197
00198 get_current_joint_angles(current_angles);
00199 ROS_INFO("joint angles after trajectory: %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f %0.3f\n",current_angles[0],current_angles[1],current_angles[2],current_angles[3],current_angles[4],current_angles[5],current_angles[6]);
00200
00201 if(action_client->getState() == actionlib::SimpleClientGoalState::SUCCEEDED){
00202 ROS_INFO("Hooray, the arm finished the trajectory!");
00203 return 1;
00204 }
00205 ROS_INFO("The arm failed to execute the trajectory.");
00206 return 0;
00207 }
00208
00209
00210
00211 bool execute_cartesian_ik_trajectory(
00212 pr2_laban_gazebo_demo::ExecuteCartesianIKTrajectory::Request &req,
00213 pr2_laban_gazebo_demo::ExecuteCartesianIKTrajectory::Response &res){
00214
00215 int trajectory_length = req.poses.size();
00216 int i, j;
00217
00218
00219 geometry_msgs::PoseStamped stamped_pose;
00220 stamped_pose.header = req.header;
00221 stamped_pose.header.stamp = ros::Time::now();
00222 bool success;
00223 std::vector<double *> joint_trajectory;
00224
00225
00226 double last_angles[7];
00227 get_current_joint_angles(last_angles);
00228
00229
00230
00231 for(i=0; i<trajectory_length; i++){
00232
00233 stamped_pose.pose = req.poses[i];
00234 double *trajectory_point = new double[7];
00235 success = run_ik(stamped_pose, last_angles, trajectory_point, "r_wrist_roll_link");
00236 joint_trajectory.push_back(trajectory_point);
00237
00238 if(!success){
00239 ROS_ERROR("IK solution not found for trajectory point number %d!\n", i);
00240 return 0;
00241 }
00242 for(j=0; j<7; j++) last_angles[j] = trajectory_point[j];
00243 }
00244
00245
00246 ROS_INFO("executing joint trajectory");
00247 success = execute_joint_trajectory(joint_trajectory);
00248 res.success = success;
00249
00250 return success;
00251 }
00252
00253 };
00254
00255
00256 int main(int argc, char** argv){
00257
00258
00259 ros::init(argc, argv, "cartesian_ik_trajectory_executor");
00260
00261 IKTrajectoryExecutor ik_traj_exec = IKTrajectoryExecutor();
00262
00263 ROS_INFO("Waiting for cartesian trajectories to execute");
00264 ros::spin();
00265
00266 return 0;
00267 }
00268