00001 #include "../include/icr_server.h"
00002
00003
00004 #include <sensor_msgs/PointCloud2.h>
00005 #include <algorithm>
00006 #include <Eigen/Core>
00007 #include "rosbag/bag.h"
00008
00009 namespace ICR
00010 {
00011
00012 IcrServer::IcrServer() : nh_private_("~"), obj_set_(false), pt_grasp_initialized_(false), gws_computed_(false),
00013 sz_computed_(false), icr_computed_(false), computation_mode_(MODE_CONTINUOUS),
00014 qs_(0.5),obj_frame_id_("/default"), icr_msg_(new icr_msgs::ContactRegions)
00015 {
00016 std::string searched_param;
00017
00018 nh_private_.searchParam("icr_database_directory", searched_param);
00019 nh_private_.getParam(searched_param, icr_database_dir_);
00020
00021 if(nh_private_.searchParam("computation_mode", searched_param))
00022 {
00023 nh_private_.getParam(searched_param, computation_mode_);
00024 if(!(computation_mode_== MODE_CONTINUOUS || computation_mode_ == MODE_STEP_WISE))
00025 {
00026 ROS_WARN("%d is an invalid computation mode which has to be either 0 (MODE_CONTINUOUS) or 1 (MODE_STEP_WISE). Using MODE_CONTINUOUS ... ",computation_mode_);
00027 computation_mode_=MODE_CONTINUOUS;
00028 }
00029 }
00030
00031 if (nh_private_.searchParam("phalanges", searched_param))
00032 {
00033 nh_.getParam(searched_param,phalange_config_);
00034 ROS_ASSERT(phalange_config_.getType() == XmlRpc::XmlRpcValue::TypeArray);
00035
00036 for (int32_t i = 0; i < phalange_config_.size(); ++i)
00037 {
00038 ROS_ASSERT(phalange_config_[i]["phl_name"].getType() == XmlRpc::XmlRpcValue::TypeString);
00039 ROS_ASSERT(phalange_config_[i]["force_magnitude"].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00040 ROS_ASSERT(phalange_config_[i]["fc_disc"].getType() == XmlRpc::XmlRpcValue::TypeInt);
00041 ROS_ASSERT(phalange_config_[i]["mu_0"].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00042 ROS_ASSERT(phalange_config_[i]["mu_T"].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00043 ROS_ASSERT(phalange_config_[i]["contact_type"].getType() == XmlRpc::XmlRpcValue::TypeString);
00044 ROS_ASSERT(phalange_config_[i]["model_type"].getType() == XmlRpc::XmlRpcValue::TypeString);
00045 ROS_ASSERT(phalange_config_[i]["rule_type"].getType() == XmlRpc::XmlRpcValue::TypeString);
00046 ROS_ASSERT(phalange_config_[i]["rule_parameter"].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00047 ROS_ASSERT(phalange_config_[i]["filter_patch"].getType() == XmlRpc::XmlRpcValue::TypeBoolean);
00048 ROS_ASSERT(phalange_config_[i]["display_color"].getType() == XmlRpc::XmlRpcValue::TypeArray);
00049
00050 ROS_ASSERT(phalange_config_[i]["display_color"].size()==3);
00051 for (int32_t j = 0; j < phalange_config_[i]["display_color"].size() ;j++)
00052 ROS_ASSERT(phalange_config_[i]["display_color"][j].getType() == XmlRpc::XmlRpcValue::TypeDouble);
00053
00054
00055
00056 active_phalanges_.push_back((std::string)phalange_config_[i]["phl_name"]);
00057 }
00058 }
00059 else
00060 {
00061 ROS_ERROR("The hand phalange configurations are not specified - cannot start the Icr Server");
00062 ROS_BREAK();
00063 }
00064
00065 get_icr_srv_ = nh_.advertiseService("get_icr",&IcrServer::getIcr,this);
00066 compute_sz_srv_ = nh_.advertiseService("compute_search_zones",&IcrServer::triggerSearchZonesCmp,this);
00067 compute_icr_srv_ = nh_.advertiseService("compute_icr",&IcrServer::triggerIcrCmp,this);
00068 toggle_mode_srv_ = nh_.advertiseService("toggle_mode",&IcrServer::toggleMode,this);
00069 save_icr_srv_ = nh_.advertiseService("save_icr",&IcrServer::saveIcr,this);
00070 set_obj_srv_ = nh_.advertiseService("set_object",&IcrServer::setObject,this);
00071 set_qs_srv_ = nh_.advertiseService("set_spherical_q",&IcrServer::setSphericalQuality,this);
00072 set_active_phl_srv_ = nh_.advertiseService("set_active_phalanges",&IcrServer::setActivePhalanges,this);
00073 set_phl_param_srv_ = nh_.advertiseService("set_phalange_parameters",&IcrServer::setPhalangeParameters,this);
00074 ct_pts_sub_ = nh_.subscribe("grasp",1, &IcrServer::graspCallback,this);
00075 icr_cloud_pub_ = nh_.advertise<pcl::PointCloud<pcl::PointXYZRGBNormal> >("icr_cloud",5);
00076 icr_pub_ = nh_.advertise<icr_msgs::ContactRegions>("contact_regions",5);
00077 }
00078
00079 void IcrServer::computeSearchZones()
00080 {
00081 lock_.lock();
00082
00083 sz_computed_=false;
00084
00085 if(!gws_computed_)
00086 {
00087 ROS_DEBUG("Grasp Wrench Space not computed - cannot compute search zones");
00088 lock_.unlock();
00089 return;
00090 }
00091
00092
00093 if(!pt_grasp_->getGWS()->containsOrigin())
00094 {
00095 ROS_DEBUG("Trying to compute search zones, but the GWS is not force closure");
00096 lock_.unlock();
00097 return;
00098 }
00099
00100 sz_.reset(new SearchZones(pt_grasp_));
00101 sz_->computeShiftedSearchZones(qs_);
00102 sz_computed_=true;
00103 lock_.unlock();
00104 }
00105
00106 void IcrServer::computeIcr()
00107 {
00108 lock_.lock();
00109
00110 icr_computed_=false;
00111
00112
00113 if(!pt_grasp_initialized_)
00114 {
00115 ROS_DEBUG("Prototype grasp not initialized - cannot compute ICR");
00116 lock_.unlock();
00117 return;
00118 }
00119
00120 if(!sz_computed_)
00121 {
00122 ROS_DEBUG("Search zones not computed - cannot compute ICR");
00123 lock_.unlock();
00124 return;
00125 }
00126
00127
00128 icr_.reset(new IndependentContactRegions(sz_,pt_grasp_));
00129 icr_->computeICR();
00130
00131 icr_computed_=true;
00132
00133 lock_.unlock();
00134 }
00135
00136 void IcrServer::publish()
00137 {
00138 lock_.lock();
00139 if(!icr_computed_)
00140 {
00141 ROS_DEBUG("ICR not computed - cannot publish");
00142 lock_.unlock();
00143 return;
00144 }
00145
00146
00147
00148
00149 icr_msg_->regions.clear();
00150
00151 pcl::PointCloud<pcl::PointXYZRGBNormal> region_cloud;
00152 pcl::PointCloud<pcl::PointXYZRGBNormal> icr_cloud;
00153 icr_msgs::ContactRegion region_msg;
00154 std::vector<unsigned int> point_ids;
00155
00156 icr_cloud.header.frame_id=obj_frame_id_;
00157 icr_msg_->header.frame_id=obj_frame_id_;
00158 for (unsigned int i=0; i < icr_->getNumContactRegions(); i++)
00159 {
00160 if(!cloudFromContactRegion(i,region_cloud,point_ids))
00161 {
00162 ROS_ERROR("Cannot publish ICR cloud");
00163 lock_.unlock();
00164 return;
00165 }
00166
00167 icr_cloud+=region_cloud;
00168
00169
00170 region_msg.phalange=(std::string)phalange_config_[getPhalangeId(icr_->getGrasp()->getFinger(i)->getName())]["phl_name"];
00171 pcl::toROSMsg(region_cloud,region_msg.points);
00172 region_msg.indices=point_ids;
00173 icr_msg_->regions.push_back(region_msg);
00174
00175 }
00176 icr_msg_->parent_obj=icr_->getGrasp()->getParentObj()->getName();
00177 tf::poseTFToMsg (palm_pose_,icr_msg_->palm_pose);
00178 icr_msg_->header.stamp=ros::Time::now();
00179 icr_cloud.header.stamp=ros::Time::now();
00180
00181 icr_cloud_pub_.publish(icr_cloud);
00182 icr_pub_.publish(*icr_msg_);
00183 lock_.unlock();
00184 }
00185
00186 bool IcrServer::cloudFromContactRegion(unsigned int region_id,pcl::PointCloud<pcl::PointXYZRGBNormal> & cloud, std::vector<unsigned int> & point_ids)
00187 {
00188
00189 if(!icr_computed_)
00190 {
00191 ROS_ERROR("Cannot extract cloud because ICR are not computed");
00192 return false;
00193 }
00194 int phl_id = getPhalangeId(icr_->getGrasp()->getFinger(region_id)->getName());
00195 if(phl_id == -1)
00196 {
00197 ROS_ERROR("Cannot extract color associated with the phalange - cannot convert ContactRegion to pcl::PointCloud");
00198 return false;
00199 }
00200
00201 Eigen::Vector3d color;
00202 for (int32_t j = 0; j < 3 ;j++)
00203 color(j)=(double)phalange_config_[phl_id]["display_color"][j];
00204
00205
00206 cloud.clear();
00207 point_ids.resize(icr_->getContactRegion(region_id)->size());
00208 for(uint j=0; j < icr_->getContactRegion(region_id)->size();j++)
00209 {
00210 uint pt_id = icr_->getContactRegion(region_id)->at(j)->patch_ids_.front();
00211 point_ids[j]=pt_id;
00212
00213
00214 const Eigen::Vector3d* v = icr_->getGrasp()->getParentObj()->getContactPoint(pt_id)->getVertex();
00215 const Eigen::Vector3d* vn = icr_->getGrasp()->getParentObj()->getContactPoint(pt_id)->getVertexNormal();
00216
00217 pcl::PointXYZRGBNormal pt;
00218 pt.x=v->x(); pt.y=v->y();pt.z=v->z();
00219 pt.r=color(0); pt.g=color(1); pt.b=color(2);
00220 pt.normal[0]=vn->x();pt.normal[0]=vn->y();pt.normal[0]=vn->z();
00221 cloud.points.push_back(pt);
00222 }
00223
00224 cloud.header.frame_id = obj_frame_id_;
00225 cloud.width=cloud.points.size();
00226 cloud.height = 1;
00227 cloud.is_dense=true;
00228
00229 return true;
00230 }
00231
00232 bool IcrServer::setPhalangeParameters(icr_msgs::SetPhalangeParameters::Request &req, icr_msgs::SetPhalangeParameters::Response &res)
00233 {
00234 res.success=false;
00235 lock_.lock();
00236
00237 int phl_id =getPhalangeId(req.name);
00238
00239 if(phl_id == -1)
00240 {
00241 ROS_ERROR("Phalange name %s is invalid. Cannot set phalange parameters - valid phalange specifications are:",req.name.c_str());
00242 for(int j=0; j<phalange_config_.size();j++)
00243 ROS_INFO("%s",((std::string)phalange_config_[j]["phl_name"]).c_str());
00244
00245 lock_.unlock();
00246 return res.success;
00247 }
00248
00249 if(req.mu_0 <= 0.0)
00250 {
00251 ROS_ERROR("%f is an invalid friction coefficent. mu_0 has to be bigger than 0",req.mu_0);
00252 lock_.unlock();
00253 return res.success;
00254 }
00255
00256 if(req.fc_disc < 3)
00257 {
00258 ROS_ERROR("%d is an invalid friction cone discretization. fc_disc has to be bigger than 2",req.fc_disc);
00259 lock_.unlock();
00260 return res.success;
00261 }
00262
00263 phalange_config_[phl_id]["mu_0"]=req.mu_0;
00264 phalange_config_[phl_id]["fc_disc"]=req.fc_disc;
00265
00266
00267 if(pt_grasp_initialized_)
00268 initPtGrasp();
00269
00270 lock_.unlock();
00271 res.success=true;
00272 return true;
00273
00274 }
00275
00276 bool IcrServer::setActivePhalanges(icr_msgs::SetActivePhalanges::Request & req, icr_msgs::SetActivePhalanges::Response &res)
00277 {
00278 res.success=false;
00279
00280 if(req.phalanges.size() < 2 )
00281 {
00282 ROS_ERROR("At least two contacting phalanges are necessary for a force closure grasp");
00283 return res.success;
00284 }
00285
00286 lock_.lock();
00287
00288 for(unsigned int i=0;i<req.phalanges.size();i++)
00289 {
00290 int phl_id=getPhalangeId(req.phalanges[i]);
00291
00292 if(phl_id == -1)
00293 {
00294 ROS_ERROR("Cannot set active phalanges - valid phalange specifications are:");
00295 for(int j=0; j<phalange_config_.size();j++)
00296 ROS_INFO("%s",((std::string)phalange_config_[j]["phl_name"]).c_str());
00297
00298 lock_.unlock();
00299 return res.success;
00300 }
00301 }
00302
00303 active_phalanges_.clear();
00304 for(unsigned int i=0; i<req.phalanges.size();i++)
00305 active_phalanges_.push_back(req.phalanges[i]);
00306
00307
00308 if(pt_grasp_initialized_)
00309 initPtGrasp();
00310
00311 lock_.unlock();
00312 res.success=true;
00313
00314 return res.success;
00315 }
00316
00317 bool IcrServer::setObject(icr_msgs::SetObject::Request &req, icr_msgs::SetObject::Response &res)
00318 {
00319 res.success=false;
00320 lock_.lock();
00321
00322 pcl::PointCloud<pcl::PointNormal> obj_cloud;
00323 pcl::fromROSMsg(req.object.points,obj_cloud);
00324
00325 ROS_ASSERT(obj_cloud.size()==req.object.neighbors.size());
00326
00327 obj_.reset(new TargetObject(req.object.name));
00328
00329 IndexList neighbors;
00330 for(unsigned int i=0;i<obj_cloud.size();i++)
00331 {
00332 neighbors.resize(req.object.neighbors[i].indices.size());
00333 std::copy(req.object.neighbors[i].indices.begin(),req.object.neighbors[i].indices.end(),neighbors.begin());
00334 obj_->addContactPoint(ContactPoint(Eigen::Vector3d(obj_cloud[i].x,obj_cloud[i].y,obj_cloud[i].z),Eigen::Vector3d(obj_cloud[i].normal[0],obj_cloud[i].normal[1],obj_cloud[i].normal[2]),neighbors,i));
00335 }
00336
00337 obj_set_=true;
00338
00339
00340 initPtGrasp();
00341
00342 obj_frame_id_=obj_cloud.header.frame_id;
00343
00344 lock_.unlock();
00345 res.success=true;
00346
00347 ROS_INFO("Object %s set in the icr_server ",req.object.name.c_str());
00348 return res.success;
00349 }
00350
00351 void IcrServer::initPtGrasp()
00352 {
00353 if(!obj_set_)
00354 {
00355 ROS_ERROR("No object is loaded - cannot initialize the prototype grasp");
00356 return;
00357 }
00358
00359 FParamList phl_param;
00360 getActivePhalangeParameters(phl_param);
00361
00362
00363
00364
00365
00366
00367 VectorXui dummy_cp_ids(phl_param.size());
00368 dummy_cp_ids.setZero();
00369
00370 pt_grasp_.reset(new Grasp);
00371 pt_grasp_->init(phl_param,obj_,dummy_cp_ids);
00372
00373
00374 pt_grasp_initialized_=true;
00375 gws_computed_=false;
00376
00377 }
00378
00379 bool IcrServer::setSphericalQuality(icr_msgs::SetSphericalQuality::Request &req, icr_msgs::SetSphericalQuality::Response &res)
00380 {
00381 res.success=false;
00382 if(!(req.qs > 0.0) || !(req.qs < 1.0))
00383 {
00384 ROS_ERROR("Qs has to be larger than zero and smaller than one - cannot change Qs");
00385 return res.success;
00386 }
00387
00388 lock_.lock();
00389
00390 qs_=req.qs;
00391 icr_computed_=false;
00392 sz_computed_=false;
00393
00394 lock_.unlock();
00395 res.success=true;
00396 return res.success;
00397 }
00398
00399 void IcrServer::graspCallback(icr_msgs::Grasp const & grasp)
00400 {
00401 lock_.lock();
00402 gws_computed_=false;
00403
00404 if(!obj_set_ || !pt_grasp_initialized_)
00405 {
00406 lock_.unlock();
00407 return;
00408 }
00409
00410 tf::poseMsgToTF(grasp.palm_pose,palm_pose_);
00411
00412
00413
00414
00415
00416 bool all_phl_touching=true;
00417 bool phl_touching;
00418 Eigen::Vector3d contact_position;
00419 VectorXui centerpoint_ids(active_phalanges_.size());
00420 for (int i=0; i<centerpoint_ids.size();i++)
00421 {
00422 if(!cpFromGraspMsg(grasp,active_phalanges_[i],contact_position,phl_touching))
00423 {
00424 ROS_ERROR("Invalid Grasp message - cannot compute the Grasp Wrench Space");
00425 lock_.unlock();
00426 return;
00427 }
00428
00429 if(!phl_touching)
00430 all_phl_touching=false;
00431
00432
00433 centerpoint_ids(i)=findObjectPointId(&contact_position);
00434
00435
00436 }
00437
00438
00439 pt_grasp_->setCenterPointIds(centerpoint_ids);
00440 gws_computed_=true;
00441
00442
00443
00444
00445
00446
00447
00448
00449 lock_.unlock();
00450 }
00451
00452 bool IcrServer::cpFromGraspMsg(icr_msgs::Grasp const & grasp, const std::string & name,Eigen::Vector3d & contact_position,bool & touching)const
00453 {
00454
00455 for(unsigned int i=0; i<grasp.points.size();i++)
00456 if(!strcmp(name.c_str(),grasp.points[i].phalange.c_str()))
00457 {
00458 contact_position(0)=grasp.points[i].position.x;
00459 contact_position(1)=grasp.points[i].position.y;
00460 contact_position(2)=grasp.points[i].position.z;
00461 touching=grasp.points[i].touching;
00462 return true;
00463 }
00464
00465 ROS_ERROR("Could not find contact point corresponding to phalange %s in Grasp message",name.c_str());
00466 return false;
00467 }
00468
00469 void IcrServer::getActivePhalangeParameters(FParamList & phl_param)
00470 {
00471 phl_param.resize(active_phalanges_.size());
00472
00473 FingerParameters f_param;
00474
00475
00476 for(unsigned int i=0; i<active_phalanges_.size();i++)
00477 {
00478 getFingerParameters(active_phalanges_[i],f_param);
00479 phl_param[i]=f_param;
00480 }
00481 }
00482
00483 unsigned int IcrServer::getPhalangeId(std::string const & name)
00484 {
00485 int phl_id= -1;
00486
00487 for(int i=0; i<phalange_config_.size();i++)
00488 if(!strcmp(name.c_str(),((std::string)phalange_config_[i]["phl_name"]).c_str()))
00489 phl_id=i;
00490
00491 if(phl_id == -1)
00492 {
00493 ROS_ERROR("Could not find phalange with name %s",name.c_str());
00494 return phl_id;
00495 }
00496 return phl_id;
00497 }
00498
00499 void IcrServer::getFingerParameters(std::string const & name,FingerParameters & f_param)
00500 {
00501 int phl_id=getPhalangeId(name);
00502 if(phl_id == -1)
00503 return;
00504
00505 f_param.setForce((double)phalange_config_[phl_id]["force_magnitude"]);
00506 f_param.setFriction((double)phalange_config_[phl_id]["mu_0"]);
00507 f_param.setFrictionTorsional((double)phalange_config_[phl_id]["mu_T"]);
00508 f_param.setDiscretization((int)phalange_config_[phl_id]["fc_disc"]);
00509 f_param.setInclusionRuleParameter((double)phalange_config_[phl_id]["rule_parameter"]);
00510 f_param.setInclusionRuleFilterPatch((bool)phalange_config_[phl_id]["filter_patch"]);
00511
00512 std::string string_param;
00513 string_param=(std::string)phalange_config_[phl_id]["phl_name"];
00514 f_param.setName(string_param);
00515 string_param=(std::string)phalange_config_[phl_id]["contact_type"];
00516 f_param.setContactType(string_param);
00517 string_param=(std::string)phalange_config_[phl_id]["model_type"];
00518 f_param.setContactModelType(string_param);
00519 string_param=(std::string)phalange_config_[phl_id]["rule_type"];
00520 f_param.setInclusionRuleType(string_param);
00521 }
00522
00523 uint IcrServer::findObjectPointId(Eigen::Vector3d* point_in) const
00524 {
00525 double min_dist = 1000000;
00526 uint closest_idx_out = 0;
00527 const Eigen::Vector3d* point_on_object;
00528 Eigen::Vector3d pt_tmp;
00529 unsigned int size = obj_->getNumCp();
00530
00531 for (uint i=0; i<size ; ++i) {
00532 point_on_object = obj_->getContactPoint(i)->getVertex();
00533 pt_tmp = *point_in - *point_on_object;
00534 double dist = pt_tmp.norm();
00535 if (dist < min_dist) {
00536 min_dist = dist;
00537 closest_idx_out = i;
00538 }
00539 }
00540 return closest_idx_out;
00541 }
00542
00543 int IcrServer::getComputationMode()
00544 {
00545 int computation_mode;
00546
00547 lock_.lock();
00548 computation_mode=computation_mode_;
00549 lock_.unlock();
00550
00551 return computation_mode;
00552 }
00553
00554 bool IcrServer::saveIcr(icr_msgs::SaveIcr::Request &req, icr_msgs::SaveIcr::Response &res)
00555 {
00556 res.success=false;
00557
00558 if(req.file.empty())
00559 {
00560 ROS_ERROR("Given file name is invalid - cannot save ICR");
00561 return res.success;
00562 }
00563
00564 lock_.lock();
00565 if(!icr_computed_)
00566 {
00567 ROS_ERROR("No ICR computed - cannot save");
00568 lock_.unlock();
00569 return res.success;
00570 }
00571
00572 rosbag::Bag bag(icr_database_dir_+ req.file + ".bag", rosbag::bagmode::Write);
00573 bag.write("contact_regions", icr_msg_->header.stamp, *icr_msg_);
00574
00575 lock_.unlock();
00576 bag.close();
00577 res.success=true;
00578
00579 ROS_INFO("saved ICR to: %s",(icr_database_dir_+ req.file + ".bag").c_str());
00580 return res.success;
00581 }
00582
00583 bool IcrServer::toggleMode(std_srvs::Empty::Request &req, std_srvs::Empty::Response &res)
00584 {
00585 bool success=true;
00586 lock_.lock();
00587
00588 switch (computation_mode_)
00589 {
00590 case MODE_CONTINUOUS :
00591 ROS_INFO("Leaving continuous mode, entering step wise mode...");
00592 computation_mode_=MODE_STEP_WISE;
00593 break;
00594
00595 case MODE_STEP_WISE :
00596 ROS_INFO("Leaving step wise mode, entering continuous mode...");
00597 computation_mode_=MODE_CONTINUOUS;
00598 break;
00599
00600 default :
00601 success = false;
00602 ROS_ERROR("%d is an invalid computation mode - cannot switch mode",computation_mode_);
00603 }
00604
00605 lock_.unlock();
00606 return success;
00607 }
00608
00609 bool IcrServer::triggerIcrCmp(std_srvs::Empty::Request &req, std_srvs::Empty::Response &res)
00610 {
00611 lock_.lock();
00612
00613 if(computation_mode_==MODE_CONTINUOUS)
00614 {
00615 ROS_ERROR("The ICR server runs in continuous mode and must be switched to step wise mode to trigger manual Icr computation");
00616 lock_.unlock();
00617 return false;
00618 }
00619
00620 icr_computed_=false;
00621
00622
00623 if(!pt_grasp_initialized_)
00624 {
00625 ROS_ERROR("Prototype grasp not initialized - cannot compute ICR");
00626 lock_.unlock();
00627 return false;
00628 }
00629
00630 if(!sz_computed_)
00631 {
00632 ROS_ERROR("Search zones not computed - cannot compute ICR");
00633 lock_.unlock();
00634 return false;
00635 }
00636
00637
00638 icr_.reset(new IndependentContactRegions(sz_,pt_grasp_));
00639 icr_->computeICR();
00640
00641 icr_computed_=true;
00642
00643 lock_.unlock();
00644
00645 ROS_INFO("Computed contact regions");
00646 return true;
00647 }
00648
00649 bool IcrServer::triggerSearchZonesCmp(std_srvs::Empty::Request &req, std_srvs::Empty::Response &res)
00650 {
00651 lock_.lock();
00652
00653 if(computation_mode_==MODE_CONTINUOUS)
00654 {
00655 ROS_ERROR("The ICR server runs in continuous mode and must be switched to step wise mode to trigger manual search zone computation");
00656 lock_.unlock();
00657 return false;
00658 }
00659
00660 sz_computed_=false;
00661
00662 if(!gws_computed_)
00663 {
00664 ROS_ERROR("Grasp Wrench Space not computed - cannot compute search zones");
00665 lock_.unlock();
00666 return false;
00667 }
00668
00669
00670 if(!pt_grasp_->getGWS()->containsOrigin())
00671 {
00672 ROS_ERROR("Trying to compute search zones, but the GWS is not force closure");
00673 lock_.unlock();
00674 return false;
00675 }
00676
00677 sz_.reset(new SearchZones(pt_grasp_));
00678 sz_->computeShiftedSearchZones(qs_);
00679 sz_computed_=true;
00680 lock_.unlock();
00681 ROS_INFO("Computed search zones");
00682 return true;
00683 }
00684
00685 bool IcrServer::getIcr(icr_msgs::GetContactRegions::Request &req, icr_msgs::GetContactRegions::Response &res)
00686 {
00687 res.success=false;
00688 lock_.lock();
00689 if(!icr_computed_)
00690 {
00691 ROS_ERROR("ICR are not computed - cannot get ICR");
00692 lock_.unlock();
00693 return res.success;
00694 }
00695 res.contact_regions=(*icr_msg_);
00696 lock_.unlock();
00697
00698 res.success=true;
00699 return res.success;
00700 }
00701
00702 }