00001 // http://www.ros.org/wiki/pr2_controllers/Tutorials/Moving%20the%20arm%20using%20the%20Joint%20Trajectory%20Action 00002 00003 #include <ros/ros.h> 00004 #include <control_msgs/FollowJointTrajectoryAction.h> 00005 #include <actionlib/client/simple_action_client.h> 00006 00007 typedef actionlib::SimpleActionClient< control_msgs::FollowJointTrajectoryAction > TrajClient; 00008 00009 class ShadowTrajectory 00010 { 00011 private: 00012 // Action client for the joint trajectory action 00013 // used to trigger the arm movement action 00014 TrajClient* traj_client_; 00015 00016 public: 00018 ShadowTrajectory() 00019 { 00020 // tell the action client that we want to spin a thread by default 00021 traj_client_ = new TrajClient("r_arm_controller/joint_trajectory_action", true); 00022 00023 // wait for action server to come up 00024 while(!traj_client_->waitForServer(ros::Duration(5.0))){ 00025 ROS_INFO("Waiting for the joint_trajectory_action server"); 00026 } 00027 } 00028 00030 ~ShadowTrajectory() 00031 { 00032 delete traj_client_; 00033 } 00034 00036 void startTrajectory(control_msgs::FollowJointTrajectoryGoal goal) 00037 { 00038 // When to start the trajectory: 1s from now 00039 goal.trajectory.header.stamp = ros::Time::now() + ros::Duration(1.0); 00040 traj_client_->sendGoal(goal); 00041 } 00042 00044 void waitTrajectory() { 00045 while(!getState().isDone() && ros::ok()) { usleep(50000); } 00046 } 00047 00049 00054 control_msgs::FollowJointTrajectoryGoal arm_movement() 00055 { 00056 //our goal variable 00057 control_msgs::FollowJointTrajectoryGoal goal; 00058 // First, the joint names, which apply to all waypoints 00059 goal.trajectory.joint_names.push_back("ShoulderJRotate"); 00060 goal.trajectory.joint_names.push_back("ShoulderJSwing"); 00061 goal.trajectory.joint_names.push_back("ElbowJSwing"); 00062 goal.trajectory.joint_names.push_back("ElbowJRotate"); 00063 goal.trajectory.joint_names.push_back("wrj2"); 00064 goal.trajectory.joint_names.push_back("wrj1"); 00065 00066 // Set number of waypoints in this goal trajectory 00067 goal.trajectory.points.resize(3); 00068 00069 // First trajectory point 00070 // Positions 00071 int ind = 0; 00072 goal.trajectory.points[ind].positions.resize(6); 00073 goal.trajectory.points[ind].positions[0] = 0.0; 00074 goal.trajectory.points[ind].positions[1] = 0.0; 00075 goal.trajectory.points[ind].positions[2] = 1.57; 00076 goal.trajectory.points[ind].positions[3] = -0.78; 00077 goal.trajectory.points[ind].positions[4] = 0.0; 00078 goal.trajectory.points[ind].positions[5] = 0.0; 00079 00080 // Points also have velocities 00081 goal.trajectory.points[ind].velocities.resize(6); 00082 goal.trajectory.points[ind].velocities[0] = 0.0; 00083 goal.trajectory.points[ind].velocities[1] = 0.0; 00084 goal.trajectory.points[ind].velocities[2] = 0.0; 00085 goal.trajectory.points[ind].velocities[3] = 0.0; 00086 goal.trajectory.points[ind].velocities[4] = 0.0; 00087 goal.trajectory.points[ind].velocities[5] = 0.0; 00088 00089 // To be reached 4.0 second after starting along the trajectory 00090 goal.trajectory.points[ind].time_from_start = ros::Duration(10.0); 00091 00092 // 2nd trajectory point 00093 ind += 1; 00094 goal.trajectory.points[ind].positions.resize(6); 00095 goal.trajectory.points[ind].positions[0] = 0.4; 00096 goal.trajectory.points[ind].positions[1] = 0.78; 00097 goal.trajectory.points[ind].positions[2] = 0.78; 00098 goal.trajectory.points[ind].positions[3] = 0.78; 00099 goal.trajectory.points[ind].positions[4] = 0.1; 00100 goal.trajectory.points[ind].positions[5] = 0.1; 00101 00102 // Points also have velocities 00103 goal.trajectory.points[ind].velocities.resize(6); 00104 goal.trajectory.points[ind].velocities[0] = 0.3; 00105 goal.trajectory.points[ind].velocities[1] = 0.0; 00106 goal.trajectory.points[ind].velocities[2] = 0.0; 00107 goal.trajectory.points[ind].velocities[3] = 0.0; 00108 goal.trajectory.points[ind].velocities[4] = 0.0; 00109 goal.trajectory.points[ind].velocities[5] = 0.0; 00110 00111 // To be reached 4.0 second after starting along the trajectory 00112 goal.trajectory.points[ind].time_from_start = ros::Duration(16.0); 00113 // 3rd trajectory point 00114 ind += 1; 00115 goal.trajectory.points[ind].positions.resize(6); 00116 goal.trajectory.points[ind].positions[0] = 0.6; 00117 goal.trajectory.points[ind].positions[1] = 0.48; 00118 goal.trajectory.points[ind].positions[2] = 0.78; 00119 goal.trajectory.points[ind].positions[3] = 0.78; 00120 goal.trajectory.points[ind].positions[4] = 0.1; 00121 goal.trajectory.points[ind].positions[5] = 0.1; 00122 00123 // Points also have velocities 00124 goal.trajectory.points[ind].velocities.resize(6); 00125 goal.trajectory.points[ind].velocities[0] = 0.0; 00126 goal.trajectory.points[ind].velocities[1] = 0.0; 00127 goal.trajectory.points[ind].velocities[2] = 0.0; 00128 goal.trajectory.points[ind].velocities[3] = 0.0; 00129 goal.trajectory.points[ind].velocities[4] = 0.0; 00130 goal.trajectory.points[ind].velocities[5] = 0.0; 00131 00132 // To be reached 4.0 second after starting along the trajectory 00133 goal.trajectory.points[ind].time_from_start = ros::Duration(20.0); 00134 00135 return goal; 00136 } 00137 00139 actionlib::SimpleClientGoalState getState() 00140 { 00141 return traj_client_->getState(); 00142 } 00143 00144 }; 00145 00146 int main(int argc, char** argv) 00147 { 00148 // Init the ROS node 00149 ros::init(argc, argv, "shadow_trajectory_driver"); 00150 00151 ShadowTrajectory sj; 00152 00153 sj.startTrajectory(sj.arm_movement()); 00154 sj.waitTrajectory(); 00155 } 00156 00157 // vim: sw=2:ts=2