00001
00063
00064
00065
00066
00067 #include <cob_3d_visualization/shape_marker.h>
00068 #include <cob_3d_visualization/table_marker.h>
00069 #include <cob_3d_visualization/shape_visualization.h>
00070 #include <math.h>
00071 #include <stdlib.h>
00072 #include <vector>
00073
00074
00075 #define PI 3.14159265
00076
00077 using namespace cob_3d_mapping;
00078
00079 ShapeVisualization::ShapeVisualization () :
00080 ctr_for_shape_indexes (0),
00081 nh_("~"),
00082 frame_id_("/map"),
00083 show_contours_(false)
00084 {
00085 shape_array_sub_ = nh_.subscribe ("shape_array", 1, &ShapeVisualization::shapeArrayCallback, this);
00086 feedback_sub_ = nh_.subscribe("shape_i_marker/feedback",1,&ShapeVisualization::setShapePosition,this);
00087
00088 marker_pub_ = nh_.advertise<visualization_msgs::MarkerArray> ("marker_array", 1);
00089
00090
00091 nh_.getParam("show_contours", show_contours_);
00092 im_server_.reset (new interactive_markers::InteractiveMarkerServer ("shape_i_marker", "", false));
00093 moreOptions() ;
00094 }
00095
00096 void ShapeVisualization::setShapePosition(const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback)
00097 {
00098
00099 cob_3d_mapping_msgs::ShapeArray map_msg;
00100 map_msg.header.frame_id = frame_id_;
00101 map_msg.header.stamp = ros::Time::now();
00102
00103 int shape_id,index;
00104 index=-1;
00105 stringstream name(feedback->marker_name);
00106
00107 Eigen::Quaternionf quat;
00108
00109 Eigen::Matrix3f rotationMat;
00110 Eigen::MatrixXf rotationMatInit;
00111
00112 Eigen::Vector3f normalVec;
00113 Eigen::Vector3f normalVecNew;
00114 Eigen::Vector3f newCentroid;
00115 Eigen::Matrix4f transSecondStep;
00116
00117
00118 if (feedback->marker_name != "Text"){
00119 name >> shape_id ;
00120 cob_3d_mapping::Polygon p;
00121
00122 for(unsigned int i=0;i<sha.shapes.size();++i)
00123 {
00124 if (sha.shapes[i].id == shape_id)
00125 {
00126 index = i;
00127 }
00128 }
00129
00130
00131
00132 if(index==-1){
00133 ROS_WARN("shape not in map array");
00134 return;
00135 }
00136
00137 cob_3d_mapping::fromROSMsg (sha.shapes.at(index), p);
00138
00139 if (feedback->event_type == 2 && feedback->menu_entry_id == 5){
00140 quatInit.x() = (float)feedback->pose.orientation.x ;
00141 quatInit.y() = (float)feedback->pose.orientation.y ;
00142 quatInit.z() = (float)feedback->pose.orientation.z ;
00143 quatInit.w() = (float)feedback->pose.orientation.w ;
00144
00145 oldCentroid (0) = (float)feedback->pose.position.x ;
00146 oldCentroid (1) = (float)feedback->pose.position.y ;
00147 oldCentroid (2) = (float)feedback->pose.position.z ;
00148
00149 quatInit.normalize() ;
00150
00151 rotationMatInit = quatInit.toRotationMatrix() ;
00152
00153 transInit.block(0,0,3,3) << rotationMatInit ;
00154 transInit.col(3).head(3) << oldCentroid(0) , oldCentroid(1), oldCentroid(2) ;
00155 transInit.row(3) << 0,0,0,1 ;
00156
00157 transInitInv = transInit.inverse() ;
00158 Eigen::Affine3f affineInitFinal (transInitInv) ;
00159 affineInit = affineInitFinal ;
00160
00161 std::cout << "transInit : " << "\n" << affineInitFinal.matrix() << "\n" ;
00162 }
00163
00164 if (feedback->event_type == 5){
00165
00166
00167
00168
00169 stringstream name(feedback->marker_name);
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 cob_3d_mapping::Polygon p;
00182
00183
00184
00185
00186
00187
00188
00189 std::cout << "index is : " << index << "\n" ;
00190 cob_3d_mapping::fromROSMsg (sha.shapes.at(index), p);
00191
00192 quat.x() = (float)feedback->pose.orientation.x ;
00193 quat.y() = (float)feedback->pose.orientation.y ;
00194 quat.z() = (float)feedback->pose.orientation.z ;
00195 quat.w() = (float)feedback->pose.orientation.w ;
00196
00197 quat.normalize() ;
00198
00199 rotationMat = quat.toRotationMatrix() ;
00200
00201 normalVec << sha.shapes.at(index).params[0],
00202 sha.shapes.at(index).params[1],
00203 sha.shapes.at(index).params[2];
00204
00205 newCentroid << (float)feedback->pose.position.x ,
00206 (float)feedback->pose.position.y ,
00207 (float)feedback->pose.position.z ;
00208
00209
00210 transSecondStep.block(0,0,3,3) << rotationMat ;
00211 transSecondStep.col(3).head(3) << newCentroid(0) , newCentroid(1), newCentroid(2) ;
00212 transSecondStep.row(3) << 0,0,0,1 ;
00213
00214 Eigen::Affine3f affineSecondStep(transSecondStep) ;
00215
00216 std::cout << "transfrom : " << "\n" << affineSecondStep.matrix() << "\n" ;
00217
00218 Eigen::Affine3f affineFinal(affineSecondStep*affineInit) ;
00219 Eigen::Matrix4f matFinal = (transSecondStep*transInitInv) ;
00220
00221 normalVecNew = (matFinal.block(0,0,3,3))* normalVec;
00222
00223
00224 sha.shapes[index].pose = feedback->pose;
00225
00226
00227
00228
00229 sha.shapes.at(index).params[0] = normalVecNew(0) ;
00230 sha.shapes.at(index).params[1] = normalVecNew(1) ;
00231 sha.shapes.at(index).params[2] = normalVecNew(2) ;
00232
00233
00234 std::cout << "transformFinal : " << "\n" << affineFinal.matrix() << "\n" ;
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 modified_shapes_.shapes.push_back(sha.shapes.at(index));
00267 }
00268 }
00269 }
00270
00271 void ShapeVisualization::applyModifications(const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback)
00272 {
00273 cob_3d_mapping_msgs::ModifyMap::Request req ;
00274 cob_3d_mapping_msgs::ModifyMap::Response res;
00275 visualization_msgs::InteractiveMarker imarker;
00276 stringstream aa;
00277 int index ;
00278
00279
00280 if (!modified_shapes_.shapes.empty()){
00281
00282 for(unsigned int i=0;i<modified_shapes_.shapes.size();i++){
00283 req.shapes.shapes.push_back(modified_shapes_.shapes.at(i)) ;
00284
00285 aa.str("");
00286 aa.clear();
00287 aa << "second_marker_" << modified_shapes_.shapes[i].id ;
00288 imarker.name = aa.str() ;
00289 im_server_->erase(imarker.name) ;
00290 im_server_->applyChanges();
00291
00292 }
00293 req.action = cob_3d_mapping_msgs::ModifyMapRequest::MODIFY ;
00294 std ::cout << "size of request: " << req.shapes.shapes.size() << "\n" ;
00295 if (ros::service::call("geometry_map/modify_map",req,res))
00296 {
00297 std::cout << "calling ModifyMap service..." << "\n" ;
00298 }
00299 while (!req.shapes.shapes.empty()){
00300 req.shapes.shapes.pop_back() ;
00301 modified_shapes_.shapes.pop_back() ;
00302 }
00303 }
00304
00305
00306 if (!deleted_markers_indices_.empty()){
00307
00308 std::cout<< "deleted_markers_indices_ size : " << deleted_markers_indices_.size() << "\n" ;
00309
00310 req.action = cob_3d_mapping_msgs::ModifyMapRequest::DELETE ;
00311 for(unsigned int i=0;i<deleted_markers_indices_.size();i++){
00312
00313 aa.str("");
00314 aa.clear();
00315 aa << "deleted_marker_" << deleted_markers_indices_.at(i) ;
00316 imarker.name = aa.str() ;
00317 im_server_->erase(imarker.name) ;
00318 im_server_->applyChanges();
00319
00320 for(unsigned int j=0;j<sha.shapes.size();++j)
00321 {
00322 if (sha.shapes[j].id == deleted_markers_indices_.at(i))
00323 {
00324 index = j;
00325 }
00326 }
00327 req.shapes.shapes.push_back(sha.shapes.at(index)) ;
00328 }
00329
00330 if (ros::service::call("geometry_map/modify_map",req,res))
00331 {
00332 std::cout << "calling ModifyMap service..." << "\n" ;
00333 }
00334
00335 while (!req.shapes.shapes.empty()){
00336 req.shapes.shapes.pop_back() ;
00337 deleted_markers_indices_.pop_back() ;
00338
00339 }
00340 std::cout<< "deleted_markers_indices_ size : " << deleted_markers_indices_.size() << "\n" ;
00341 std::cout << "req size" << req.shapes.shapes.size() << "\n" ;
00342 }
00343 im_server_->applyChanges() ;
00344 }
00345
00346 void ShapeVisualization::resetAll(const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback)
00347 {
00348 stringstream aa;
00349 modified_shapes_.shapes.clear() ;
00350
00351
00352 if(!interacted_shapes_.empty()) {
00353 for (unsigned int i=0; i< interacted_shapes_.size();i++)
00354 {
00355 unsigned int id = interacted_shapes_[i];
00356 for (unsigned int j=0; j<v_sm_.size(); j++)
00357 {
00358 if(id == v_sm_[j]->getID())
00359 v_sm_[j]->resetMarker();
00360
00361 }
00362
00363 }
00364 interacted_shapes_.clear();
00365 }
00366
00367 if(!moved_shapes_indices_.empty()) {
00368 for (unsigned int i=0; i< moved_shapes_indices_.size();i++){
00369
00370 unsigned int id = moved_shapes_indices_[i];
00371 for (unsigned int j=0; j<v_sm_.size(); j++)
00372 {
00373 if(id == v_sm_[j]->getID()){
00374 v_sm_[j]->hideArrows(0);
00375
00376 }
00377 }
00378 }
00379 moved_shapes_indices_.clear() ;
00380 }
00381
00382 if(!deleted_markers_indices_.empty()) {
00383
00384 for (unsigned int i=0; i< deleted_markers_indices_.size();i++){
00385 unsigned int id = deleted_markers_indices_[i];
00386 for (unsigned int j=0; j<v_sm_.size(); j++)
00387 {
00388 if(id == v_sm_[j]->getID()){
00389 v_sm_[j]->setDeleted() ;
00390 aa.str("");
00391 aa.clear() ;
00392 aa << "deleted_marker_"<< id ;
00393 im_server_->erase(aa.str()) ;
00394
00395 v_sm_[j]->createInteractiveMarker();
00396 im_server_->applyChanges ();
00397
00398 }
00399 }
00400 }
00401 deleted_markers_indices_.clear() ;
00402 }
00403
00404 }
00405
00406 void ShapeVisualization::moreOptions()
00407 {
00408 optionMenu();
00409 visualization_msgs::Marker Text;
00410
00411 Text.type = visualization_msgs::Marker::TEXT_VIEW_FACING;
00412 Text.action = visualization_msgs::Marker::ADD;
00413 Text.lifetime = ros::Duration ();
00414 Text.header.frame_id = frame_id_;
00415
00416 Text.id = 0;
00417 Text.ns = "text";
00418
00419 Text.text = "Click here for more options" ;
00420
00421 Text.scale.x = 0.3;
00422 Text.scale.y = 0.3;
00423 Text.scale.z = 0.3;
00424
00425
00426 Text.pose.position.x = 0;
00427 Text.pose.position.y = 0;
00428 Text.pose.position.z = 0.5;
00429
00430 Text.pose.orientation.x = 0;
00431 Text.pose.orientation.y = 0;
00432 Text.pose.orientation.z = 0;
00433 Text.pose.orientation.w = 1;
00434
00435
00436
00437 Text.color.r = 1;
00438 Text.color.g = 1;
00439 Text.color.b = 1;
00440 Text.color.a = 1;
00441
00442
00443
00444 visualization_msgs::InteractiveMarker imarkerText;
00445 visualization_msgs::InteractiveMarkerControl im_ctrl_text_ ;
00446 im_ctrl_text_.always_visible = true ;
00447 im_ctrl_text_.interaction_mode = visualization_msgs::InteractiveMarkerControl::BUTTON;
00448 imarkerText.name = "Text" ;
00449 imarkerText.header = Text.header ;
00450 im_ctrl_text_.markers.push_back(Text);
00451 imarkerText.controls.push_back(im_ctrl_text_);
00452
00453 im_server_->insert (imarkerText);
00454 menu_handler_for_text_.apply (*im_server_,imarkerText.name);
00455
00456 }
00457
00458 void ShapeVisualization::displayAllNormals(const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback) {
00459
00460 interactive_markers::MenuHandler::CheckState check_state;
00461
00462 menu_handler_for_text_.getCheckState (feedback->menu_entry_id, check_state);
00463 if (check_state == interactive_markers::MenuHandler::UNCHECKED)
00464 {
00465 ROS_INFO ("Displaying all Normals...");
00466 menu_handler_for_text_.setCheckState (feedback->menu_entry_id, interactive_markers::MenuHandler::CHECKED);
00467
00468 for (unsigned int j=0; j<v_sm_.size(); j++)
00469 {
00470 v_sm_[j]->displayNormal();
00471 }
00472 }
00473 else if (check_state == interactive_markers::MenuHandler::CHECKED)
00474 {
00475 menu_handler_for_text_.setCheckState (feedback->menu_entry_id, interactive_markers::MenuHandler::UNCHECKED);
00476 ROS_INFO ("Deleting all Normals...");
00477 for (unsigned int j=0; j<v_sm_.size(); j++)
00478 {
00479 v_sm_[j]->hideNormal(0);
00480 }
00481 }
00482 menu_handler_for_text_.reApply (*im_server_);
00483 im_server_->applyChanges ();
00484 }
00485
00486 void
00487 ShapeVisualization::displayAllCentroids (const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback)
00488 {
00489
00490 interactive_markers::MenuHandler::CheckState check_state;
00491 menu_handler_for_text_.getCheckState (feedback->menu_entry_id, check_state);
00492
00493 if (check_state == interactive_markers::MenuHandler::UNCHECKED)
00494 {
00495 menu_handler_for_text_.setCheckState (feedback->menu_entry_id, interactive_markers::MenuHandler::CHECKED);
00496 for (unsigned int j=0; j<v_sm_.size(); j++)
00497 {
00498 v_sm_[j]->displayCentroid();
00499 }
00500 }
00501 else if (check_state == interactive_markers::MenuHandler::CHECKED)
00502 {
00503 menu_handler_for_text_.setCheckState (feedback->menu_entry_id, interactive_markers::MenuHandler::UNCHECKED);
00504 for (unsigned int i=0; i< sha.shapes.size();i++)
00505 {
00506
00507 for (unsigned int j=0; j<v_sm_.size(); j++)
00508 {
00509 v_sm_[j]->hideCentroid(0);
00510 }
00511 }
00512 }
00513 menu_handler_for_text_.reApply (*im_server_);
00514 im_server_->applyChanges ();
00515 }
00516
00517 void
00518 ShapeVisualization::displayAllContours (const visualization_msgs::InteractiveMarkerFeedbackConstPtr& feedback){
00519
00520 interactive_markers::MenuHandler::CheckState check_state;
00521 menu_handler_for_text_.getCheckState (feedback->menu_entry_id, check_state);
00522
00523 if (check_state == interactive_markers::MenuHandler::UNCHECKED)
00524 {
00525 menu_handler_for_text_.setCheckState (feedback->menu_entry_id, interactive_markers::MenuHandler::CHECKED);
00526 for (unsigned int j=0; j<v_sm_.size(); j++)
00527 {
00528 v_sm_[j]->displayContour();
00529 }
00530 }
00531 else if (check_state == interactive_markers::MenuHandler::CHECKED)
00532 {
00533 menu_handler_for_text_.setCheckState (feedback->menu_entry_id, interactive_markers::MenuHandler::UNCHECKED);
00534 for (unsigned int i=0; i< sha.shapes.size();i++)
00535 {
00536
00537 for (unsigned int j=0; j<v_sm_.size(); j++)
00538 {
00539 v_sm_[j]->hideContour(0);
00540 }
00541 }
00542 }
00543 menu_handler_for_text_.reApply (*im_server_);
00544 im_server_->applyChanges ();
00545 }
00546
00547 void ShapeVisualization::optionMenu() {
00548
00549
00550
00551 interactive_markers::MenuHandler::EntryHandle eh_1, eh_2 , eh_3 ,eh_4 ,eh_5, eh_6;
00552
00553 eh_1 = menu_handler_for_text_.insert ("Menu");
00554 eh_2 = menu_handler_for_text_.insert (eh_1, "All Normals",boost::bind (&ShapeVisualization::displayAllNormals, this, _1));
00555 eh_3 = menu_handler_for_text_.insert (eh_1, "All Centroids",boost::bind (&ShapeVisualization::displayAllCentroids, this, _1));
00556 eh_4 = menu_handler_for_text_.insert (eh_1, "All Contours",boost::bind (&ShapeVisualization::displayAllContours, this, _1));
00557 eh_5 = menu_handler_for_text_.insert (eh_1, "Apply map modifications",boost::bind (&ShapeVisualization::applyModifications, this, _1));
00558 eh_6 = menu_handler_for_text_.insert (eh_1, "Reset all Controls",boost::bind (&ShapeVisualization::resetAll, this, _1));
00559
00560 menu_handler_for_text_.setVisible (eh_1, true);
00561 menu_handler_for_text_.setCheckState (eh_1, interactive_markers::MenuHandler::NO_CHECKBOX);
00562 menu_handler_for_text_.setVisible (eh_2, true);
00563 menu_handler_for_text_.setCheckState (eh_2, interactive_markers::MenuHandler::UNCHECKED);
00564 menu_handler_for_text_.setVisible (eh_3, true);
00565 menu_handler_for_text_.setCheckState (eh_3, interactive_markers::MenuHandler::UNCHECKED);
00566 menu_handler_for_text_.setVisible (eh_4, true);
00567 menu_handler_for_text_.setCheckState (eh_4, interactive_markers::MenuHandler::UNCHECKED);
00568 menu_handler_for_text_.setVisible (eh_5, true);
00569 menu_handler_for_text_.setCheckState (eh_5, interactive_markers::MenuHandler::NO_CHECKBOX);
00570 menu_handler_for_text_.setVisible (eh_6, true);
00571 menu_handler_for_text_.setCheckState (eh_6, interactive_markers::MenuHandler::NO_CHECKBOX);
00572
00573
00574 }
00575
00576 void
00577 ShapeVisualization::shapeArrayCallback (const cob_3d_mapping_msgs::ShapeArrayPtr& sa)
00578 {
00579 if(show_contours_)
00580 {
00581 visualization_msgs::MarkerArray dContourMarker;
00582 for( unsigned int i=0; i<contour_ids_.size(); i++)
00583 {
00584 visualization_msgs::Marker marker;
00585 marker.id = contour_ids_[i];
00586 marker.header = sa->header;
00587 marker.ns = "contours";
00588 marker.action = visualization_msgs::Marker::DELETE;
00589 dContourMarker.markers.push_back(marker);
00590 ROS_DEBUG("Deleting contour marker %d", marker.id);
00591 }
00592 contour_ids_.clear();
00593 marker_pub_.publish(dContourMarker);
00594 }
00595
00596 std::vector<unsigned int> new_ids;
00597 v_sm_.clear();
00598 sha.shapes.clear() ;
00599 im_server_->applyChanges();
00600 ROS_INFO("shape array with %d shapes received", sa->shapes.size());
00601 frame_id_ = sa->header.frame_id;
00602 visualization_msgs::MarkerArray ma;
00603
00604 for (unsigned int i = 0; i < sa->shapes.size (); i++)
00605 {
00606 sha.shapes.push_back(sa->shapes[i]);
00607 sha.shapes[i].id = sa->shapes[i].id;
00608 sa->shapes[i].header = sa->header;
00609
00610
00611 boost::shared_ptr<ShapeMarker> sm(new ShapeMarker(im_server_, sa->shapes[i],moved_shapes_indices_
00612 ,interacted_shapes_,deleted_markers_indices_,false,false)) ;
00613
00614 v_sm_.push_back(sm);
00615 new_ids.push_back(sa->shapes[i].id);
00616
00617 if(sm->getMarker().points.size())
00618 ma.markers.push_back(sm->getMarker());
00619 if(show_contours_)
00620 {
00621 visualization_msgs::MarkerArray contourMarker = sm->getContourMarker();
00622 for( unsigned int j=0; j<contourMarker.markers.size(); j++)
00623 contour_ids_.push_back(contourMarker.markers[j].id);
00624 marker_pub_.publish(sm->getContourMarker());
00625 }
00626 }
00627
00628 for( unsigned int i=0; i<marker_ids_.size(); i++)
00629 {
00630 bool found = false;
00631 for( unsigned int j=0; j<new_ids.size(); j++)
00632 {
00633 if( marker_ids_[i] == new_ids[j])
00634 {
00635 found = true;
00636 break;
00637 }
00638 }
00639 if (!found)
00640 {
00641 visualization_msgs::Marker marker;
00642 marker.id = marker_ids_[i];
00643 marker.header = sa->header;
00644 marker.ns = "shape visualization";
00645 marker.action = visualization_msgs::Marker::DELETE;
00646 ma.markers.push_back(marker);
00647 ROS_INFO("Deleting marker %d", marker.id);
00648 }
00649 }
00650
00651 marker_pub_.publish(ma);
00652 marker_ids_.swap(new_ids);
00653 }
00654
00655 int
00656 main (int argc, char** argv)
00657 {
00658 ros::init (argc, argv, "shape_visualization");
00659 ROS_INFO("shape_visualization node started....");
00660 ShapeVisualization sv;
00661
00662 ros::spin();
00663 }