00001 #include "../include/model_server.h"
00002 #include <gazebo_msgs/SpawnModel.h>
00003 #include <gazebo_msgs/DeleteModel.h>
00004 #include <gazebo_msgs/GetWorldProperties.h>
00005 #include <urdf_interface/link.h>
00006 #include <urdf/model.h>
00007 #include <std_srvs/Empty.h>
00008 #include <iostream>
00009 #include <fstream>
00010 #include <pcl/ros/conversions.h>
00011 #include <Eigen/Core>
00012 #include <algorithm>
00013 #include <icr_msgs/SetObject.h>
00014
00015 namespace ICR
00016 {
00017 ModelServer::ModelServer() : nh_private_("~"),pose_brc_(new PoseBroadcaster),obj_(new icr_msgs::Object),scale_(1.0),obj_loaded_(false)
00018 {
00019 std::string searched_param;
00020 std::string gazebo_prefix;
00021
00022 nh_private_.searchParam("pose_source", searched_param);
00023 nh_private_.getParam(searched_param, pose_source_);
00024
00025 nh_private_.searchParam("model_directory", searched_param);
00026 nh_private_.getParam(searched_param, model_dir_);
00027
00028 nh_private_.searchParam("gazebo_prefix", searched_param);
00029 nh_private_.getParam(searched_param, gazebo_prefix);
00030
00031 nh_private_.searchParam("object_scale", searched_param);
00032 nh_private_.getParam(searched_param, scale_);
00033
00034
00035 XmlRpc::XmlRpcValue obj_client_topics;
00036 if (nh_private_.searchParam("obj_client_topics", searched_param))
00037 {
00038 nh_.getParam(searched_param,obj_client_topics);
00039 ROS_ASSERT(obj_client_topics.getType() == XmlRpc::XmlRpcValue::TypeArray);
00040
00041 for (int32_t i = 0; i < obj_client_topics.size(); ++i)
00042 {
00043 ROS_ASSERT(obj_client_topics[i].getType() == XmlRpc::XmlRpcValue::TypeString);
00044
00045
00046 boost::shared_ptr<ros::ServiceClient> obj_client(new ros::ServiceClient( nh_.serviceClient<icr_msgs::SetObject>((std::string)obj_client_topics[i])));
00047 set_obj_clts_.push_back(obj_client);
00048 }
00049 }
00050
00051 gazebo_spawn_clt_ = nh_.serviceClient<gazebo_msgs::SpawnModel>(gazebo_prefix + "/spawn_urdf_model");
00052 gazebo_delete_clt_ = nh_.serviceClient<gazebo_msgs::DeleteModel>(gazebo_prefix + "/delete_model");
00053 gazebo_get_wp_clt_ = nh_.serviceClient<gazebo_msgs::GetWorldProperties>(gazebo_prefix + "/get_world_properties");
00054 gazebo_pause_clt_ = nh_.serviceClient<std_srvs::Empty>(gazebo_prefix + "/pause_physics");
00055 gazebo_unpause_clt_ = nh_.serviceClient<std_srvs::Empty>(gazebo_prefix + "/unpause_physics");
00056
00057
00058 if(!strcmp(pose_source_.c_str(),"gazebo"))
00059 {
00060 gazebo_delete_clt_.waitForExistence();
00061 gazebo_get_wp_clt_.waitForExistence();
00062 gazebo_pause_clt_.waitForExistence();
00063 gazebo_unpause_clt_.waitForExistence();
00064 gazebo_spawn_clt_.waitForExistence();
00065 }
00066
00067 for(unsigned int i=0;i<set_obj_clts_.size();i++)
00068 set_obj_clts_[i]->waitForExistence();
00069
00070 load_obj_srv_ = nh_.advertiseService("load_object",&ModelServer::loadObject,this);
00071 }
00072
00073 bool ModelServer::loadObject(icr_msgs::LoadObject::Request &req, icr_msgs::LoadObject::Response &res)
00074 {
00075 res.success=false;
00076
00077 lock_.lock();
00078 obj_loaded_=false;
00079
00080
00081 if(!strcmp(pose_source_.c_str(),"gazebo"))
00082 if(!gazeboDeleteModel(obj_name_))
00083 {
00084 lock_.unlock();
00085 return res.success;
00086 }
00087
00088
00089
00090
00091 if(!strcmp(pose_source_.c_str(),"gazebo"))
00092 if(!gazeboDeleteModel(req.file))
00093 {
00094 lock_.unlock();
00095 return res.success;
00096 }
00097
00098
00099 std::string serialized_model;
00100 if(!loadURDF(model_dir_+"/urdf/"+req.file+".urdf",serialized_model))
00101 {
00102 lock_.unlock();
00103 return res.success;
00104 }
00105
00106
00107 if(!strcmp(pose_source_.c_str(),"gazebo"))
00108 if(!gazeboSpawnModel(serialized_model,req.initial_pose))
00109 {
00110 lock_.unlock();
00111 return res.success;
00112 }
00113
00114
00115 pcl::PointCloud<pcl::PointNormal> obj_cloud;
00116 std::vector<std::vector<unsigned int> > neighbors;
00117 if(!loadWavefrontObj(model_dir_+"/obj/"+req.file+".obj",obj_cloud,neighbors))
00118 {
00119 lock_.unlock();
00120 return res.success;
00121 }
00122
00123
00124 pose_brc_->setObject(obj_cloud,obj_name_);
00125
00126
00127 if(pose_brc_->isPoseSourceUC3M() == true)
00128 {
00129 if (!pose_brc_->getPoseUC3MObjtrack()) {
00130 ROS_WARN("uc3m_objtracker failed.");
00131 }
00132 }
00133
00134
00135 obj_->name=obj_name_;
00136 pcl::toROSMsg(obj_cloud,obj_->points);
00137 icr_msgs::Neighbors ngb;
00138
00139 obj_->neighbors.clear();
00140 for(unsigned int i=0;i<neighbors.size();i++)
00141 {
00142 ngb.indices.resize(neighbors[i].size());
00143 std::copy(neighbors[i].begin(),neighbors[i].end(),ngb.indices.begin());
00144 obj_->neighbors.push_back(ngb);
00145 }
00146
00147 obj_loaded_=true;
00148 res.success=true;
00149
00150
00151 icr_msgs::SetObject set_obj;
00152 set_obj.request.object=(*obj_);
00153 for(unsigned int i=0; i<set_obj_clts_.size();i++)
00154 if(!set_obj_clts_[i]->call(set_obj))
00155 {
00156 ROS_ERROR("Could not send object to server number %d",i+1);
00157 res.success=false;
00158 }
00159
00160 lock_.unlock();
00161
00162
00163 return res.success;
00164 }
00165
00166 void ModelServer::spin()
00167 {
00168
00169 if(obj_loaded_)
00170 pose_brc_->broadcastPose();
00171
00172 ros::spinOnce();
00173 }
00174
00175 bool ModelServer::loadURDF(std::string const & path,std::string & serialized_model)
00176 {
00177
00178 serialized_model.clear();
00179 std::string line;
00180 std::ifstream file(path.c_str());
00181
00182 if(!file.is_open())
00183 {
00184 ROS_ERROR("Could not open file %s",path.c_str());
00185 return false;
00186 }
00187 while(!file.eof())
00188 {
00189 std::getline(file,line);
00190 serialized_model+=line;
00191 }
00192 file.close();
00193
00194
00195
00196 urdf::Model urdf_model;
00197 if(!urdf_model.initString(serialized_model))
00198 {
00199 ROS_ERROR("Could not parse urdf model %s",path.c_str());
00200 return false;
00201 }
00202
00203 obj_name_=urdf_model.getName();
00204 obj_frame_id_="/"+urdf_model.getRoot()->name;
00205
00206
00207 nh_.setParam("icr_object",serialized_model);
00208
00209 return true;
00210 }
00211
00212 bool ModelServer::gazeboSpawnModel(std::string const & serialized_model,geometry_msgs::Pose const & initial_pose)
00213 {
00214
00215 gazebo_msgs::SpawnModel spawn_model;
00216 std_srvs::Empty empty;
00217
00218 spawn_model.request.model_name=obj_name_;
00219 spawn_model.request.model_xml=serialized_model;
00220 spawn_model.request.initial_pose=initial_pose;
00221 spawn_model.request.reference_frame="world";
00222
00223 gazebo_pause_clt_.call(empty);
00224 if (gazebo_spawn_clt_.call(spawn_model))
00225 ROS_INFO("Successfully spawned model %s in Gazebo",obj_name_.c_str());
00226 else
00227 {
00228 ROS_ERROR("Failed to spawn model %s in Gazebo",obj_name_.c_str());
00229 return false;
00230 }
00231
00232 gazebo_unpause_clt_.call(empty);
00233
00234 return true;
00235 }
00236
00237 bool ModelServer::gazeboDeleteModel(std::string const & name)
00238 {
00239
00240 gazebo_msgs::GetWorldProperties get_wp;
00241 gazebo_msgs::DeleteModel delete_model;
00242 std_srvs::Empty empty;
00243
00244 if(!gazebo_get_wp_clt_.call(get_wp))
00245 {
00246 ROS_ERROR("Could not get world properties from Gazebo");
00247 return false;
00248 }
00249
00250 delete_model.request.model_name=name;
00251
00252
00253 for(unsigned int i=0; i < get_wp.response.model_names.size();i++ )
00254 {
00255 if(!strcmp(get_wp.response.model_names[i].c_str(),name.c_str()))
00256 {
00257 gazebo_pause_clt_.call(empty);
00258 if(!gazebo_delete_clt_.call(delete_model))
00259 {
00260 ROS_WARN("Could not delete model %s",name.c_str());
00261 }
00262 gazebo_unpause_clt_.call(empty);
00263 ROS_INFO("Deleted model %s in Gazebo",name.c_str());
00264 break;
00265 }
00266 }
00267
00268 return true;
00269 }
00270
00271 bool ModelServer::loadWavefrontObj(std::string const & path, pcl::PointCloud<pcl::PointNormal> & cloud, std::vector<std::vector<unsigned int> > & neighbors )
00272 {
00273 ObjectLoader obj_loader;
00274
00275 obj_loader.loadObject(path.c_str() ,obj_name_);
00276
00277 if(!((obj_loader.objectLoaded()) && (obj_loader.getObject()->getNumCp() > 0)))
00278 {
00279 ROS_INFO("Invalid Wavefront obj file: %s",path.c_str());
00280 return false;
00281 }
00282 obj_loader.getObject()->scaleObject(scale_);
00283 double xmax=0;
00284 pcl::PointNormal p;
00285 neighbors.resize(obj_loader.getObject()->getNumCp());
00286 for(unsigned int i=0; i<obj_loader.getObject()->getNumCp();i++)
00287 {
00288 Eigen::Vector3d const * v=obj_loader.getObject()->getContactPoint(i)->getVertex();
00289 Eigen::Vector3d const * vn=obj_loader.getObject()->getContactPoint(i)->getVertexNormal();
00290 neighbors[i].resize(obj_loader.getObject()->getContactPoint(i)->getNeighbors()->size());
00291 std::copy(obj_loader.getObject()->getContactPoint(i)->getNeighbors()->begin(),obj_loader.getObject()->getContactPoint(i)->getNeighbors()->end(),neighbors[i].begin());
00292 p.x=v->x(); p.y=v->y(); p.z=v->z();
00293 p.normal[0]=vn->x(); p.normal[1]=vn->y(); p.normal[2]=vn->z();
00294 p.curvature=0;
00295 cloud.push_back(p);
00296 if(p.x > xmax)
00297 xmax=p.x;
00298
00299
00300 }
00301 cloud.header.frame_id=obj_frame_id_;
00302 cloud.header.stamp=ros::Time::now();
00303 cloud.width = cloud.size();
00304 cloud.height = 1;
00305 cloud.is_dense=true;
00306 std::cout<<"XMAX: "<<xmax<<std::endl;
00307 return true;
00308 }
00309
00310 }