iri_score_map_mix_node.cpp
Go to the documentation of this file.
00001 #include "iri_score_map_mix_node.h"
00002 
00003 ScoreMapMixAlgNode::ScoreMapMixAlgNode(void) :
00004   algorithm_base::IriBaseAlgorithm<ScoreMapMixAlgorithm>()
00005 {
00006   //init class attributes if necessary
00007   //this->loop_rate_ = 2;//in [Hz]
00008     num_score_maps_ = 0;
00009     selection_algorithm_id_ = 0;
00010     weights_.resize(MAXMAPS);
00011     for(int i=0;i<MAXMAPS;i++)
00012       weights_[i] = 0;
00013 
00014   // [init publishers]
00015   this->score_results_publisher_ = this->public_node_handle_.advertise<iri_deformable_analysis::ScoreMapMixResults>("deformable_score_results", 10);
00016   /* Next 3 are just for logging and visualization purposes */
00017   this->grasping_point_pose_publisher_ = this->public_node_handle_.advertise<geometry_msgs::PoseStamped>("grasping_point_pose", 5);
00018   this->algorithm_id_publisher_ = this->public_node_handle_.advertise<std_msgs::UInt32>("score_mix_algorithm_id", 5);
00019   this->score_map_global_publisher_ = this->public_node_handle_.advertise<sensor_msgs::PointCloud2>("score_map_global", 10);
00020 
00021 
00022   // [init subscribers]
00023   this->score_map7_subscriber_ = this->public_node_handle_.subscribe("score_map7", 10, &ScoreMapMixAlgNode::score_map7_callback, this);
00024   this->score_map6_subscriber_ = this->public_node_handle_.subscribe("score_map6", 10, &ScoreMapMixAlgNode::score_map6_callback, this);
00025   this->score_map5_subscriber_ = this->public_node_handle_.subscribe("score_map5", 10, &ScoreMapMixAlgNode::score_map5_callback, this);
00026   this->score_map4_subscriber_ = this->public_node_handle_.subscribe("score_map4", 10, &ScoreMapMixAlgNode::score_map4_callback, this);
00027   this->score_map3_subscriber_ = this->public_node_handle_.subscribe("score_map3", 10, &ScoreMapMixAlgNode::score_map3_callback, this);
00028   this->score_map2_subscriber_ = this->public_node_handle_.subscribe("score_map2", 10, &ScoreMapMixAlgNode::score_map2_callback, this);
00029   this->score_map1_subscriber_ = this->public_node_handle_.subscribe("score_map1", 10, &ScoreMapMixAlgNode::score_map1_callback, this);
00030   this->score_map0_subscriber_ = this->public_node_handle_.subscribe("score_map0", 10, &ScoreMapMixAlgNode::score_map0_callback, this);
00031   
00032   // [init services]
00033   this->algorithm_id_server_ = this->public_node_handle_.advertiseService("set_score_mix_algorithm_id", &ScoreMapMixAlgNode::algorithm_idCallback, this);
00034   
00035   // [init clients]
00036   
00037   // [init action servers]
00038   
00039   // [init action clients]
00040 
00041     ROS_INFO("Starting score_map_mix_node with %d num_score_maps_ and algorithm %d", num_score_maps_, selection_algorithm_id_);
00042 }
00043 
00044 ScoreMapMixAlgNode::~ScoreMapMixAlgNode(void)
00045 {
00046   // [free dynamic memory]
00047 }
00048 
00049 void ScoreMapMixAlgNode::mainNodeThread(void)
00050 {
00051   // [fill msg structures]
00052   //this->PointCloud2_msg_.data = my_var;
00053   //this->PoseStamped_msg_.data = my_var;
00054   alg_.lock(); 
00055   UInt32_msg_.data = selection_algorithm_id_;
00056   //this->grasp_point_description_msg_.data = my_var;
00057   
00058   // [fill srv structure and make request to the server]
00059   
00060   // [fill action structure and make request to the action server]
00061 
00062   // [publish messages]
00063   //score_map_global_publisher_.publish(score_map_global_msg_);
00064   grasping_point_pose_publisher_.publish(best_scored_pose_);
00065   algorithm_id_publisher_.publish(UInt32_msg_);
00066   alg_.unlock(); 
00067 
00068         
00069 }
00070 
00071 /*  [subscriber callbacks] */
00072 void ScoreMapMixAlgNode::score_map7_callback(const sensor_msgs::PointCloud2::ConstPtr& msg) 
00073 { 
00074   ROS_DEBUG("ScoreMapMixAlgNode::score_map7_callback: New Message Received"); 
00075 
00076   if(num_score_maps_ <7){
00077     ROS_WARN("Received pointcloud 7 while I was expecting a max of %d score maps", num_score_maps_);
00078     return;
00079   }
00080 
00081   //use appropiate mutex to shared variables if necessary 
00082   this->alg_.lock(); 
00083   //this->score_map7_mutex_.enter(); 
00084 
00085   //std::cout << msg->data << std::endl; 
00086   pcl::fromROSMsg(*msg, input_score_maps_[7]);
00087 
00088   score_map_ready_[7] = true;
00089 
00090   if(all_clouds_ready())
00091     computeGraspPoints();
00092   
00093   //unlock previously blocked shared variables 
00094   this->alg_.unlock(); 
00095   //this->score_map7_mutex_.exit(); 
00096 }
00097 
00098 void ScoreMapMixAlgNode::score_map6_callback(const sensor_msgs::PointCloud2::ConstPtr& msg) 
00099 { 
00100   ROS_DEBUG("ScoreMapMixAlgNode::score_map6_callback: New Message Received"); 
00101 
00102   if(num_score_maps_ <7){
00103     ROS_WARN("Received pointcloud 6 but expecting a max of %d score maps", num_score_maps_);
00104     return;
00105   }
00106 
00107   this->alg_.lock(); 
00108 
00109   pcl::fromROSMsg(*msg, input_score_maps_[6]);
00110 
00111   score_map_ready_[6] = true;
00112 
00113   if(all_clouds_ready())
00114     computeGraspPoints();
00115 
00116   this->alg_.unlock(); 
00117 }
00118 void ScoreMapMixAlgNode::score_map5_callback(const sensor_msgs::PointCloud2::ConstPtr& msg) 
00119 { 
00120   ROS_DEBUG("ScoreMapMixAlgNode::score_map5_callback: New Message Received"); 
00121 
00122   if(num_score_maps_ <6){
00123     ROS_WARN("Received pointcloud 5 but expecting a max of %d score maps", num_score_maps_);
00124     return;
00125   }
00126 
00127   this->alg_.lock(); 
00128 
00129   pcl::fromROSMsg(*msg, input_score_maps_[5]);
00130 
00131   score_map_ready_[5] = true;
00132 
00133   if(all_clouds_ready())
00134     computeGraspPoints();
00135 
00136   this->alg_.unlock(); 
00137 }
00138 
00139 void ScoreMapMixAlgNode::score_map4_callback(const sensor_msgs::PointCloud2::ConstPtr& msg) 
00140 { 
00141   ROS_DEBUG("ScoreMapMixAlgNode::score_map4_callback: New Message Received"); 
00142 
00143   if(num_score_maps_ <5){
00144     ROS_WARN("Received pointcloud 4 but expecting a max of %d score maps", num_score_maps_);
00145     return;
00146   }
00147 
00148   this->alg_.lock(); 
00149 
00150   pcl::fromROSMsg(*msg, input_score_maps_[4]);
00151 
00152   score_map_ready_[4] = true;
00153 
00154   if(all_clouds_ready())
00155     computeGraspPoints();
00156 
00157   this->alg_.unlock(); 
00158 }
00159 
00160 void ScoreMapMixAlgNode::score_map3_callback(const sensor_msgs::PointCloud2::ConstPtr& msg) 
00161 { 
00162   ROS_DEBUG("ScoreMapMixAlgNode::score_map3_callback: New Message Received"); 
00163 
00164   if(num_score_maps_ <4){
00165     ROS_WARN("Received pointcloud 3 but expecting a max of %d score maps", num_score_maps_);
00166     return;
00167   }
00168 
00169   this->alg_.lock(); 
00170 
00171   pcl::fromROSMsg(*msg, input_score_maps_[3]);
00172 
00173   score_map_ready_[3] = true;
00174 
00175   if(all_clouds_ready())
00176     computeGraspPoints();
00177 
00178   this->alg_.unlock(); 
00179 }
00180 
00181 void ScoreMapMixAlgNode::score_map2_callback(const sensor_msgs::PointCloud2::ConstPtr& msg) 
00182 { 
00183   ROS_DEBUG("ScoreMapMixAlgNode::score_map2_callback: New Message Received"); 
00184 
00185   if(num_score_maps_ <3){
00186     ROS_WARN("Received pointcloud 2 but expecting a max of %d score maps", num_score_maps_);
00187     return;
00188   }
00189 
00190   this->alg_.lock(); 
00191 
00192   pcl::fromROSMsg(*msg, input_score_maps_[2]);
00193 
00194   score_map_ready_[2] = true;
00195 
00196   if(all_clouds_ready())
00197     computeGraspPoints();
00198 
00199   this->alg_.unlock(); 
00200 }
00201 
00202 void ScoreMapMixAlgNode::score_map1_callback(const sensor_msgs::PointCloud2::ConstPtr& msg) 
00203 { 
00204   ROS_DEBUG("ScoreMapMixAlgNode::score_map1_callback: New Message Received"); 
00205   this->alg_.lock(); 
00206 
00207   if(num_score_maps_ <2){
00208     ROS_WARN("Received pointcloud 1 but expecting a max of %d score maps", num_score_maps_);
00209     return;
00210   }
00211 
00212   pcl::fromROSMsg(*msg, input_score_maps_[1]);
00213 
00214   score_map_ready_[1] = true;
00215 
00216   if(all_clouds_ready())
00217     computeGraspPoints();
00218 
00219   this->alg_.unlock(); 
00220 }
00221 
00222 void ScoreMapMixAlgNode::score_map0_callback(const sensor_msgs::PointCloud2::ConstPtr& msg) 
00223 { 
00224   ROS_DEBUG("ScoreMapMixAlgNode::score_map0_callback: New Message Received"); 
00225 
00226   if(num_score_maps_ <1){
00227     ROS_WARN("Received pointcloud 0 but expecting a max of %d score maps", num_score_maps_);
00228     return;
00229   }
00230   this->alg_.lock(); 
00231 
00232   pcl::fromROSMsg(*msg, input_score_maps_[0]);
00233 
00234   score_map_ready_[0] = true;
00235 
00236   if(all_clouds_ready())
00237     computeGraspPoints();
00238 
00239   this->alg_.unlock(); 
00240 }
00241 
00242 /*  [service callbacks] */
00243 bool 
00244 ScoreMapMixAlgNode::algorithm_idCallback(iri_deformable_analysis::SetScoreMixAlgorithmID::Request &req, 
00245                                          iri_deformable_analysis::SetScoreMixAlgorithmID::Response &res)
00246 { 
00247   ROS_INFO("ScoreMapMixAlgNode::algorithm_idCallback: New Request Received!"); 
00248 
00249   //use appropiate mutex to shared variables if necessary 
00250   this->alg_.lock(); 
00251   //this->algorithm_id_mutex_.enter(); 
00252 
00253   selection_algorithm_id_ = req.algorithm_id;
00254   algorithmConfigurationTranslation(req.algorithm_id);
00255 
00256   res.success = true;
00257   //set the parameter server to globally know which algorithm we are using
00258   //public_node_handle_.setParam(public_node_hanle_.getNamespace() + "/info/algorithm_id", selection_algorithm_id_);
00259 
00260   //if(this->alg_.isRunning()) 
00261   //{ 
00262     //ROS_INFO("ScoreMapMixAlgNode::algorithm_idCallback: Processin New Request!"); 
00263     //do operations with req and output on res 
00264     //res.data2 = req.data1 + my_var; 
00265   //} 
00266   //else 
00267   //{ 
00268     //ROS_INFO("ScoreMapMixAlgNode::algorithm_idCallback: ERROR: alg is not on run mode yet."); 
00269   //} 
00270 
00271   //unlock previously blocked shared variables 
00272   this->alg_.unlock(); 
00273   //this->algorithm_id_mutex_.exit(); 
00274 
00275   return true; 
00276 }
00277 
00278 /*  [action callbacks] */
00279 
00280 /*  [action requests] */
00281 
00282 void ScoreMapMixAlgNode::node_config_update(Config &config, uint32_t level)
00283 {
00284   this->alg_.lock();
00285 
00286   ROS_INFO("Reconfiguring");
00287   num_score_maps_ = config.num_score_maps;
00288   if(selection_algorithm_id_ != config.selection_algorithm_id){
00289       algorithmConfigurationTranslation(config.selection_algorithm_id);
00290       selection_algorithm_id_ = config.selection_algorithm_id;
00291   }
00292 
00293   weights_[0] = config.weight_0; 
00294   weights_[1] = config.weight_1; 
00295   weights_[2] = config.weight_2; 
00296   weights_[3] = config.weight_3; 
00297   weights_[4] = config.weight_4; 
00298   weights_[5] = config.weight_5; 
00299   weights_[6] = config.weight_6; 
00300   weights_[7] = config.weight_7; 
00301 
00302   ROS_INFO("Reconfiguring map mix node with %d score maps and algorithm %d", num_score_maps_, selection_algorithm_id_);
00303 
00304     input_score_maps_.resize(num_score_maps_);
00305     score_map_ready_.resize(num_score_maps_);
00306     for(int i = 0; i < num_score_maps_; i++)
00307         score_map_ready_[i] = false;
00308 
00309   this->alg_.unlock();
00310 }
00311 
00312 void ScoreMapMixAlgNode::addNodeDiagnostics(void)
00313 {
00314 }
00315 
00316 bool ScoreMapMixAlgNode::all_clouds_ready(){
00317     //function protected by mutex
00318 
00319     if(num_score_maps_ == 0)
00320         return false;
00321 
00322     for(int i=0; i<num_score_maps_; i++){
00323         if(!score_map_ready_[i]){
00324             ROS_WARN("%d clouds out of %d ready, waiting",i,num_score_maps_);
00325             return false;
00326         }
00327     }
00328 
00329     //reset the new data vector
00330     for(int i=0; i<num_score_maps_; i++)
00331         score_map_ready_[i] = false;
00332 
00333     ROS_INFO("all maps ready");
00334     return true;
00335 
00336 }
00337 
00338 void ScoreMapMixAlgNode::algorithmConfigurationTranslation(int alg_id){
00339     int i;
00340     for(i=0; i<num_score_maps_;i++)
00341         weights_[i] = 0;
00342     switch(alg_id){
00343         case FULL0:
00344             weights_[0] = 1;
00345             break;
00346         case FULL1:
00347             weights_[1] = 1;
00348             break;
00349         case FIFTY01:
00350             weights_[0] = 0.5;
00351             weights_[1] = 0.5;
00352             break;
00353         default:
00354             weights_[0] = 1;
00355             ROS_WARN("Algorithm id undefined");
00356     }
00357 
00358 }
00359 
00360 void ScoreMapMixAlgNode::computeScoreMap(){
00361 
00362     //the only thing not required to copy is the rgb!
00363     copyPointCloud(input_score_maps_[0], output_score_map_);
00364 
00365     pcl::PointCloud<pcl::PointXYZRGB>::iterator pt_iter_xyzrgb = output_score_map_.begin();
00366 
00367     pcl::PointXYZRGB point; 
00368     //TODO check pointcloud sizes and structuredness 
00369     for (unsigned int rr = 0; rr < output_score_map_.height; ++rr) {
00370       for (unsigned int cc = 0; cc < output_score_map_.width; ++cc, ++pt_iter_xyzrgb) {
00371         pt_iter_xyzrgb->rgb = 0; 
00372         for(unsigned int i = 0; i < input_score_maps_.size(); i++) {
00373             if(output_score_map_.height != input_score_maps_[i].height
00374                || output_score_map_.width != input_score_maps_[i].width){
00375                 ROS_ERROR("score map size mismatch. Expected %d %d received %d %d",output_score_map_.height, output_score_map_.width, input_score_maps_[i].height, input_score_maps_[i].width);
00376                 break;
00377             }
00378  
00379             point = input_score_maps_[i].at(cc,rr);
00380             if(!(isnan(point.x) || isnan(point.y) || isnan(point.z))) {
00381                 //TODO is it possible to perform this kind of operation without going point by point?
00382                 pt_iter_xyzrgb->rgb += weights_[i]*point.rgb; 
00383             } else {
00384                 //TODO do something else to know the point does not have xyz coordinates
00385                 pt_iter_xyzrgb->rgb = 0; 
00386             }
00387         }
00388       }
00389     } 
00390 }
00391 
00392 void ScoreMapMixAlgNode::getMax(pcl::PointCloud<pcl::PointXYZRGB> score_map, pcl::PointXYZRGB& grasp_point, int& pcl_row, int& pcl_col, float& max_score, float& min_score){
00393     
00394     pcl::PointCloud<pcl::PointXYZRGB>::iterator pt_iter_xyzrgb = score_map.begin();
00395 
00396     max_score = -std::numeric_limits<float>::infinity();
00397     min_score = std::numeric_limits<float>::infinity();
00398     pcl_row = -1;
00399     pcl_col = -1;
00400     for (unsigned int rr = 0; rr < score_map.height; ++rr) {
00401       for (unsigned int cc = 0; cc < score_map.width; ++cc, ++pt_iter_xyzrgb) {
00402         if(!(isnan(pt_iter_xyzrgb->x) && isnan(pt_iter_xyzrgb->y) && isnan(pt_iter_xyzrgb->z))) {
00403            if(max_score < pt_iter_xyzrgb->rgb){ 
00404                max_score = pt_iter_xyzrgb->rgb; 
00405                grasp_point.x = pt_iter_xyzrgb->x;
00406                grasp_point.y = pt_iter_xyzrgb->y;
00407                grasp_point.z = pt_iter_xyzrgb->z;
00408                grasp_point.rgb = pt_iter_xyzrgb->rgb;
00409                pcl_row = rr;
00410                pcl_col = cc;
00411 //               ROS_INFO("Max at %d %d at position %f %f %f with score %f",pcl_row, pcl_col, grasp_point.x, grasp_point.y, grasp_point.z, grasp_point.rgb);
00412            }
00413            if(min_score > pt_iter_xyzrgb->rgb){ 
00414                min_score = pt_iter_xyzrgb->rgb; 
00415            }
00416         }
00417       }
00418     } 
00419 }
00420 
00421 void ScoreMapMixAlgNode::computeGraspPoints(){
00422 
00423     int pcl_row = -1, pcl_col = -1;
00424     float max_score, min_score;
00425     pcl::PointXYZRGB point;
00426     ROS_INFO("Normalize and compute global score map");
00427     for(int i=0;i<num_score_maps_;i++){
00428         normalizeScoreMap(input_score_maps_[i]);
00429     }
00430     computeScoreMap();
00431     ROS_INFO("Fetching max");
00432     getMax(output_score_map_, point, pcl_row, pcl_col, max_score, min_score);
00433     normalizeScoreMap(output_score_map_, max_score, min_score);
00434 
00435     pcl::toROSMsg(output_score_map_, score_map_global_msg_);
00436     score_map_global_publisher_.publish(score_map_global_msg_);
00437 
00438     if(pcl_row == -1 || pcl_col == -1){
00439         ROS_ERROR("Any suitable point has been found! Aborting.");
00440         //TODO deal with errors
00441         return;
00442     }
00443 
00444     ROS_INFO("Max at %d %d at position %f %f %f with score %f",pcl_row, pcl_col, point.x, point.y, point.z, point.rgb);
00445 
00446     // Build the pose: best_score_pose_ class member si use for visualization
00447     // purposes so it is built first and added to the returning messages.
00448     best_scored_pose_.header = output_score_map_.header;
00449     // Timestamp should be the message building time (now) so overriding
00450     best_scored_pose_.header.stamp = ros::Time::now();
00451 
00452     best_scored_pose_.pose = score_results_.best_scored_pose.pose;
00453     best_scored_pose_.pose.position.x = point.x;
00454     best_scored_pose_.pose.position.y = point.y;
00455     best_scored_pose_.pose.position.z = point.z;
00456     best_scored_pose_.pose.orientation.x = sqrt(2)/2;
00457     best_scored_pose_.pose.orientation.y = sqrt(2)/2;
00458     best_scored_pose_.pose.orientation.z = 0;
00459     best_scored_pose_.pose.orientation.w = 0;
00460 
00461     score_results_.best_scored_pose = best_scored_pose_;
00462 
00463     // Build the point
00464     score_results_.best_scored_point.x = point.x;
00465     score_results_.best_scored_point.y = point.y;
00466     score_results_.best_scored_point.z = point.z;
00467 
00468     score_results_publisher_.publish(score_results_);
00469 }
00470 
00471 void ScoreMapMixAlgNode::normalizeScoreMap(pcl::PointCloud<pcl::PointXYZRGB> score_map, double max_score, double min_score){
00472 
00473     pcl::PointCloud<pcl::PointXYZRGB>::iterator pt_iter_xyzrgb = score_map.begin();
00474 
00475     for (unsigned int rr = 0; rr < output_score_map_.height; ++rr) {
00476       for (unsigned int cc = 0; cc < output_score_map_.width; ++cc, ++pt_iter_xyzrgb) {
00477         if(!(isnan(pt_iter_xyzrgb->x) && isnan(pt_iter_xyzrgb->y) && isnan(pt_iter_xyzrgb->z))) {
00478             if(pt_iter_xyzrgb->rgb > max_score){
00479                 pt_iter_xyzrgb->rgb = max_score;
00480             }else if(pt_iter_xyzrgb->rgb < min_score){
00481                 pt_iter_xyzrgb->rgb = min_score;
00482             }else{
00483                 pt_iter_xyzrgb->rgb = (pt_iter_xyzrgb->rgb - min_score)/(max_score-min_score); 
00484             }
00485         }
00486       }
00487     } 
00488 }
00489 
00490 void ScoreMapMixAlgNode::normalizeScoreMap(const pcl::PointCloud<pcl::PointXYZRGB> score_map){
00491 
00492     int pcl_row = -1, pcl_col = -1;
00493     float max_score, min_score;
00494     pcl::PointXYZRGB point;
00495     getMax(score_map, point, pcl_row, pcl_col, max_score, min_score);
00496     normalizeScoreMap(score_map, max_score, min_score);
00497 
00498 }
00499 
00500 /* main function */
00501 int main(int argc,char *argv[])
00502 {
00503   return algorithm_base::main<ScoreMapMixAlgNode>(argc, argv, "iri_score_map_mix_node");
00504 }


iri_deformable_analysis
Author(s): Pol Monso, Arnau Ramisa, Jose Luis Rivero
autogenerated on Fri Dec 6 2013 21:15:35