icr_server.cpp
Go to the documentation of this file.
00001 #include "../include/icr_server.h"
00002 //#include <sys/time.h>
00003 //#include <time.h>
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); //3 rgb values to specify a color
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"]);//by default, all phalanges are considered in the icr computation
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     //cannot compute ICR if the prototype grasp is not force closure
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     //need to check if the OWS list and the Patch list contained in the grasp are computed
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     //this could possibly done more efficiently with the setSearchZones and setGrasp methods
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     //the conversion to the icr message maybe should go in the computation of the contact regions,
00147     //so its not necessary for icr to be published in order to be saved to a file
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))//convert region i to a point cloud
00161           {
00162             ROS_ERROR("Cannot publish ICR cloud");
00163             lock_.unlock();
00164             return;
00165           }
00166 
00167         icr_cloud+=region_cloud; //concatenate the region clouds to a complete icr_cloud holding all regions
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(); //get the patch centerpoint id
00211         point_ids[j]=pt_id;
00212         //need to check the vertices from the ICR grasp's parent obj whichs associated OWS list and
00213         //Patch list were used to compute the given ICR
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     //changing the active phalange parameters (its not actually checked whether the change was made on an active or inactive phalange) potentially requires changes in the associated OWS and Patch list. Thus, reinitialization is necessary
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     //changing the active phalanges requires changing the number of fingers in a grasp, thus reinitialzation of the prototype grasp is necessary
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()); //make sure there are neighbors for each point in the cloud
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     //Loading a new object requires recomputing the OWS list and the Patch list which is done by creating a new grasp an initializing it
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     //The init function also requires centerpoint ids, here only a set of dummy ids is created so
00363     //that OWS list and Patch list can be computed. The init function actually also computes the GWS
00364     //(should be changed in the icrcpp library). However, since the computation was done with dummy
00365     //centerpoint ids, the gws_computed_ flag is set to false anyway. The actual GWS with proper
00366     //centerpoints will be computed in the getGrasp callback
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_) //do nothing if no object is loaded or the grasp is not initialized
00405       {
00406         lock_.unlock();
00407         return;
00408       }
00409 
00410     tf::poseMsgToTF(grasp.palm_pose,palm_pose_);//memorize the pose of the palm
00411     
00412   
00413     // struct timeval start, end;
00414     // double c_time=0;
00415   
00416     bool all_phl_touching=true; //not used right now
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         //      std::cout<<active_phalanges_[i]<<": "<<phl_touching<<" ";
00429         if(!phl_touching)
00430           all_phl_touching=false;   
00431    
00432         //gettimeofday(&start,0);
00433         centerpoint_ids(i)=findObjectPointId(&contact_position);
00434         // gettimeofday(&end,0);
00435         // c_time += end.tv_sec - start.tv_sec + 0.000001 * (end.tv_usec - start.tv_usec);
00436       }
00437     //std::cout<<"Computation time: "<<c_time<<" s"<<std::endl;  
00438     //  std::cout<<"all ph:"<<all_phl_touching<<std::endl;
00439     pt_grasp_->setCenterPointIds(centerpoint_ids); //this computes the Grasp Wrench Space
00440     gws_computed_=true;
00441 
00442     //EXPERIMENTAL!!!!!!!!!!!!!!!!!!!! just check if its feasible to stop computatin once all fingers are in touch (e.g. for saving icr)
00443     // if(all_phl_touching && (computation_mode_ == MODE_CONTINUOUS))
00444     //   {
00445     //  computation_mode_=MODE_STEP_WISE;   
00446     //  ROS_INFO("All active phalanges are touching - leaving continuous mode and entering step wise mode...");
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     //need to check if the OWS list and the Patch list contained in the grasp are computed
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     //this could possibly done more efficiently with the setSearchZones and setGrasp methods
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     //cannot compute ICR if the prototype grasp is not force closure
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 }//end namespace


icr
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:36:10