uncalibvs_sim_alg_node.cpp
Go to the documentation of this file.
00001 #include "uncalibvs_sim_alg_node.h"
00002 
00003 using namespace KDL;
00004 
00005 Uncalibvs_simAlgNode::Uncalibvs_simAlgNode(void) :
00006   algorithm_base::IriBaseAlgorithm<Uncalibvs_simAlgorithm>(),
00007   activate_(false),
00008   traditional_(false),
00009   random_points_(false),
00010   quadrotor_(true),
00011   output_files_(false),
00012   arm_unina_(false),
00013   arm_catec_(false),
00014   lambda_(0.005),
00015   dist_to_tag_(1.0),
00016   path_("/home/asantamaria/Desktop/joint_velocities.txt"),
00017   lambda_robot_(Eigen::MatrixXf::Zero(9,1)),
00018   Rquad_inertial_(Eigen::MatrixXf::Zero(3,3)){
00019 
00020   this->init_=true; 
00021   this->ini_vars_=true;
00022   //mutex=true;
00023   //init class attributes if necessary
00024   //this->loop_rate_ = 2;//in [Hz]
00025 
00026   // [init publishers]
00027   this->joints_pub_publisher_ = this->public_node_handle_.advertise<sensor_msgs::JointState>("arm_joints_states", 10);
00028   this->output_publisher_ = this->public_node_handle_.advertise<geometry_msgs::Twist>("cmd_vel", 10);
00029 
00030   // [init subscribers]
00031   this->model_state_subscriber_ = this->public_node_handle_.subscribe("model_state", 10, &Uncalibvs_simAlgNode::model_state_callback, this);
00032   this->input_tag_subscriber_ = this->public_node_handle_.subscribe("input_tag", 10, &Uncalibvs_simAlgNode::input_tag_callback, this);
00033  
00034   // [init services]
00035   
00036   // [init clients]
00037   
00038   // [init action servers]
00039   
00040   // [init action clients]
00041 
00042 
00043   if (this->quadrotor_){
00044 
00045     ros::NodeHandle nh;
00046  
00047     std::string tip_name, root_name;
00048     std::string xml_string;
00049     KDL::Tree tree;
00050     
00051     std::string urdf_xml,full_urdf_xml;
00052     nh.param("urdf_xml",urdf_xml,std::string("robot_description"));
00053     nh.searchParam(urdf_xml,full_urdf_xml);
00054        
00055     ROS_DEBUG("Reading xml file from parameter server\n");
00056     if (!nh.getParam(full_urdf_xml, xml_string)){
00057       ROS_ERROR("Could not load the xml from parameter server: %s\n", urdf_xml.c_str());
00058     }
00059     if (!nh.getParam("root_name", root_name)){
00060       ROS_ERROR("No root name found on parameter server");
00061     }
00062     if (!nh.getParam("tip_name", tip_name)){
00063       ROS_ERROR("No tip name found on parameter server");
00064     }
00065     if (!kdl_parser::treeFromString(xml_string, tree)){
00066       ROS_ERROR("Could not initialize tree object");
00067     }
00068     if (!tree.getChain(root_name, tip_name, this->kdl_chain_)){
00069       ROS_ERROR("Could not initialize kdl_chain object");
00070     }
00071   }
00072 }
00073 
00074 Uncalibvs_simAlgNode::~Uncalibvs_simAlgNode(void)
00075 {
00076   // [free dynamic memory]
00077 }
00078 
00079 void Uncalibvs_simAlgNode::mainNodeThread(void)
00080 {
00081   
00082   // [fill msg structures]
00083   //this->JointState_msg_.data = my_var;
00084   //this->Twist_msg_.data = my_var;
00085    
00086   // [fill srv structure and make request to the server]
00087   
00088   // [fill action structure and make request to the action server]
00089 }
00090 
00091 /*  [subscriber callbacks] */
00092 void Uncalibvs_simAlgNode::model_state_callback(const gazebo_msgs::ModelStates::ConstPtr& msg) 
00093 { 
00094   //ROS_INFO("Uncalibvs_simAlgNode::model_state_callback: New Message Received"); 
00095   //use appropiate mutex to shared variables if necessary 
00096   //this->alg_.lock(); 
00097   this->model_state_mutex_.enter(); 
00098   //std::cout << msg->data << std::endl; 
00099   
00100   tf::Transform tf_pose;
00101   double ya,pi,ro;
00102   
00103   for (int s=0; s<int(msg->name.size()); ++s){
00104      if (msg->name[s]=="quadrotor"){
00105      this->twist_quad_=msg->twist[s];
00106      
00107      //Get quadrotor pose to extract body to inertial rotation
00108      tf::poseMsgToTF(msg->pose[s], tf_pose);
00109      tf_pose.getBasis().getRPY(ro,pi,ya);
00110      // euler convention zyx  
00111      this->Rquad_inertial_ = Eigen::AngleAxisf(ro, Eigen::Vector3f::UnitZ()) \
00112          * Eigen::AngleAxisf(pi, Eigen::Vector3f::UnitY()) \
00113          * Eigen::AngleAxisf(ya, Eigen::Vector3f::UnitX());
00114      }
00115    }
00116 
00117   //this->alg_.lock();   
00118   this->model_state_mutex_.exit(); 
00119 }
00120  
00121 void Uncalibvs_simAlgNode::input_tag_callback(const ar_pose::ARMarkers::ConstPtr& msg) 
00122 { 
00123 
00124   //use appropiate mutex to shared variables if necessary 
00125   this->alg_.lock();   
00126   if (ini_vars_)
00127   {
00128     //Quadrotor
00129     if (!this->arm_unina_ && !this->arm_catec_){
00130       this->num_joints_=0;
00131       this->q_=Eigen::MatrixXf::Zero(6+this->num_joints_,1);
00132       this->q_ << 0, 0, 2.5, 0, 0, 0;    
00133     }
00134     //UNINA arm
00135     else if (this->arm_unina_ && !this->arm_catec_){
00136       this->num_joints_=5;
00137       this->JointState_msg_.header.stamp=ros::Time::now();
00138       this->JointState_msg_.header.frame_id="";
00139       this->JointState_msg_.name.resize(this->num_joints_);
00140       this->JointState_msg_.position.resize(this->num_joints_);
00141       this->JointState_msg_.velocity.resize(this->num_joints_);
00142       this->JointState_msg_.effort.resize(this->num_joints_);
00143       this->JointState_msg_.name[0]="quadrotor::arm_g1";
00144       this->JointState_msg_.name[1]="quadrotor::arm_B1";
00145       this->JointState_msg_.name[2]="quadrotor::arm_B2";
00146       this->JointState_msg_.name[3]="quadrotor::arm_B3";
00147       this->JointState_msg_.name[4]="quadrotor::arm_B4";
00148       this->q_=Eigen::MatrixXf::Zero(6+this->num_joints_,1);
00149       //this->q_ << 0, 0, 2.5, 0, 0, 0, 0, 0.2, 1.7, 2, 0;
00150       //this->q_ << 0, 0, 2.5, 0, 0, 0, 0, 0, 0, 0, 0;
00151       this->q_ << 0, 0, 2.5, 0, 0, 0, 0, -0.5, 1.7, 1, 0;
00152     }
00153     //CATEC arm
00154     else if (this->arm_catec_ && !this->arm_unina_){
00155       this->num_joints_=6;
00156       this->JointState_msg_.header.stamp=ros::Time::now();
00157       this->JointState_msg_.header.frame_id="";
00158       this->JointState_msg_.name.resize(this->num_joints_);
00159       this->JointState_msg_.position.resize(this->num_joints_);
00160       this->JointState_msg_.velocity.resize(this->num_joints_);
00161       this->JointState_msg_.effort.resize(this->num_joints_);
00162       this->JointState_msg_.name[0]="quadrotor::arm_shoulder_0";
00163       this->JointState_msg_.name[1]="quadrotor::arm_shoulder_1";
00164       this->JointState_msg_.name[2]="quadrotor::arm_elbow_0";
00165       this->JointState_msg_.name[3]="quadrotor::arm_elbow_1";
00166       this->JointState_msg_.name[4]="quadrotor::arm_wirst_0";
00167       this->JointState_msg_.name[5]="quadrotor::arm_wirst_1";
00168       this->q_=Eigen::MatrixXf::Zero(6+this->num_joints_,1);
00169   //     this->q_ << 0, 0, 2.5, 0, 0, 0, 0, 3.14159/2, 0, 0, 0, 0;
00170       this->q_ << 0, 0, 2.5, 0, 0, 0, 0, 2, -2, 0, 1.5707, 0;
00171     }
00172     else if (this->arm_unina_ && this->arm_catec_){
00173       ROS_ERROR("Two arms detected");
00174     }
00175     ini_vars_=false;
00176   }
00177     
00178   this->Twist_msg_.linear.x=0;
00179   this->Twist_msg_.linear.y=0;
00180   this->Twist_msg_.linear.z=0;
00181   this->Twist_msg_.angular.x=0;
00182   this->Twist_msg_.angular.y=0;
00183   this->Twist_msg_.angular.z=0;
00184   
00185   if (msg->markers.empty()){
00186     
00187     for (int s=0; s<this->num_joints_; ++s){
00188       this->JointState_msg_.position[s]=this->q_(6+s,0);
00189       this->JointState_msg_.velocity[s]=0.0;
00190       this->JointState_msg_.effort[s]=1000;
00191     }    
00192     this->joints_pub_publisher_.publish(this->JointState_msg_); 
00193     this->init_=true;  
00194     this->ini_vars_=true;
00195     ROS_INFO("No tag detected");
00196   }
00197 
00198   else if (!msg->markers.empty()){
00199     //ROS_INFO("Uncalibvs_simAlgNode::input_callback: New Marker Received"); 
00200  
00201     this->t_old_=this->t_;
00202     
00203     // markers check
00204     bool markers_ok=true;
00205     if ((!std::isnan(msg->markers[0].pose.pose.orientation.x) && std::isfinite(msg->markers[0].pose.pose.orientation.x)) || (!std::isnan(msg->markers[1].pose.pose.orientation.x) && std::isfinite(msg->markers[1].pose.pose.orientation.x))){
00206       markers_ok=true;
00207       //ROS_ERROR("Markers OK");
00208     }
00209     else {
00210       markers_ok=false;
00211       //ROS_ERROR("Markers KO");
00212     }
00213         
00214     if (markers_ok) {
00215       if (1<msg->markers.size()) {
00216         //ROS_WARN("Two markers zone");
00217         if (msg->markers[0].pose.pose.position.z<(this->dist_to_tag_+0.24) || (this->fixed_to_id_==1)){
00218           this->pose_ = msg->markers[1].pose.pose;
00219           this->t_ = msg->markers[1].header.stamp;
00220           this->fixed_to_id_=1;
00221           //ROS_INFO("BAR at z distance: %f \n", msg->markers[1].pose.pose.position.z);
00222         }
00223         else if (msg->markers[0].pose.pose.position.z>(this->dist_to_tag_+0.24)){
00224           this->pose_ = msg->markers[0].pose.pose;
00225           this->t_ = msg->markers[0].header.stamp;
00226           this->fixed_to_id_=0;
00227           //ROS_INFO("BASE at z distance: %f \n", msg->markers[0].pose.pose.position.z);          
00228         }
00229       }
00230       else {
00231         this->pose_ = msg->markers.back().pose.pose;
00232         this->t_ = msg->markers.back().header.stamp;
00233         this->fixed_to_id_=msg->markers.back().id;
00234       } 
00235     }    
00236     //reset time that will reset the algorithm integration
00237     if (this->init_){
00238       this->t_old_=this->t_;
00239       this->init_=false;
00240     }
00241     
00242     ros::Duration Ts;
00243     Ts=this->t_-this->t_old_;
00244     
00245     double secs;
00246     secs=Ts.toSec();  
00247 
00248     if (this->activate_ && markers_ok){
00249       //this->input_mutex_.enter();
00250    
00251       // Convert pose from marker////////////////////////////////////////////////
00252       // Convert quaternion to RPY.
00253       tf::Transform tf_pose;
00254       Eigen::Matrix3f R;
00255       double x,y,z,yaw,pitch,roll;
00256     
00257       tf::poseMsgToTF(this->pose_, tf_pose);
00258       tf_pose.getBasis().getRPY(roll,pitch,yaw);
00259   
00260       // euler convention zyx  
00261       R = Eigen::AngleAxisf(roll, Eigen::Vector3f::UnitZ()) \
00262           * Eigen::AngleAxisf(pitch, Eigen::Vector3f::UnitY()) \
00263           * Eigen::AngleAxisf(yaw, Eigen::Vector3f::UnitX());
00264 
00265       x = this->pose_.position.x;
00266       y = this->pose_.position.y;
00267       z = this->pose_.position.z;
00268 
00269       Eigen::Matrix4f cTo(4,4);
00270       cTo=Eigen::Matrix4f::Zero();
00271       if (!std::isnan(R(0,0)))  cTo.block(0,0,3,3)=R;
00272      
00273       cTo.block(0,3,3,1) << x, y, z;
00274       cTo.row(3) << 0, 0, 0, 1;
00275     
00276       // Extract the Non DOF velocities ///////////////////////////////////    
00277       Eigen::MatrixXf V2(2,1);
00278       V2=Eigen::MatrixXf::Zero(2,1);
00279       if (this->quadrotor_ && !std::isnan(this->twist_quad_.angular.x) && !std::isnan(this->twist_quad_.angular.y)){
00280               V2(0,0)=this->twist_quad_.angular.x;
00281         V2(1,0)=this->twist_quad_.angular.y; 
00282         //V2=Eigen::MatrixXf::Zero(2,1);
00283       }
00284       Eigen::MatrixXf Vel_quad(6,1);
00285       Vel_quad=Eigen::MatrixXf::Zero(6,1);
00286       
00287       
00288       double dist_z;
00289       dist_z=this->dist_to_tag_;
00290       double dist;
00291       if (this->fixed_to_id_==0){
00292         dist=msg->markers[0].pose.pose.position.z-0.24;
00293         // ROS_INFO("Anchored to BASE at z distance: %f",dist);
00294         //dist_z=this->dist_to_tag_;
00295       }
00296       else if (this->fixed_to_id_==1){
00297         dist=msg->markers[1].pose.pose.position.z-0.24;
00298         // ROS_INFO("Anchored to BAR at z distance: %f",dist);
00299         //dist_z=this->dist_to_tag_/2;
00300       }
00301 
00302       //ROS_INFO("marker 0: %f",msg->markers[0].pose.pose.position.z);
00303       //ROS_INFO("marker 1: %f",msg->markers[1].pose.pose.position.z);
00304       //ROS_ERROR_STREAM(cTo);
00305       //ROS_ERROR_STREAM(secs);
00306       //ROS_ERROR_STREAM(V2);
00307       //ROS_ERROR_STREAM(Rquad_inertial_);
00308 
00309       uncalib_vs_sim_alg.uncalib_vs_sim(this->traditional_,this->random_points_,this->quadrotor_,this->arm_unina_,this->arm_catec_,this->output_files_,this->path_,this->lambda_,this->lambda_robot_,dist_z,cTo,secs,V2,this->kdl_chain_,this->q_,this->Rquad_inertial_,Vel_quad);
00310       
00311       this->Twist_msg_.linear.x=Vel_quad(0);
00312       this->Twist_msg_.linear.y=Vel_quad(1);
00313       this->Twist_msg_.linear.z=Vel_quad(2);
00314       this->Twist_msg_.angular.x=Vel_quad(3);  
00315       this->Twist_msg_.angular.y=Vel_quad(4);  
00316       this->Twist_msg_.angular.z=Vel_quad(5); 
00317 
00318     }
00319     else {
00320      ROS_INFO("Not active"); 
00321     }
00322   }
00323 
00324   for (int s=0; s<this->num_joints_; ++s){
00325     if (this->arm_unina_){
00326     this->q_(6,0)=-this->q_(6,0);
00327     // this->q_(8,0)=this->q_(8,0)+3.1415;
00328     // this->q_(9,0)=this->q_(9,0)+3.1415;
00329 
00330     }
00331     this->JointState_msg_.position[s]=this->q_(6+s,0);
00332     this->JointState_msg_.velocity[s]=0.0;
00333     this->JointState_msg_.effort[s]=100;
00334   }
00335 
00336   // adding an offset to the thrust to compensate the arm weight
00337   if (this->arm_unina_){
00338     this->Twist_msg_.linear.z= this->Twist_msg_.linear.z + 0.15;
00339   }
00340   else if (this->arm_catec_){
00341     this->Twist_msg_.linear.z= this->Twist_msg_.linear.z + 0;
00342   }
00343   else if (!this->arm_unina_ && !this->arm_catec_){
00344     this->Twist_msg_.linear.z= this->Twist_msg_.linear.z;
00345   }
00346   
00347   // [publish messages] 
00348   this->output_publisher_.publish(this->Twist_msg_);
00349   this->joints_pub_publisher_.publish(this->JointState_msg_); 
00350 
00351   //unlock previously blocked shared variables 
00352   this->alg_.unlock(); 
00353 }
00354 
00355 /*  [service callbacks] */
00356 
00357 /*  [action callbacks] */
00358 
00359 /*  [action requests] */
00360 
00361 
00362 void Uncalibvs_simAlgNode::node_config_update(Config &config, uint32_t level)
00363 {
00364   this->alg_.lock();
00365   this->activate_=config.activate;
00366   this->traditional_=config.traditional;
00367   this->lambda_=config.lambda;
00368   double lambda_quadrotor=config.lambda_quadrotor;
00369   double lambda_arm=config.lambda_arm;
00370   this->dist_to_tag_=config.dist_to_tag;
00371   this->random_points_=config.random_points;
00372   this->quadrotor_=config.quadrotor;
00373   this->output_files_=config.output_files;
00374   this->path_=config.path;
00375   this->arm_unina_=config.arm_unina;
00376   this->arm_catec_=config.arm_catec;
00377   this->alg_.unlock();
00378 
00379   for (int i = 0; i < 4; ++i)
00380   {
00381     this->lambda_robot_(i,0)=lambda_quadrotor;
00382   }
00383   for (int i = 0; i < this->num_joints_; ++i)
00384   {
00385     this->lambda_robot_(4+i,0)=lambda_arm;
00386   }
00387 }
00388 
00389 void Uncalibvs_simAlgNode::addNodeDiagnostics(void)
00390 {
00391 }
00392 
00393 /* main function */
00394 int main(int argc,char *argv[])
00395 {
00396   return algorithm_base::main<Uncalibvs_simAlgNode>(argc, argv, "uncalibvs_sim_alg_node");
00397 }


iri_uncalibvs_sim
Author(s): Àngel Sanatamaria Navarro
autogenerated on Fri Dec 6 2013 21:57:13