tibi_dabo_arm_kinematics_alg_node.cpp
Go to the documentation of this file.
00001 #include "tibi_dabo_arm_kinematics_alg_node.h"
00002 
00003 
00004 TibiDaboArmKinematicsAlgNode::TibiDaboArmKinematicsAlgNode(void) :
00005   algorithm_base::IriBaseAlgorithm<TibiDaboArmKinematicsAlgorithm>()
00006 {
00007   
00008   this->public_node_handle_.getParam("arm_id", arm_id);
00009   
00010   //init class attributes if necessary
00011   if(arm_id=="Left")   arm = new CSegwayArmKinematics(LEFT_ARM);
00012   else if(arm_id=="Right")  arm = new CSegwayArmKinematics(RIGHT_ARM);
00013 
00014   angles.resize(4);
00015   pose.resize(3);
00016   arm_length=1;
00017   
00018   //this->loop_rate_ = 2;//in [Hz]
00019   // [init publishers]
00020   // [init subscribers]
00021   // [init services]
00022   this->GetPositionIK_server_ = this->public_node_handle_.advertiseService("GetPositionIK", &TibiDaboArmKinematicsAlgNode::GetPositionIKCallback, this);
00023   this->GetKinematicSolverInfo_server_ = this->public_node_handle_.advertiseService("GetKinematicSolverInfo", &TibiDaboArmKinematicsAlgNode::GetKinematicSolverInfoCallback, this);
00024   this->GetPositionFK_server_ = this->public_node_handle_.advertiseService("GetPositionFK", &TibiDaboArmKinematicsAlgNode::GetPositionFKCallback, this);
00025   
00026   // [init clients]
00027   // [init action servers]
00028   // [init action clients]
00029 }
00030 
00031 TibiDaboArmKinematicsAlgNode::~TibiDaboArmKinematicsAlgNode(void)
00032 {
00033   // [free dynamic memory]
00034 }
00035 
00036 void TibiDaboArmKinematicsAlgNode::mainNodeThread(void)
00037 {
00038   // [fill msg structures]
00039   
00040   // [fill srv structure and make request to the server]
00041   
00042   // [fill action structure and make request to the action server]
00043 
00044   // [publish messages]
00045 }
00046 
00047 /*  [subscriber callbacks] */
00048 
00049 /*  [service callbacks] */
00050 bool TibiDaboArmKinematicsAlgNode::GetPositionIKCallback(kinematics_msgs::GetPositionIK::Request &req, kinematics_msgs::GetPositionIK::Response &res) 
00051 { 
00052   static int calibration_countdown=5;
00053   //ROS_INFO("TibiDaboArmKinematicsAlgNode::GetPositionIKCallback: New Request Received!"); 
00054 
00055   //Check if theta3 is given
00056   if(req.ik_request.ik_seed_state.joint_state.name[0].empty()) {
00057     ROS_ERROR("ik_request.ik_seed_state.joint_state.name[0] should be 'shoulder_roll', and ik_request.ik_seed_state.joint_state.position[0] must be a valid theta3 seed");
00058     return false;
00059   }
00060   
00061   //Reset arm lenght if user leaves
00062   if(req.ik_request.ik_seed_state.joint_state.velocity[0]==1){
00063     calibration_countdown=5;
00064     arm_length=1;
00065   }
00066  
00067   //Obtain pose
00068   pose[0]=req.ik_request.pose_stamped.pose.position.x;
00069   pose[1]=req.ik_request.pose_stamped.pose.position.y;
00070   pose[2]=req.ik_request.pose_stamped.pose.position.z;
00071   
00072   //Transform pose from neck to shoulder
00073   pose=(*arm).neck_to_shoulder_transform(pose);
00074   
00075   if(!req.ik_request.ik_seed_state.joint_state.velocity[0]==2){ //Not debug mode
00076   //Try to get the arm length (get the maximum length) (only at the beginning)
00077   if(sqrt(pose[0]*pose[0]+pose[1]*pose[1]+pose[2]*pose[2])>arm_length && calibration_countdown >= 0)
00078   {
00079     arm_length=sqrt(pose[0]*pose[0]+pose[1]*pose[1]+pose[2]*pose[2]);
00080     calibration_countdown--;
00081     ROS_WARN_STREAM("CALIBRATING: PLEASE EXTEND ARM  " << calibration_countdown);
00082     sleep(1);
00083   }
00084   
00085   //Escalate to robot's arm 
00086   pose[0]=pose[0]/arm_length*((*arm).D+(*arm).A);
00087   pose[1]=pose[1]/arm_length*((*arm).D+(*arm).A);
00088   pose[2]=pose[2]/arm_length*((*arm).D+(*arm).A);
00089   
00090   }
00091   
00092   ROS_WARN_STREAM("Pose for IK: " << pose[0] << " " << pose[1] << " " << pose[2]);
00093   
00094   //Calculate IK with q3 seed
00095   if(!(*arm).best_ikine(pose, req.ik_request.ik_seed_state.joint_state.position[0], angles)){
00096     ROS_ERROR("IK could not be calculated");
00097     return false;
00098   }
00099   
00100   ROS_WARN_STREAM("IK angles in kinematics_base: " << angles[0]*180/3.14159 << " " << angles[1]*180/3.14159 << " " << angles[2]*180/3.14159 << " " << angles[3]*180/3.14159);
00101   
00102   
00103   //Potentiometer in left and right arms are not same oriented
00104   if(arm_id=="Left"){
00105     angles[0]=-angles[0];
00106   }else if(arm_id=="Right"){
00107     angles[3]=-angles[3];
00108   }
00109   
00110   //Transform kinematics angles to potentiometer angles   
00111   angles[0]=angles[0]+(*arm).theta1_pote_offset;
00112   angles[1]=angles[1]+(*arm).theta2_pote_offset;
00113   angles[2]=angles[2]+(*arm).theta3_pote_offset;
00114   angles[3]=angles[3]+(*arm).theta4_pote_offset;
00115     
00116   //Fill srv
00117   res.solution.joint_state.name.resize(4);
00118   res.solution.joint_state.position.resize(4);
00119   int i;
00120   for(i=0;i<4;i++){
00121     res.solution.joint_state.name[i]=(*arm).joint_name[i];
00122     res.solution.joint_state.position[i]=angles[i];
00123   }
00124   
00125   //use appropiate mutex to shared variables if necessary 
00126   //this->alg_.lock(); 
00127   //this->GetPositionIK_mutex_.enter(); 
00128 
00129   //if(this->alg_.isRunning()) 
00130   //{ 
00131     //ROS_INFO("TibiDaboArmKinematicsAlgNode::GetPositionIKCallback: Processin New Request!"); 
00132     //do operations with req and output on res 
00133     //res.data2 = req.data1 + my_var; 
00134   //} 
00135   //else 
00136   //{ 
00137     //ROS_INFO("TibiDaboArmKinematicsAlgNode::GetPositionIKCallback: ERROR: alg is not on run mode yet."); 
00138   //} 
00139 
00140   //unlock previously blocked shared variables 
00141   //this->alg_.unlock(); 
00142   //this->GetPositionIK_mutex_.exit(); 
00143 
00144   return true; 
00145 }
00146 bool TibiDaboArmKinematicsAlgNode::GetKinematicSolverInfoCallback(kinematics_msgs::GetKinematicSolverInfo::Request &req, kinematics_msgs::GetKinematicSolverInfo::Response &res) 
00147 { 
00148   ROS_INFO("TibiDaboArmKinematicsAlgNode::GetKinematicSolverInfoCallback: New Request Received!"); 
00149     
00150   //Fill srv
00151   
00152   //Joint names
00153   int i;
00154   res.kinematic_solver_info.joint_names.resize(4);
00155   
00156   for(i=0;i<4;i++){  
00157     res.kinematic_solver_info.joint_names[i] = (*arm).joint_name[i];
00158     
00159     res.kinematic_solver_info.limits.resize(4);
00160     res.kinematic_solver_info.limits[i].joint_name=(*arm).joint_name[i];
00161   }
00162   
00163   //Limits
00164   res.kinematic_solver_info.limits.resize(4);
00165   
00166   res.kinematic_solver_info.limits[0].has_position_limits=true;
00167   res.kinematic_solver_info.limits[0].min_position=(*arm).theta1_lower;
00168   res.kinematic_solver_info.limits[0].max_position=(*arm).theta1_upper;
00169   res.kinematic_solver_info.limits[0].has_velocity_limits=false;
00170   res.kinematic_solver_info.limits[0].has_acceleration_limits=false;
00171   
00172   res.kinematic_solver_info.limits[1].has_position_limits=true;
00173   res.kinematic_solver_info.limits[1].min_position=(*arm).theta2_lower;
00174   res.kinematic_solver_info.limits[1].max_position=(*arm).theta2_upper;
00175   res.kinematic_solver_info.limits[1].has_velocity_limits=false;
00176   res.kinematic_solver_info.limits[1].has_acceleration_limits=false;
00177   
00178   res.kinematic_solver_info.limits[2].has_position_limits=true;
00179   res.kinematic_solver_info.limits[2].min_position=(*arm).theta3_lower;
00180   res.kinematic_solver_info.limits[2].max_position=(*arm).theta3_upper;
00181   res.kinematic_solver_info.limits[2].has_velocity_limits=false;
00182   res.kinematic_solver_info.limits[2].has_acceleration_limits=false;
00183   
00184   res.kinematic_solver_info.limits[3].has_position_limits=true;
00185   res.kinematic_solver_info.limits[3].min_position=(*arm).theta4_lower;
00186   res.kinematic_solver_info.limits[3].max_position=(*arm).theta4_upper;
00187   res.kinematic_solver_info.limits[3].has_velocity_limits=false;
00188   res.kinematic_solver_info.limits[3].has_acceleration_limits=false; 
00189   
00190   
00191   ROS_INFO("Sending back Kinematic Info");
00192 
00193   //use appropiate mutex to shared variables if necessary 
00194   //this->alg_.lock(); 
00195   //this->GetKinematicSolverInfo_mutex_.enter(); 
00196 
00197   //if(this->alg_.isRunning()) 
00198   //{ 
00199     //ROS_INFO("TibiDaboArmKinematicsAlgNode::GetKinematicSolverInfoCallback: Processin New Request!"); 
00200     //do operations with req and output on res 
00201     //res.data2 = req.data1 + my_var; 
00202   //} 
00203   //else 
00204   //{ 
00205     //ROS_INFO("TibiDaboArmKinematicsAlgNode::GetKinematicSolverInfoCallback: ERROR: alg is not on run mode yet."); 
00206   //} 
00207 
00208   //unlock previously blocked shared variables 
00209   //this->alg_.unlock(); 
00210   //this->GetKinematicSolverInfo_mutex_.exit(); 
00211 
00212   return true; 
00213 }
00214 bool TibiDaboArmKinematicsAlgNode::GetPositionFKCallback(kinematics_msgs::GetPositionFK::Request &req, kinematics_msgs::GetPositionFK::Response &res) 
00215 { 
00216   
00217   ROS_INFO("TibiDaboArmKinematicsAlgNode::GetPositionFKCallback: New Request Received!"); 
00218   
00219   //For FK, obtain 4 joints associated with their names
00220   int i;
00221   for(i=0;i<4;i++)
00222   {
00223     if(!req.robot_state.joint_state.name[i].compare((*arm).joint_name[0])) angles[0]=req.robot_state.joint_state.position[i];
00224     else if(!req.robot_state.joint_state.name[i].compare((*arm).joint_name[1])) angles[1]=req.robot_state.joint_state.position[i];
00225     else if(!req.robot_state.joint_state.name[i].compare((*arm).joint_name[2])) angles[2]=req.robot_state.joint_state.position[i];
00226     else if(!req.robot_state.joint_state.name[i].compare((*arm).joint_name[3])) angles[3]=req.robot_state.joint_state.position[i];
00227     else {
00228       ROS_INFO("Incorrect joint name. Joint name must be shoulder_pitch, shoulder_yaw, shoulder_roll or elbow");
00229       return false;
00230     }
00231   }
00232     
00233   //Calculate FK
00234   pose=(*arm).fkine(angles);
00235 
00236   //Fill srv
00237   res.pose_stamped.resize(1);
00238   res.pose_stamped[0].pose.position.x=pose[0];
00239   res.pose_stamped[0].pose.position.y=pose[1];
00240   res.pose_stamped[0].pose.position.z=pose[2];
00241   
00242   ROS_INFO("Sending back FK");
00243   
00244   //use appropiate mutex to shared variables if necessary 
00245   //this->alg_.lock(); 
00246   //this->GetPositionFK_mutex_.enter(); 
00247 
00248   //if(this->alg_.isRunning()) 
00249   //{ 
00250     //ROS_INFO("TibiDaboArmKinematicsAlgNode::GetPositionFKCallback: Processin New Request!"); 
00251     //do operations with req and output on res 
00252     //res.data2 = req.data1 + my_var; 
00253   //} 
00254   //else 
00255   //{ 
00256     //ROS_INFO("TibiDaboArmKinematicsAlgNode::GetPositionFKCallback: ERROR: alg is not on run mode yet."); 
00257   //} 
00258 
00259   //unlock previously blocked shared variables 
00260   //this->alg_.unlock(); 
00261   //this->GetPositionFK_mutex_.exit(); 
00262 
00263   return true; 
00264 }
00265 
00266 /*  [action callbacks] */
00267 
00268 /*  [action requests] */
00269 
00270 void TibiDaboArmKinematicsAlgNode::node_config_update(Config &config, uint32_t level)
00271 {
00272   this->alg_.lock();
00273   arm_id=config.arm_id;
00274 
00275   this->alg_.unlock();
00276 }
00277 
00278 void TibiDaboArmKinematicsAlgNode::addNodeDiagnostics(void)
00279 {
00280 }
00281 
00282 /* main function */
00283 int main(int argc,char *argv[])
00284 {
00285   return algorithm_base::main<TibiDaboArmKinematicsAlgNode>(argc, argv, "tibi_dabo_arm_kinematics_alg_node");
00286 }


tibi_dabo_arm_kinematics
Author(s):
autogenerated on Fri Dec 6 2013 21:17:28