darwin_arm_simple_nav_alg_node.cpp
Go to the documentation of this file.
00001 #include "darwin_arm_simple_nav_alg_node.h"
00002 #include "arm_navigation_msgs/convert_messages.h"
00003 
00004 DarwinArmSimpleNavAlgNode::DarwinArmSimpleNavAlgNode(void) :
00005   algorithm_base::IriBaseAlgorithm<DarwinArmSimpleNavAlgorithm>(),
00006   move_arm_aserver_(public_node_handle_, "move_arm"),
00007   move_joints_client_("move_joints", true),
00008   tf_listener(ros::Duration(10.0))
00009 {
00010   //init class attributes if necessary
00011   //this->loop_rate_ = 2;//in [Hz]
00012   this->robot_running=false;
00013   this->joints_moving=false;
00014 
00015   // [init publishers]
00016   
00017   // [init subscribers]
00018   this->joint_state_subscriber_ = this->public_node_handle_.subscribe("joint_state", 100, &DarwinArmSimpleNavAlgNode::joint_state_callback, this);
00019   
00020   // [init services]
00021   
00022   // [init clients]
00023   ik_info_client_ = this->public_node_handle_.serviceClient<kinematics_msgs::GetKinematicSolverInfo>("ik_info");
00024 
00025   get_ik_client_ = this->public_node_handle_.serviceClient<kinematics_msgs::GetPositionIK>("get_ik");
00026   
00027   // [init action servers]
00028   move_arm_aserver_.registerStartCallback(boost::bind(&DarwinArmSimpleNavAlgNode::move_armStartCallback, this, _1)); 
00029   move_arm_aserver_.registerStopCallback(boost::bind(&DarwinArmSimpleNavAlgNode::move_armStopCallback, this)); 
00030   move_arm_aserver_.registerIsFinishedCallback(boost::bind(&DarwinArmSimpleNavAlgNode::move_armIsFinishedCallback, this)); 
00031   move_arm_aserver_.registerHasSucceedCallback(boost::bind(&DarwinArmSimpleNavAlgNode::move_armHasSucceedCallback, this)); 
00032   move_arm_aserver_.registerGetResultCallback(boost::bind(&DarwinArmSimpleNavAlgNode::move_armGetResultCallback, this, _1)); 
00033   move_arm_aserver_.registerGetFeedbackCallback(boost::bind(&DarwinArmSimpleNavAlgNode::move_armGetFeedbackCallback, this, _1)); 
00034   move_arm_aserver_.start();
00035   
00036   // [init action clients]
00037 
00038   // get the default value of the arm_id parameter
00039   this->public_node_handle_.getParam("arm_id",this->arm_id);
00040   if(this->arm_id!="left" && this->arm_id!="right")
00041     ROS_ERROR("Invalid arm identifier (neither left nor right). The node is running but it will not execute any action.");
00042 }
00043 
00044 DarwinArmSimpleNavAlgNode::~DarwinArmSimpleNavAlgNode(void)
00045 {
00046   // [free dynamic memory]
00047 }
00048 
00049 void DarwinArmSimpleNavAlgNode::mainNodeThread(void)
00050 {
00051   // [fill msg structures]
00052   
00053   // [fill srv structure and make request to the server]
00054 
00055   // [publish messages]
00056 }
00057 
00058 /*  [subscriber callbacks] */
00059 void DarwinArmSimpleNavAlgNode::joint_state_callback(const sensor_msgs::JointState::ConstPtr& msg) 
00060 { 
00061   static bool first=true;
00062 
00063   //ROS_INFO("DarwinArmSimpleNavAlgNode::joint_state_callback: New Message Received"); 
00064 
00065   //use appropiate mutex to shared variables if necessary 
00066   //this->alg_.lock(); 
00067   this->joint_state_mutex_.enter(); 
00068 
00069   //std::cout << msg->data << std::endl; 
00070   this->current_state=(*msg);
00071   if(first)
00072   {
00073     this->robot_running=true;
00074     first=false;
00075   }
00076   //unlock previously blocked shared variables 
00077   //this->alg_.unlock(); 
00078   this->joint_state_mutex_.exit(); 
00079 }
00080 
00081 /*  [service callbacks] */
00082 
00083 /*  [action callbacks] */
00084 void DarwinArmSimpleNavAlgNode::move_jointsDone(const actionlib::SimpleClientGoalState& state,  const control_msgs::FollowJointTrajectoryResultConstPtr& result) 
00085 { 
00086   if( state.toString().compare("SUCCEEDED") == 0 ) 
00087     ROS_INFO("DarwinArmSimpleNavAlgNode::move_jointsDone: Goal Achieved!"); 
00088   else 
00089     ROS_INFO("DarwinArmSimpleNavAlgNode::move_jointsDone: %s", state.toString().c_str()); 
00090   this->joints_moving=false;
00091   //copy & work with requested result 
00092 } 
00093 
00094 void DarwinArmSimpleNavAlgNode::move_jointsActive() 
00095 { 
00096   //ROS_INFO("DarwinArmSimpleNavAlgNode::move_jointsActive: Goal just went active!"); 
00097 } 
00098 
00099 void DarwinArmSimpleNavAlgNode::move_jointsFeedback(const control_msgs::FollowJointTrajectoryFeedbackConstPtr& feedback) 
00100 { 
00101   //ROS_INFO("DarwinArmSimpleNavAlgNode::move_jointsFeedback: Got Feedback!"); 
00102 
00103   bool feedback_is_ok = true; 
00104 
00105   //analyze feedback 
00106   //my_var = feedback->var; 
00107 
00108   //if feedback is not what expected, cancel requested goal 
00109   if( !feedback_is_ok ) 
00110   { 
00111     move_joints_client_.cancelGoal(); 
00112     //ROS_INFO("DarwinArmSimpleNavAlgNode::move_jointsFeedback: Cancelling Action!"); 
00113   } 
00114 }
00115 void DarwinArmSimpleNavAlgNode::move_armStartCallback(const arm_navigation_msgs::MoveArmGoalConstPtr& goal)
00116 {
00117   geometry_msgs::PoseStamped local_goal,target_goal;
00118   double time=0.0,max_angle=0.0;
00119   bool tf_exists;
00120   int i=0;
00121 
00122   if(this->robot_running)
00123   {
00124     alg_.lock(); 
00125     // create the target_goal from the input message
00126     target_goal.header=goal->motion_plan_request.goal_constraints.position_constraints[0].header;
00127     target_goal.pose.position=goal->motion_plan_request.goal_constraints.position_constraints[0].position;   
00128     target_goal.pose.orientation=tf::createQuaternionMsgFromYaw(0);    
00129     try{
00130       // transform the target_goal to the local goal in the MP_BODY reference frame
00131       tf_exists = tf_listener.waitForTransform(target_goal.header.frame_id,std::string("MP_BODY"), target_goal.header.stamp,
00132                                                ros::Duration(10),ros::Duration(0.01));
00133       tf_listener.transformPose(std::string("MP_BODY"),target_goal,local_goal);
00134       // chose the arm to move depending on the target postion
00135       if(this->arm_id=="left")
00136       {
00137         this->get_ik_srv_.request.ik_request.ik_link_name="MP_ARM_GRIPPER_FIX_L";
00138         // IK seed, get the current arm position
00139         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.name.resize(4);
00140         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.name[0]="j_shoulder_l";
00141         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.name[1]="j_high_arm_l";
00142         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.name[2]="j_low_arm_l";
00143         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.name[3]="j_wrist_l";
00144         this->joint_state_mutex_.enter();
00145         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position.resize(4);
00146         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position[0]=this->current_state.position[2];
00147         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position[1]=this->current_state.position[4];
00148         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position[2]=this->current_state.position[6];
00149         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position[3]=this->current_state.position[23];
00150         this->joint_state_mutex_.exit();
00151       } 
00152       else if(this->arm_id=="right")
00153       { 
00154         this->get_ik_srv_.request.ik_request.ik_link_name="MP_ARM_GRIPPER_FIX_R";
00155         // IK seed, get the current arm position
00156         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.name.resize(4);
00157         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.name[0]="j_shoulder_r";
00158         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.name[1]="j_high_arm_r";
00159         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.name[2]="j_low_arm_r";
00160         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.name[3]="j_wrist_r";
00161         this->joint_state_mutex_.enter();
00162         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position.resize(4);
00163         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position[0]=this->current_state.position[1];
00164         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position[1]=this->current_state.position[3];
00165         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position[2]=this->current_state.position[5];
00166         this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position[3]=this->current_state.position[21];
00167         this->joint_state_mutex_.exit();
00168       }
00169       // desired pose
00170       this->get_ik_srv_.request.ik_request.pose_stamped=local_goal;
00171       // ignore the rest of the infomation for the moment
00172       if (get_ik_client_.call(get_ik_srv_))
00173       {
00174         ROS_INFO("DarwinArmSimpleNavAlgNode:: Response: %s", arm_navigation_msgs::armNavigationErrorCodeToString(get_ik_srv_.response.error_code).c_str());
00175         if(this->get_ik_srv_.response.error_code.val==this->get_ik_srv_.response.error_code.SUCCESS)// success
00176         {
00177           this->move_joints_goal_.trajectory.header.seq=0;
00178           this->move_joints_goal_.trajectory.header.stamp=ros::Time::now();
00179           this->move_joints_goal_.trajectory.header.frame_id="MP_BODY";
00180           this->move_joints_goal_.trajectory.joint_names=this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.name;
00181           this->move_joints_goal_.trajectory.points.resize(1);
00182           this->move_joints_goal_.trajectory.points[0].positions.resize(4);
00183           this->move_joints_goal_.trajectory.points[0].velocities.resize(4);
00184           this->move_joints_goal_.trajectory.points[0].accelerations.resize(4);
00185           for(i=0;i<4;i++)
00186             if(fabs(this->get_ik_srv_.response.solution.joint_state.position[i]-this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position[i])>max_angle)
00187               max_angle=fabs(this->get_ik_srv_.response.solution.joint_state.position[i]-this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position[i]);
00188           time=max_angle/50.0;
00189           for(i=0;i<4;i++)
00190           {
00191             this->move_joints_goal_.trajectory.points[0].positions[i]=this->get_ik_srv_.response.solution.joint_state.position[i]*180.0/3.141592;
00192             this->move_joints_goal_.trajectory.points[0].velocities[i]=fabs(this->get_ik_srv_.response.solution.joint_state.position[i]-this->get_ik_srv_.request.ik_request.ik_seed_state.joint_state.position[i])/time;
00193             if(this->move_joints_goal_.trajectory.points[0].velocities[i]<5.0)
00194               this->move_joints_goal_.trajectory.points[0].velocities[i]=5.0;
00195             this->move_joints_goal_.trajectory.points[0].accelerations[i]=100.0;
00196           }
00197           this->move_joints_goal_.trajectory.points[0].time_from_start=ros::Duration(time);
00198           // make the request
00199           this->move_jointsMakeActionRequest();
00200         }
00201         else
00202         {
00203           ROS_INFO("DarwinArmSimpleNavAlgNode:: No solution to the inverse kinematics");
00204           this->move_arm_aserver_.setAborted();
00205         }
00206       }
00207       else
00208       {
00209         ROS_INFO("DarwinArmSimpleNavAlgNode:: Failed to Call Server on topic get_ik ");
00210         // cancel the action
00211         this->move_arm_aserver_.setAborted();
00212       }
00213       //execute goal 
00214       alg_.unlock();
00215     }catch(tf::TransformException ex){
00216       ROS_ERROR("NoCollisionAlgNode:: %s",ex.what());
00217       this->move_arm_aserver_.setAborted();
00218       alg_.unlock();
00219     }
00220   }
00221   else
00222   {
00223     ROS_INFO("DarwinArmSimpleNavAlgNode:: Robot is not running");
00224     this->move_arm_aserver_.setAborted();
00225   }
00226 } 
00227 
00228 void DarwinArmSimpleNavAlgNode::move_armStopCallback(void) 
00229 { 
00230   alg_.lock(); 
00231     //stop action 
00232     // cancel the joints motion
00233     this->move_joints_client_.cancelGoal();
00234     this->joints_moving=false;
00235   alg_.unlock(); 
00236 } 
00237 
00238 bool DarwinArmSimpleNavAlgNode::move_armIsFinishedCallback(void) 
00239 { 
00240   bool ret = false; 
00241 
00242   alg_.lock(); 
00243     //if action has finish for any reason 
00244     ret = !this->joints_moving; 
00245   alg_.unlock(); 
00246 
00247   return ret; 
00248 } 
00249 
00250 bool DarwinArmSimpleNavAlgNode::move_armHasSucceedCallback(void) 
00251 { 
00252   bool ret = false; 
00253 
00254   alg_.lock(); 
00255     //if goal was accomplished 
00256     ret = true;
00257   alg_.unlock(); 
00258 
00259   return ret; 
00260 } 
00261 
00262 void DarwinArmSimpleNavAlgNode::move_armGetResultCallback(arm_navigation_msgs::MoveArmResultPtr& result) 
00263 { 
00264   alg_.lock(); 
00265     //update result data to be sent to client 
00266     //result->data = data; 
00267   alg_.unlock(); 
00268 } 
00269 
00270 void DarwinArmSimpleNavAlgNode::move_armGetFeedbackCallback(arm_navigation_msgs::MoveArmFeedbackPtr& feedback) 
00271 { 
00272   alg_.lock(); 
00273     //keep track of feedback 
00274     //ROS_INFO("feedback: %s", feedback->data.c_str()); 
00275   alg_.unlock(); 
00276 }
00277 
00278 /*  [action requests] */
00279 void DarwinArmSimpleNavAlgNode::move_jointsMakeActionRequest() 
00280 { 
00281   ROS_INFO("DarwinArmSimpleNavAlgNode::move_jointsMakeActionRequest: Starting New Request!"); 
00282 
00283   //wait for the action server to start 
00284   //will wait for infinite time 
00285   move_joints_client_.waitForServer();  
00286   ROS_INFO("DarwinArmSimpleNavAlgNode::move_jointsMakeActionRequest: Server is Available!"); 
00287 
00288   //send a goal to the action 
00289   //move_joints_goal_.data = my_desired_goal; 
00290   move_joints_client_.sendGoal(move_joints_goal_, 
00291               boost::bind(&DarwinArmSimpleNavAlgNode::move_jointsDone,     this, _1, _2), 
00292               boost::bind(&DarwinArmSimpleNavAlgNode::move_jointsActive,   this), 
00293               boost::bind(&DarwinArmSimpleNavAlgNode::move_jointsFeedback, this, _1)); 
00294   ROS_INFO("DarwinArmSimpleNavAlgNode::move_jointsMakeActionRequest: Goal Sent. Wait for Result!"); 
00295   this->joints_moving=true;
00296 }
00297 
00298 void DarwinArmSimpleNavAlgNode::node_config_update(Config &config, uint32_t level)
00299 {
00300   this->alg_.lock();
00301 
00302   this->arm_id=config.arm_id;
00303   if(this->arm_id!="left" && this->arm_id!="right")
00304     ROS_ERROR("Invalid arm identifier (neither left nor right). The node is running but it will not execute any action.");
00305 
00306   this->alg_.unlock();
00307 }
00308 
00309 void DarwinArmSimpleNavAlgNode::addNodeDiagnostics(void)
00310 {
00311 }
00312 
00313 /* main function */
00314 int main(int argc,char *argv[])
00315 {
00316   return algorithm_base::main<DarwinArmSimpleNavAlgNode>(argc, argv, "darwin_arm_simple_nav_alg_node");
00317 }


darwin_arm_simple_nav
Author(s): Sergi Hernandez Juan
autogenerated on Fri Dec 6 2013 20:47:43