00001 #include "iri_score_map_mix_node.h"
00002
00003 ScoreMapMixAlgNode::ScoreMapMixAlgNode(void) :
00004 algorithm_base::IriBaseAlgorithm<ScoreMapMixAlgorithm>()
00005 {
00006
00007
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
00015 this->score_results_publisher_ = this->public_node_handle_.advertise<iri_deformable_analysis::ScoreMapMixResults>("deformable_score_results", 10);
00016
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
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
00033 this->algorithm_id_server_ = this->public_node_handle_.advertiseService("set_score_mix_algorithm_id", &ScoreMapMixAlgNode::algorithm_idCallback, this);
00034
00035
00036
00037
00038
00039
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
00047 }
00048
00049 void ScoreMapMixAlgNode::mainNodeThread(void)
00050 {
00051
00052
00053
00054 alg_.lock();
00055 UInt32_msg_.data = selection_algorithm_id_;
00056
00057
00058
00059
00060
00061
00062
00063
00064 grasping_point_pose_publisher_.publish(best_scored_pose_);
00065 algorithm_id_publisher_.publish(UInt32_msg_);
00066 alg_.unlock();
00067
00068
00069 }
00070
00071
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
00082 this->alg_.lock();
00083
00084
00085
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
00094 this->alg_.unlock();
00095
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
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
00250 this->alg_.lock();
00251
00252
00253 selection_algorithm_id_ = req.algorithm_id;
00254 algorithmConfigurationTranslation(req.algorithm_id);
00255
00256 res.success = true;
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 this->alg_.unlock();
00273
00274
00275 return true;
00276 }
00277
00278
00279
00280
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
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
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
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
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
00382 pt_iter_xyzrgb->rgb += weights_[i]*point.rgb;
00383 } else {
00384
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
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
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
00447
00448 best_scored_pose_.header = output_score_map_.header;
00449
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
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
00501 int main(int argc,char *argv[])
00502 {
00503 return algorithm_base::main<ScoreMapMixAlgNode>(argc, argv, "iri_score_map_mix_node");
00504 }