00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "openraveros.h"
00015
00016 class ROSServer : public ModuleBase
00017 {
00018 inline boost::shared_ptr<ROSServer> shared_server() {
00019 return boost::static_pointer_cast<ROSServer>(shared_from_this());
00020 }
00021 inline boost::shared_ptr<ROSServer const> shared_server_const() const {
00022 return boost::static_pointer_cast<ROSServer const>(shared_from_this());
00023 }
00024
00025 public:
00026 ROSServer(EnvironmentBasePtr penv, std::istream& sinput) : ModuleBase(penv), _nNextFigureId(1), _nNextPlannerId(1), _nNextModuleId(1), _iWorkerId(0) {
00027 __description = ":Interface Author: Rosen Diankov\n\nOffers many services that can control this environment through ROS. When calling Environment::AddModule, can pass in the namespace to advertise the services on. Note that these are services just for the environment that instantiates this module! Check out the openraveros_tutorials package for how to use it (http://www.ros.org/wiki/openraveros_tutorials)";
00028 _bDestroyThreads = false;
00029 _bWorking = false;
00030 _fSimulationTimestep = 0.01;
00031 }
00032
00033 virtual ~ROSServer() {
00034 Destroy();
00035 }
00036
00037 virtual void Destroy()
00038 {
00039 _bDestroyThreads = true;
00040 Reset();
00041 {
00042 boost::mutex::scoped_lock lock(_mutexWorker);
00043 _condHasWork.notify_all();
00044 _ros.reset();
00045 _mapservices.clear();
00046 }
00047
00048 _threadviewer.join();
00049 _workerthread.join();
00050 _threadros.join();
00051
00052 _bDestroyThreads = false;
00053 ModuleBase::Destroy();
00054 }
00055
00056 virtual void Reset()
00057 {
00058
00059 {
00060 boost::mutex::scoped_lock lock(_mutexWorker);
00061 _mapplanners.clear();
00062 _mapFigureIds.clear();
00063 _listWorkers.clear();
00064
00065 {
00066 boost::mutex::scoped_lock lock(_mutexModules);
00067 FOREACH(itprob, _mapmodules)
00068 itprob->second->GetEnv()->Remove(itprob->second);
00069 _mapmodules.clear();
00070 }
00071 }
00072
00073
00074 while(_bWorking) {
00075 _conditionWorkers.notify_all();
00076 usleep(1000);
00077 }
00078
00079 if( !!_pviewer ) {
00080 _pviewer->quitmainloop();
00081 _pviewer.reset();
00082 }
00083 }
00084
00085 virtual int main(const std::string& args)
00086 {
00087 Destroy();
00088 _bDestroyThreads = false;
00089 _bWorking = false;
00090 _threadros.join();
00091
00092 stringstream ss(args);
00093 int argc=0;
00094 ros::init(argc,NULL,"openraverosserver", ros::init_options::NoSigintHandler|ros::init_options::AnonymousName);
00095 if( !ros::master::check() ) {
00096 RAVELOG_WARN("failed to create ros\n");
00097 return -1;
00098 }
00099 _ros.reset(new ros::NodeHandle());
00100
00101 _threadros = boost::thread(boost::bind(&ROSServer::_threadrosfn, this));
00102 _workerthread = boost::thread(boost::bind(&ROSServer::_WorkerThread,this));
00103
00104 string ns;
00105 ss >> ns;
00106 if( ns.size() > 0 ) {
00107 if( ns.at(ns.size()-1) != '/' ) {
00108 ns.push_back('/');
00109 }
00110 }
00111 else {
00112 ns="openrave/";
00113 }
00114 _mapservices["body_destroy"] = _ros->advertiseService(ns+string("body_destroy"),&ROSServer::body_destroy_srv,this);
00115 _mapservices["body_enable"] = _ros->advertiseService(ns+string("body_enable"),&ROSServer::body_enable_srv,this);
00116 _mapservices["body_getaabb"] = _ros->advertiseService(ns+string("body_getaabb"),&ROSServer::body_getaabb_srv,this);
00117 _mapservices["body_getaabbs"] = _ros->advertiseService(ns+string("body_getaabbs"),&ROSServer::body_getaabbs_srv,this);
00118 _mapservices["body_getdof"] = _ros->advertiseService(ns+string("body_getdof"),&ROSServer::body_getdof_srv,this);
00119 _mapservices["body_getjointvalues"] = _ros->advertiseService(ns+string("body_getjointvalues"),&ROSServer::body_getjointvalues_srv,this);
00120 _mapservices["body_setjointvalues"] = _ros->advertiseService(ns+string("body_setjointvalues"),&ROSServer::body_setjointvalues_srv,this);
00121 _mapservices["body_settransform"] = _ros->advertiseService(ns+string("body_settransform"),&ROSServer::body_settransform_srv,this);
00122 _mapservices["env_checkcollision"] = _ros->advertiseService(ns+string("env_checkcollision"),&ROSServer::env_checkcollision_srv,this);
00123 _mapservices["env_closefigures"] = _ros->advertiseService(ns+string("env_closefigures"),&ROSServer::env_closefigures_srv,this);
00124 _mapservices["env_createbody"] = _ros->advertiseService(ns+string("env_createbody"),&ROSServer::env_createbody_srv,this);
00125 _mapservices["env_createplanner"] = _ros->advertiseService(ns+string("env_createplanner"),&ROSServer::env_createplanner_srv,this);
00126 _mapservices["env_createmodule"] = _ros->advertiseService(ns+string("env_createmodule"),&ROSServer::env_createmodule_srv,this);
00127 _mapservices["env_createrobot"] = _ros->advertiseService(ns+string("env_createrobot"),&ROSServer::env_createrobot_srv,this);
00128 _mapservices["env_destroymodule"] = _ros->advertiseService(ns+string("env_destroymodule"),&ROSServer::env_destroymodule_srv,this);
00129 _mapservices["env_getbodies"] = _ros->advertiseService(ns+string("env_getbodies"),&ROSServer::env_getbodies_srv,this);
00130 _mapservices["env_getbody"] = _ros->advertiseService(ns+string("env_getbody"),&ROSServer::env_getbody_srv,this);
00131 _mapservices["env_getrobots"] = _ros->advertiseService(ns+string("env_getrobots"),&ROSServer::env_getrobots_srv,this);
00132 _mapservices["env_loadplugin"] = _ros->advertiseService(ns+string("env_loadplugin"),&ROSServer::env_loadplugin_srv,this);
00133 _mapservices["env_loadscene"] = _ros->advertiseService(ns+string("env_loadscene"),&ROSServer::env_loadscene_srv,this);
00134 _mapservices["env_plot"] = _ros->advertiseService(ns+string("env_plot"),&ROSServer::env_plot_srv,this);
00135 _mapservices["env_raycollision"] = _ros->advertiseService(ns+string("env_raycollision"),&ROSServer::env_raycollision_srv,this);
00136 _mapservices["env_set"] = _ros->advertiseService(ns+string("env_set"),&ROSServer::env_set_srv,this);
00137 _mapservices["env_triangulate"] = _ros->advertiseService(ns+string("env_triangulate"),&ROSServer::env_triangulate_srv,this);
00138 _mapservices["env_wait"] = _ros->advertiseService(ns+string("env_wait"),&ROSServer::env_wait_srv,this);
00139 _mapservices["planner_init"] = _ros->advertiseService(ns+string("planner_init"),&ROSServer::planner_init_srv,this);
00140 _mapservices["planner_plan"] = _ros->advertiseService(ns+string("planner_plan"),&ROSServer::planner_plan_srv,this);
00141 _mapservices["module_sendcommand"] = _ros->advertiseService(ns+string("module_sendcommand"),&ROSServer::module_sendcommand_srv,this);
00142 _mapservices["robot_controllersend"] = _ros->advertiseService(ns+string("robot_controllersend"),&ROSServer::robot_controllersend_srv,this);
00143 _mapservices["robot_controllerset"] = _ros->advertiseService(ns+string("robot_controllerset"),&ROSServer::robot_controllerset_srv,this);
00144 _mapservices["robot_getactivevalues"] = _ros->advertiseService(ns+string("robot_getactivevalues"),&ROSServer::robot_getactivevalues_srv,this);
00145 _mapservices["robot_sensorgetdata"] = _ros->advertiseService(ns+string("robot_sensorgetdata"),&ROSServer::robot_sensorgetdata_srv,this);
00146 _mapservices["robot_sensorsend"] = _ros->advertiseService(ns+string("robot_sensorsend"),&ROSServer::robot_sensorsend_srv,this);
00147 _mapservices["robot_setactivedofs"] = _ros->advertiseService(ns+string("robot_setactivedofs"),&ROSServer::robot_setactivedofs_srv,this);
00148 _mapservices["robot_setactivemanipulator"] = _ros->advertiseService(ns+string("robot_setactivemanipulator"),&ROSServer::robot_setactivemanipulator_srv,this);
00149 _mapservices["robot_setactivevalues"] = _ros->advertiseService(ns+string("robot_setactivevalues"),&ROSServer::robot_setactivevalues_srv,this);
00150 _mapservices["robot_starttrajectory"] = _ros->advertiseService(ns+string("robot_starttrajectory"),&ROSServer::robot_starttrajectory_srv,this);
00151 return 0;
00152 }
00153
00154 virtual void _threadrosfn()
00155 {
00156 while(!_bDestroyThreads && ros::ok()) {
00157 ros::spinOnce();
00158 usleep(1000);
00159 }
00160 }
00161
00163 virtual void _WorkerThread()
00164 {
00165 RAVELOG_DEBUG("starting ros worker thread\n");
00166 list<boost::function<void()> > listlocalworkers;
00167
00168 while(!_bDestroyThreads) {
00169 {
00170 boost::mutex::scoped_lock lock(_mutexWorker);
00171 _condHasWork.wait(lock);
00172 if( _bDestroyThreads ) {
00173 break;
00174 }
00175 if( _listWorkers.size() == 0 ) {
00176 _conditionWorkers.notify_all();
00177 continue;
00178 }
00179
00180 _bWorking = true;
00181 listlocalworkers.swap(_listWorkers);
00182 _iWorkerId++;
00183 }
00184
00185
00186 FOREACH(it, listlocalworkers) {
00187 try {
00188 (*it)();
00189 }
00190 catch(const openrave_exception& ex) {
00191 RAVELOG_FATAL("%s\n",ex.what());
00192 }
00193 }
00194 listlocalworkers.clear();
00195
00196 boost::mutex::scoped_lock lock(_mutexWorker);
00197 _bWorking = false;
00198 _iWorkerId++;
00199 _conditionWorkers.notify_all();
00200 }
00201
00202 _bWorking = false;
00203 RAVELOG_DEBUG("stopping ros worker thread\n");
00204 }
00205
00206 virtual void AddWorker(const boost::function<void()>& fn, bool bWait=true)
00207 {
00208 boost::mutex::scoped_lock lock(_mutexWorker);
00209 int iWorkerId = _iWorkerId;
00210
00211 _listWorkers.push_back(fn);
00212 _condHasWork.notify_all();
00213 if( bWait ) {
00214 while(!_bDestroyThreads) {
00215 _conditionWorkers.wait(lock);
00216 if( _iWorkerId >= iWorkerId+2 ) {
00217 break;
00218 }
00219 _condHasWork.notify_all();
00220 }
00221 }
00222 }
00223
00225 virtual void ViewerThread(const string& strviewer)
00226 {
00227 {
00228 boost::mutex::scoped_lock lock(_mutexViewer);
00229 _pviewer = RaveCreateViewer(GetEnv(),strviewer);
00230 if( !!_pviewer ) {
00231 GetEnv()->AddViewer(_pviewer);
00232 _pviewer->SetSize(1024,768);
00233 }
00234 _conditionViewer.notify_all();
00235 }
00236
00237 if( !_pviewer ) {
00238 return;
00239 }
00240 _pviewer->main();
00241 RAVELOG_DEBUGA("destroying viewer\n");
00242 _pviewer.reset();
00243 }
00244
00245 bool SetPhysicsEngine(const string& physicsengine)
00246 {
00247 PhysicsEngineBasePtr p = RaveCreatePhysicsEngine(GetEnv(),physicsengine);
00248 if( !p ) {
00249 return false;
00250 }
00251 GetEnv()->SetPhysicsEngine(p);
00252 return true;
00253 }
00254
00255 bool SetCollisionChecker(const string& collisionchecker)
00256 {
00257 CollisionCheckerBasePtr p = RaveCreateCollisionChecker(GetEnv(),collisionchecker);
00258 if( !p ) {
00259 return false;
00260 }
00261 GetEnv()->SetCollisionChecker(p);
00262 return true;
00263 }
00264
00265 bool SetViewer(const string& viewer)
00266 {
00267 if( viewer.size() == 0 ) {
00268 return true;
00269 }
00270 if( !!_setviewer ) {
00271 stringstream ss;
00272 ss << "OpenRAVE " << OPENRAVE_VERSION_STRING << " - session " << RaveGetEnvironmentId(GetEnv());
00273 return _setviewer(viewer,ss.str());
00274 }
00275
00276 _threadviewer.join();
00277
00278 if( viewer.size() > 0 ) {
00279 boost::mutex::scoped_lock lock(_mutexViewer);
00280 _threadviewer = boost::thread(boost::bind(&ROSServer::ViewerThread, this, viewer));
00281 _conditionViewer.wait(lock);
00282
00283 if( !_pviewer ) {
00284 RAVELOG_WARNA(str(boost::format("failed to create viewer %s\n")%viewer));
00285 _threadviewer.join();
00286 return false;
00287 }
00288 else {
00289 RAVELOG_INFO(str(boost::format("viewer %s successfully attached\n")%viewer));
00290 }
00291 }
00292
00293 return true;
00294 }
00295
00297
00299
00300 bool body_destroy_srv(openraveros::body_destroy::Request& req, openraveros::body_destroy::Response& res)
00301 {
00302 KinBodyPtr pbody = _FromROSBody(req.bodyid);
00303 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00304 return GetEnv()->Remove(pbody);
00305 }
00306
00307 bool body_enable_srv(openraveros::body_enable::Request& req, openraveros::body_enable::Response& res)
00308 {
00309 KinBodyPtr pbody = _FromROSBody(req.bodyid);
00310 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00311 pbody->Enable(req.enable);
00312 return true;
00313 }
00314
00315 bool body_getaabb_srv(openraveros::body_getaabb::Request& req, openraveros::body_getaabb::Response& res)
00316 {
00317 KinBodyPtr pbody = _FromROSBody(req.bodyid);
00318 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00319 OpenRAVE::AABB ab = pbody->ComputeAABB();
00320 res.box.center[0] = ab.pos.x; res.box.center[1] = ab.pos.y; res.box.center[2] = ab.pos.z;
00321 res.box.extents[0] = ab.extents.x; res.box.extents[1] = ab.extents.y; res.box.extents[2] = ab.extents.z;
00322 return true;
00323 }
00324
00325 bool body_getaabbs_srv(openraveros::body_getaabbs::Request& req, openraveros::body_getaabbs::Response& res)
00326 {
00327 KinBodyPtr pbody = _FromROSBody(req.bodyid);
00328 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00329 res.boxes.resize(pbody->GetLinks().size()); int index = 0;
00330 FOREACHC(itlink, pbody->GetLinks()) {
00331 OpenRAVE::AABB ab = (*itlink)->ComputeAABB();
00332 openraveros::AABB& resbox = res.boxes[index++];
00333 resbox.center[0] = ab.pos.x; resbox.center[1] = ab.pos.y; resbox.center[2] = ab.pos.z;
00334 resbox.extents[0] = ab.extents.x; resbox.extents[1] = ab.extents.y; resbox.extents[2] = ab.extents.z;
00335 }
00336 return true;
00337 }
00338
00339 bool body_getdof_srv(openraveros::body_getdof::Request& req, openraveros::body_getdof::Response& res)
00340 {
00341 KinBodyPtr pbody = _FromROSBody(req.bodyid);
00342 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00343 res.dof = pbody->GetDOF();
00344 return true;
00345 }
00346
00347 bool body_getjointvalues_srv(openraveros::body_getjointvalues::Request& req, openraveros::body_getjointvalues::Response& res)
00348 {
00349 KinBodyPtr pbody = _FromROSBody(req.bodyid);
00350 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00351 if( req.indices.size() > 0 ) {
00352 vector<dReal> vtemp;
00353 pbody->GetDOFValues(vtemp);
00354
00355 res.values.resize(req.indices.size());
00356 for(size_t i = 0; i < req.indices.size(); ++i) {
00357 BOOST_ASSERT( req.indices[i] < vtemp.size() );
00358 res.values[i] = vtemp[req.indices[i]];
00359 }
00360 }
00361 else {
00362 vector<dReal> vtemp;
00363 pbody->GetDOFValues(vtemp);
00364
00365 res.values.resize(vtemp.size());
00366 for(size_t i = 0; i < res.values.size(); ++i)
00367 res.values[i] = vtemp[i];
00368 }
00369
00370 return true;
00371 }
00372
00373 bool body_setjointvalues_srv(openraveros::body_setjointvalues::Request& req, openraveros::body_setjointvalues::Response& res)
00374 {
00375 KinBodyPtr pbody = _FromROSBody(req.bodyid);
00376 BOOST_ASSERT( pbody->GetDOF() > 0 );
00377
00378 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00379 vector<dReal> vvalues;
00380
00381 if( req.indices.size() > 0 ) {
00382 if( req.indices.size() != req.jointvalues.size() ) {
00383 RAVELOG_WARNA("indices (%d) different size than joint values (%d)\n", req.indices.size(), req.jointvalues.size());
00384 return false;
00385 }
00386
00387 pbody->GetDOFValues(vvalues);
00388 for(uint32_t i = 0; i < req.indices.size(); ++i)
00389 vvalues[req.indices[i]] = req.jointvalues[i];
00390 }
00391 else {
00392 if( pbody->GetDOF() != (int)req.jointvalues.size() ) {
00393 RAVELOG_WARNA("body dof (%d) not equal to jointvalues (%d)", pbody->GetDOF(), req.jointvalues.size());
00394 return false;
00395 }
00396
00397 vvalues.reserve(req.jointvalues.size());
00398 FOREACHC(it,req.jointvalues)
00399 vvalues.push_back(*it);
00400 }
00401
00402 pbody->SetJointValues(vvalues, true);
00403
00404 if( pbody->IsRobot() ) {
00405
00406 RobotBasePtr probot = boost::static_pointer_cast<RobotBase>(pbody);
00407 if( !!probot->GetController() ) {
00408 probot->GetDOFValues(vvalues);
00409 probot->GetController()->SetDesired(vvalues);
00410 }
00411 }
00412
00413 return true;
00414 }
00415
00416 bool body_settransform_srv(openraveros::body_settransform::Request& req, openraveros::body_settransform::Response& res)
00417 {
00418 KinBodyPtr pbody = _FromROSBody(req.bodyid);
00419 Transform t = _FromROSAffineTransform(req.transform);
00420 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00421 pbody->SetTransform(t);
00422
00423 if( pbody->IsRobot() ) {
00424 RobotBasePtr probot = boost::static_pointer_cast<RobotBase>(pbody);
00425 if( !!probot->GetController() )
00426 probot->GetController()->SetPath(TrajectoryBasePtr());
00427 }
00428
00429 return true;
00430 }
00431
00432 bool env_checkcollision_srv(openraveros::env_checkcollision::Request& req, openraveros::env_checkcollision::Response& res)
00433 {
00434 KinBodyPtr pbody = GetEnv()->GetBodyFromEnvironmentId(req.bodyid);
00435 if( !pbody )
00436 return false;
00437
00438 vector<KinBodyConstPtr> setignore;
00439 FOREACH(it, req.excludedbodyids) {
00440 KinBodyPtr pbody = GetEnv()->GetBodyFromEnvironmentId(req.bodyid);
00441 if( !pbody )
00442 return false;
00443 setignore.push_back(pbody);
00444 }
00445
00446 boost::shared_ptr<CollisionReport> report(new CollisionReport());
00447 {
00448 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00449 int oldopts = GetEnv()->GetCollisionChecker()->GetCollisionOptions();
00450 if( !GetEnv()->GetCollisionChecker()->SetCollisionOptions(req.options) )
00451 RAVELOG_WARNA("failed to set collision options\n");
00452
00453 vector<KinBody::LinkConstPtr> empty;
00454 if( req.linkid < 0 )
00455 res.collision = GetEnv()->CheckCollision(pbody, setignore, empty, report);
00456 else {
00457 if( req.linkid >= (int)pbody->GetLinks().size() )
00458 return false;
00459 res.collision = GetEnv()->CheckCollision(pbody->GetLinks().at(req.linkid), setignore, empty, report);
00460 }
00461
00462 if( !res.collision && req.checkselfcollision ) {
00463 res.collision = pbody->CheckSelfCollision(report);
00464 }
00465
00466 GetEnv()->GetCollisionChecker()->SetCollisionOptions(oldopts);
00467 }
00468
00469 res.collidingbodyid = 0;
00470
00471 if( res.collision ) {
00472 KinBody::LinkConstPtr plinkcol = report->plink1;
00473 if( !!report->plink2 && report->plink2->GetParent() != pbody && !pbody->IsAttached(report->plink2->GetParent()) ) {
00474 plinkcol = report->plink2;
00475 }
00476
00477 if( !!plinkcol ) {
00478 res.collidingbodyid = plinkcol->GetParent()->GetEnvironmentId();
00479 res.collidinglink = plinkcol->GetIndex();
00480 }
00481
00482 RAVELOG_DEBUGA(str(boost::format("collision %s:%s with %s:%s\n")%
00483 (!!report->plink1 ? report->plink1->GetParent()->GetName() : "(NULL)")%
00484 (!!report->plink1 ? report->plink1->GetName() : "(NULL)")%
00485 (!!report->plink2 ? report->plink2->GetParent()->GetName() : "(NULL)")%
00486 (!!report->plink2 ? report->plink2->GetName() : "(NULL)")));
00487 }
00488
00489 if( req.options & CO_Distance )
00490 res.mindist = report->minDistance;
00491 if( req.options & CO_Contacts ) {
00492 res.contacts.resize(report->contacts.size());
00493 int negnormals = 0;
00494 if( !!report->plink1 ) {
00495 if( req.linkid < 0 )
00496 negnormals = report->plink1->GetParent() != pbody;
00497 else
00498 negnormals = report->plink1->GetParent() != pbody || report->plink1->GetIndex() != req.linkid;
00499 }
00500
00501 int index = 0;
00502 FOREACHC(itc, report->contacts) {
00503 openraveros::Contact& c = res.contacts[index++];
00504 Vector vnorm = negnormals ? -itc->norm : itc->norm;
00505 c.position[0] = itc->pos.x; c.position[1] = itc->pos.y; c.position[2] = itc->pos.z;
00506 c.normal[0] = vnorm.x; c.normal[1] = vnorm.y; c.normal[2] = vnorm.z;
00507 }
00508 }
00509
00510 return true;
00511 }
00512
00513 bool env_closefigures_srv(openraveros::env_closefigures::Request& req, openraveros::env_closefigures::Response& res)
00514 {
00515 bool bSuccess = true;
00516
00517 if( req.figureids.size() > 0 ) {
00518 FOREACH(itid, req.figureids) {
00519 if( !_mapFigureIds.erase(*itid) )
00520 bSuccess = false;
00521 }
00522 }
00523 else
00524 _mapFigureIds.clear();
00525
00526 return bSuccess;
00527 }
00528
00529 bool env_createbody_srv(openraveros::env_createbody::Request& req, openraveros::env_createbody::Response& res)
00530 {
00531 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00532 KinBodyPtr pbody;
00533
00534 if( req.file.size() > 0 ) {
00535 pbody = GetEnv()->ReadKinBodyXMLFile(req.file);
00536 }
00537 else {
00538 pbody = RaveCreateKinBody(GetEnv());
00539 }
00540 if( !pbody ) {
00541 return false;
00542 }
00543 pbody->SetName(req.name);
00544
00545 GetEnv()->Add(pbody);
00546 res.bodyid = pbody->GetEnvironmentId();
00547 return true;
00548 }
00549
00550 bool env_createplanner_srv(openraveros::env_createplanner::Request& req, openraveros::env_createplanner::Response& res)
00551 {
00552 PlannerBasePtr pplanner = RaveCreatePlanner(GetEnv(),req.plannertype);
00553 if( !pplanner )
00554 return false;
00555
00556 _mapplanners[++_nNextPlannerId] = pplanner;
00557 res.plannerid = _nNextPlannerId;
00558 return true;
00559 }
00560
00561 void _AddModuleWorker(int& retval, ModuleBasePtr module, const string& args )
00562 {
00563 retval = module->GetEnv()->AddModule(module, args);
00564 }
00565
00566 bool env_createmodule_srv(openraveros::env_createmodule::Request& req, openraveros::env_createmodule::Response& res)
00567 {
00568 ModuleBasePtr pmodule = RaveCreateModule(GetEnv(),req.xmlid);
00569 if( !pmodule ) {
00570 return false;
00571 }
00572 boost::mutex::scoped_lock lock(_mutexModules);
00573
00574 if( req.destroyduplicates ) {
00575 map<int, ModuleBasePtr >::iterator itmodule = _mapmodules.begin();
00576 while(itmodule != _mapmodules.end()) {
00577 if( itmodule->second->GetXMLId() == req.xmlid ) {
00578 RAVELOG_INFO(str(boost::format("deleting duplicate module %s\n")%req.xmlid));
00579 if( !GetEnv()->Remove(itmodule->second) ) {
00580 RAVELOG_WARN(str(boost::format("failed to remove module %s\n")%itmodule->second->GetXMLId()));
00581 }
00582 _mapmodules.erase(itmodule++);
00583 }
00584 else {
00585 ++itmodule;
00586 }
00587 }
00588 }
00589
00590 int retval=0;
00591 AddWorker(boost::bind(&ROSServer::_AddModuleWorker,shared_server(),boost::ref(retval), pmodule,req.args),true);
00592
00593 if( retval != 0 ) {
00594 RAVELOG_WARNA(str(boost::format("failed to load module %s with args %s\n")%req.xmlid%req.args));
00595 return false;
00596 }
00597
00598 _mapmodules[++_nNextModuleId] = pmodule;
00599 res.id = _nNextModuleId;
00600 return true;
00601 }
00602
00603 bool env_createrobot_srv(openraveros::env_createrobot::Request& req, openraveros::env_createrobot::Response& res)
00604 {
00605 RobotBasePtr probot;
00606 if( req.file.size() > 0 ) {
00607 probot = GetEnv()->ReadRobotXMLFile(req.file);
00608 }
00609 else {
00610 probot = RaveCreateRobot(GetEnv(),req.type);
00611 }
00612 if( !probot ) {
00613 return false;
00614 }
00615 probot->SetName(req.name);
00616
00617 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00618 GetEnv()->Add(probot);;
00619 res.bodyid = probot->GetEnvironmentId();
00620 return true;
00621 }
00622
00623 bool env_destroymodule_srv(openraveros::env_destroymodule::Request& req, openraveros::env_destroymodule::Response& res)
00624 {
00625 boost::mutex::scoped_lock lock(_mutexModules);
00626 map<int, ModuleBasePtr >::iterator itmodule = _mapmodules.find(req.id);
00627 if( itmodule == _mapmodules.end() ) {
00628 return false;
00629 }
00630 ModuleBasePtr prob = itmodule->second;
00631 _mapmodules.erase(itmodule);
00632
00633 if( !GetEnv()->Remove(itmodule->second) ) {
00634 RAVELOG_WARNA("failed to remove module\n");
00635 return false;
00636 }
00637 return true;
00638 }
00639
00640 bool env_getbodies_srv(openraveros::env_getbodies::Request& req, openraveros::env_getbodies::Response& res)
00641 {
00642 vector<KinBodyPtr> vbodies;
00643 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00644 GetEnv()->GetBodies(vbodies);
00645
00646 if( req.bodyid != 0 ) {
00647 KinBodyPtr pfound;
00648 FOREACH(it, vbodies) {
00649 if( (*it)->GetEnvironmentId() == req.bodyid ) {
00650 pfound = *it;
00651 break;
00652 }
00653 }
00654
00655 if( !pfound )
00656 return false;
00657
00658
00659 vbodies.resize(0); vbodies.push_back(pfound);
00660 }
00661
00662 res.bodies.resize(vbodies.size()); int index = 0;
00663 FOREACH(itbody, vbodies) {
00664 openraveros::BodyInfo& info = res.bodies[index++];
00665 _GetROSBodyInfo(*itbody, info, req.options);
00666 }
00667
00668 return true;
00669 }
00670
00671 bool env_getbody_srv(openraveros::env_getbody::Request& req, openraveros::env_getbody::Response& res)
00672 {
00673 KinBodyPtr pbody = GetEnv()->GetKinBody(req.name);
00674 if( !pbody )
00675 return false;
00676 res.bodyid = pbody->GetEnvironmentId();
00677 return true;
00678 }
00679
00680 bool env_getrobots_srv(openraveros::env_getrobots::Request& req, openraveros::env_getrobots::Response& res)
00681 {
00682 vector<RobotBasePtr> vrobots;
00683 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00684 GetEnv()->GetRobots(vrobots);
00685
00686 if( req.bodyid != 0 ) {
00687 RobotBasePtr pfound;
00688 FOREACH(it, vrobots) {
00689 if( (*it)->GetEnvironmentId() == req.bodyid ) {
00690 pfound = *it;
00691 break;
00692 }
00693 }
00694
00695 if( !pfound )
00696 return false;
00697
00698
00699 vrobots.resize(0); vrobots.push_back(pfound);
00700 }
00701
00702 res.robots.resize(vrobots.size()); int index = 0;
00703 FOREACH(itrobot, vrobots) {
00704 BOOST_ASSERT( (*itrobot)->IsRobot() );
00705 openraveros::RobotInfo& info = res.robots[index++];
00706 _GetROSRobotInfo(*itrobot, info, req.options);
00707 }
00708
00709 return true;
00710 }
00711
00712 bool env_loadplugin_srv(openraveros::env_loadplugin::Request& req, openraveros::env_loadplugin::Response& res)
00713 {
00714 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00715 return RaveLoadPlugin(req.filename);
00716 }
00717
00718 bool env_loadscene_srv(openraveros::env_loadscene::Request& req, openraveros::env_loadscene::Response& res)
00719 {
00720 if( req.resetscene )
00721 GetEnv()->Reset();
00722 if( req.filename.size() > 0 )
00723 return GetEnv()->Load(req.filename);
00724
00725 return true;
00726 }
00727
00728 bool env_plot_srv(openraveros::env_plot::Request& req, openraveros::env_plot::Response& res)
00729 {
00730 bool bOneColor = req.colors.size() != req.points.size();
00731 float falpha = max(0.0f, 1.0f-req.transparency);
00732 falpha = min(1.0f,falpha);
00733 RaveVector<float> vOneColor(1.0f,0.5f,0.5f,falpha);
00734 if( req.colors.size() >= 3 )
00735 vOneColor = RaveVector<float>(req.colors[0], req.colors[1], req.colors[2],falpha);
00736
00737 GraphHandlePtr figure;
00738 switch(req.drawtype) {
00739 case openraveros::env_plot::Request::Draw_Point:
00740 if( bOneColor ) {
00741 figure = GetEnv()->plot3(&req.points[0],req.points.size()/3,3*sizeof(req.points[0]),req.size,vOneColor, 0);
00742 }
00743 else {
00744 figure = GetEnv()->plot3(&req.points[0],req.points.size()/3,3*sizeof(req.points[0]),req.size,&req.colors[0], 0);
00745 }
00746 break;
00747 case openraveros::env_plot::Request::Draw_LineStrip:
00748 if( bOneColor ) {
00749 figure = GetEnv()->drawlinestrip(&req.points[0],req.points.size()/3,3*sizeof(req.points[0]),req.size,vOneColor);
00750 }
00751 else {
00752 figure = GetEnv()->drawlinestrip(&req.points[0],req.points.size()/3,3*sizeof(req.points[0]),req.size,&req.colors[0]);
00753 }
00754 break;
00755 case openraveros::env_plot::Request::Draw_LineList:
00756 if( bOneColor ) {
00757 figure = GetEnv()->drawlinelist(&req.points[0],req.points.size()/3,3*sizeof(req.points[0]),req.size,vOneColor);
00758 }
00759 else {
00760 figure = GetEnv()->drawlinelist(&req.points[0],req.points.size()/3,3*sizeof(req.points[0]),req.size,&req.colors[0]);
00761 }
00762 break;
00763 case openraveros::env_plot::Request::Draw_TriList:
00764
00765 figure = GetEnv()->drawtrimesh(&req.points[0],3*sizeof(req.points[0]), NULL, req.points.size()/9, vOneColor);
00766
00767
00768 break;
00769 case openraveros::env_plot::Request::Draw_Sphere:
00770 if( bOneColor ) {
00771 figure = GetEnv()->plot3(&req.points[0],req.points.size()/3,3*sizeof(req.points[0]),req.size,vOneColor, 1);
00772 }
00773 else {
00774 figure = GetEnv()->plot3(&req.points[0],req.points.size()/3,3*sizeof(req.points[0]),req.size,&req.colors[0], 1);
00775 }
00776 break;
00777 default:
00778 return false;
00779 }
00780
00781 if( !figure ) {
00782 return false;
00783 }
00784 _mapFigureIds[++_nNextFigureId] = figure;
00785 res.figureid = _nNextFigureId;
00786 return true;
00787 }
00788
00789 bool env_raycollision_srv(openraveros::env_raycollision::Request& req, openraveros::env_raycollision::Response& res)
00790 {
00791 KinBodyPtr pbody;
00792 if( req.bodyid != 0 )
00793 pbody = GetEnv()->GetBodyFromEnvironmentId(req.bodyid);
00794
00795 res.collision.reserve(req.rays.size()); res.collision.resize(0);
00796
00797 if( req.request_contacts ) {
00798 res.contacts.reserve(req.rays.size());
00799 res.contacts.resize(0);
00800 }
00801
00802 if( req.request_bodies ) {
00803 res.hitbodies.reserve(req.rays.size());
00804 res.hitbodies.resize(0);
00805 }
00806
00807 boost::shared_ptr<CollisionReport> report(new CollisionReport());
00808 {
00809 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00810 int oldopts = GetEnv()->GetCollisionChecker()->GetCollisionOptions();
00811 if( !GetEnv()->GetCollisionChecker()->SetCollisionOptions(req.request_contacts ? CO_Contacts : 0) )
00812 RAVELOG_WARNA("failed to set collision options\n");
00813
00814 FOREACHC(itray, req.rays) {
00815 RAY r;
00816 r.pos = Vector(itray->position[0], itray->position[1], itray->position[2]);
00817 r.dir = Vector(itray->direction[0], itray->direction[1], itray->direction[2]);
00818
00819 uint8_t bCollision = 0;
00820
00821 if( r.dir.lengthsqr3() > 1e-7 ) {
00822 r.dir.normalize3();
00823
00824 if( !!pbody )
00825 bCollision = GetEnv()->CheckCollision(r,pbody,report);
00826 else
00827 bCollision = GetEnv()->CheckCollision(r,report);
00828 }
00829 else
00830 RAVELOG_WARNA("ray has zero direction\n");
00831
00832 res.collision.push_back(bCollision);
00833 if( bCollision && req.request_contacts ) {
00834 openraveros::Contact rosc;
00835 if( report->contacts.size() > 0 ) {
00836 CollisionReport::CONTACT& c = report->contacts.front();
00837 rosc.position[0] = c.pos.x; rosc.position[1] = c.pos.y; rosc.position[2] = c.pos.z;
00838 rosc.normal[0] = c.norm.x; rosc.normal[1] = c.norm.y; rosc.normal[2] = c.norm.z;
00839 }
00840 res.contacts.push_back(rosc);
00841 }
00842 else
00843 res.contacts.push_back(openraveros::Contact());
00844
00845
00846 if( bCollision && req.request_bodies ) {
00847 KinBody::LinkConstPtr plink = !!report->plink1 ? report->plink1 : report->plink2;
00848 res.hitbodies.push_back(!!plink ? plink->GetParent()->GetEnvironmentId() : 0);
00849 }
00850 else
00851 res.hitbodies.push_back(0);
00852 }
00853
00854 GetEnv()->GetCollisionChecker()->SetCollisionOptions(oldopts);
00855 }
00856
00857 return true;
00858 }
00859
00860 bool env_set_srv(openraveros::env_set::Request& req, openraveros::env_set::Response& res)
00861 {
00862 if( req.setmask & openraveros::env_set::Request::Set_Simulation ) {
00863 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00864 switch(req.sim_action) {
00865 case openraveros::env_set::Request::SimAction_Start:
00866 if( req.sim_timestep > 0 ) {
00867 _fSimulationTimestep = req.sim_timestep;
00868 }
00869 GetEnv()->StartSimulation(_fSimulationTimestep);
00870 break;
00871 case openraveros::env_set::Request::SimAction_Stop:
00872 GetEnv()->StopSimulation();
00873 break;
00874 case openraveros::env_set::Request::SimAction_Timestep:
00875 _fSimulationTimestep = req.sim_timestep;
00876 GetEnv()->StartSimulation(_fSimulationTimestep);
00877 break;
00878 }
00879 }
00880 if( req.setmask & openraveros::env_set::Request::Set_PhysicsEngine ) {
00881 SetPhysicsEngine(req.physicsengine);
00882 }
00883 if( req.setmask & openraveros::env_set::Request::Set_CollisionChecker ) {
00884 SetCollisionChecker(req.collisionchecker);
00885 }
00886 if( req.setmask & openraveros::env_set::Request::Set_Gravity ) {
00887 GetEnv()->GetPhysicsEngine()->SetGravity(Vector(req.gravity[0],req.gravity[1],req.gravity[2]));
00888 }
00889 if( req.setmask & openraveros::env_set::Request::Set_DebugLevel ) {
00890 map<string,DebugLevel> mlevels;
00891 mlevels["fatal"] = Level_Fatal;
00892 mlevels["error"] = Level_Error;
00893 mlevels["info"] = Level_Info;
00894 mlevels["warn"] = Level_Warn;
00895 mlevels["debug"] = Level_Debug;
00896 mlevels["verbose"] = Level_Verbose;
00897 int level = GetEnv()->GetDebugLevel();
00898 if( mlevels.find(req.debuglevel) != mlevels.end() ) {
00899 level = mlevels[req.debuglevel];
00900 }
00901 else {
00902 stringstream ss(req.debuglevel);
00903 int nlevel;
00904 ss >> nlevel;
00905 if( !!ss ) {
00906 level = nlevel;
00907 }
00908 }
00909 GetEnv()->SetDebugLevel(level);
00910 }
00911 if( req.setmask & openraveros::env_set::Request::Set_Viewer ) {
00912 if( !!_pviewer ) {
00913 GetEnv()->Remove(_pviewer);
00914 }
00915 SetViewer(req.viewer);
00916 }
00917 if( req.setmask & openraveros::env_set::Request::Set_ViewerDims ) {
00918 if( !!GetEnv()->GetViewer() ) {
00919 GetEnv()->GetViewer()->SetSize(req.viewerwidth,req.viewerheight);
00920 }
00921 }
00922
00923 return true;
00924 }
00925
00926 bool env_triangulate_srv(openraveros::env_triangulate::Request& req, openraveros::env_triangulate::Response& res)
00927 {
00928 set<int> setobjids;
00929 FOREACH(it, req.bodyids)
00930 setobjids.insert(*it);
00931
00932 KinBody::Link::TRIMESH trimesh;
00933
00934 {
00935 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
00936
00937 vector<KinBodyPtr> vbodies;
00938 GetEnv()->GetBodies(vbodies);
00939
00940 FOREACH(itbody, vbodies) {
00941 if( (setobjids.find((*itbody)->GetEnvironmentId()) == setobjids.end()) ^ !req.inclusive )
00942 continue;
00943 GetEnv()->Triangulate(trimesh, *itbody);
00944 }
00945 }
00946
00947 res.points.resize(3*trimesh.vertices.size());
00948 for(size_t i = 0; i < trimesh.vertices.size(); ++i) {
00949 Vector& v = trimesh.vertices[i];
00950 res.points[3*i+0] = v.x;
00951 res.points[3*i+1] = v.y;
00952 res.points[3*i+2] = v.z;
00953 }
00954
00955 res.indices.resize(trimesh.indices.size());
00956 for(size_t i = 0; i < trimesh.indices.size(); ++i)
00957 res.indices[i] = (uint32_t)trimesh.indices[i];
00958
00959 return true;
00960 }
00961
00962 bool env_wait_srv(openraveros::env_wait::Request& req, openraveros::env_wait::Response& res)
00963 {
00964 KinBodyPtr pbody = GetEnv()->GetBodyFromEnvironmentId(req.bodyid);
00965 if( !pbody || !pbody->IsRobot() ) {
00966 return false;
00967 }
00968 RobotBasePtr probot = boost::static_pointer_cast<RobotBase>(pbody);
00969 ControllerBasePtr pcontroller = probot->GetController();
00970 if( !pcontroller ) {
00971 return false;
00972 }
00973 uint32_t timeout = (uint32_t)(req.timeout*1000.0f);
00974 while( !pcontroller->IsDone() ) {
00975 usleep(400);
00976 if( timeout > 0 ) {
00977 if( --timeout == 0 )
00978 break;
00979 }
00980 if( _bDestroyThreads ) {
00981 return false;
00982 }
00983 }
00984
00985 res.isdone = pcontroller->IsDone();
00986 return true;
00987 }
00988
00989 bool planner_init_srv(openraveros::planner_init::Request& req, openraveros::planner_init::Response& res)
00990 {
00991 KinBodyPtr pbody = GetEnv()->GetBodyFromEnvironmentId(req.robotid);
00992 if( !pbody || !pbody->IsRobot() )
00993 return false;
00994 RobotBasePtr probot = boost::static_pointer_cast<RobotBase>(pbody);
00995
00996 map<int, boost::shared_ptr<PlannerBase> >::iterator itplanner = _mapplanners.find(req.plannerid);
00997 if( itplanner == _mapplanners.end() )
00998 return false;
00999
01000 boost::shared_ptr<PlannerBase::PlannerParameters> params;
01001
01002 RAVELOG_ERRORA("need to fill with params!\n");
01003
01004 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
01005 return itplanner->second->InitPlan(probot, params);
01006 }
01007
01008 bool planner_plan_srv(openraveros::planner_plan::Request& req, openraveros::planner_plan::Response& res)
01009 {
01010 map<int, PlannerBasePtr >::iterator itplanner = _mapplanners.find(req.plannerid);
01011 if( itplanner == _mapplanners.end() ) {
01012 return false;
01013 }
01014 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
01015
01016 TrajectoryBasePtr traj = RaveCreateTrajectory(GetEnv(),"");
01017 RAVELOG_DEBUG("starting to plan");
01018 if( !(itplanner->second->PlanPath(traj)&PS_HasSolution) ) {
01019 RAVELOG_DEBUG("plan failed\n");
01020 return false;
01021 }
01022 _GetROSTrajectory(res.trajectory, traj);
01023 return true;
01024 }
01025
01026 bool module_sendcommand_srv(openraveros::module_sendcommand::Request& req, openraveros::module_sendcommand::Response& res)
01027 {
01028 boost::mutex::scoped_lock lock(_mutexModules);
01029 map<int, ModuleBasePtr >::iterator itmodule = _mapmodules.find(req.id);
01030 if( itmodule == _mapmodules.end() ) {
01031 return false;
01032 }
01033 try {
01034 stringstream sout;
01035 stringstream sin(req.cmd);
01036 if( itmodule->second->SendCommand(sout,sin) ) {
01037 res.output = sout.str();
01038 return true;
01039 }
01040 }
01041 catch(const openrave_exception& ex) {
01042 RAVELOG_FATAL("%s\n",ex.what());
01043 }
01044
01045 return false;
01046 }
01047
01048 bool robot_controllersend_srv(openraveros::robot_controllersend::Request& req, openraveros::robot_controllersend::Response& res)
01049 {
01050 RobotBasePtr probot = _FromROSRobot(req.robotid);
01051 ControllerBasePtr pcontroller = probot->GetController();
01052 if( !pcontroller ) {
01053 return false;
01054 }
01055 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
01056 stringstream sout;
01057 stringstream sin(req.cmd);
01058 if( pcontroller->SendCommand(sout,sin) ) {
01059 res.output = sout.str();
01060 return true;
01061 }
01062 return false;
01063 }
01064
01065 bool robot_controllerset_srv(openraveros::robot_controllerset::Request& req, openraveros::robot_controllerset::Response& res)
01066 {
01067 RobotBasePtr probot = _FromROSRobot(req.robotid);
01068 ControllerBasePtr pcontroller = RaveCreateController(GetEnv(),req.controllername);
01069 if( !pcontroller ) {
01070 return false;
01071 }
01072 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
01073 return probot->SetController(pcontroller,req.indices, req.controltransformation);
01074 }
01075
01076 bool robot_getactivevalues_srv(openraveros::robot_getactivevalues::Request& req, openraveros::robot_getactivevalues::Response& res)
01077 {
01078 RobotBasePtr probot = _FromROSRobot(req.robotid);
01079 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
01080
01081 if( req.indices.size() > 0 ) {
01082 vector<dReal> vtemp;
01083 probot->GetActiveDOFValues(vtemp);
01084
01085 res.values.resize(req.indices.size());
01086 for(size_t i = 0; i < req.indices.size(); ++i) {
01087 if( req.indices[i] >= vtemp.size() )
01088 return false;
01089 res.values[i] = vtemp[req.indices[i]];
01090 }
01091 }
01092 else {
01093 vector<dReal> vtemp;
01094 probot->GetActiveDOFValues(vtemp);
01095
01096 res.values.resize(vtemp.size());
01097 for(size_t i = 0; i < res.values.size(); ++i)
01098 res.values[i] = vtemp[i];
01099 }
01100
01101 return true;
01102 }
01103
01104 bool robot_sensorgetdata_srv(openraveros::robot_sensorgetdata::Request& req, openraveros::robot_sensorgetdata::Response& res)
01105 {
01106 RobotBasePtr probot = _FromROSRobot(req.robotid);
01107 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
01108 if( req.sensorindex >= probot->GetAttachedSensors().size() )
01109 return false;
01110
01111 SensorBasePtr psensor = probot->GetAttachedSensors().at(req.sensorindex)->GetSensor();
01112 if( !psensor )
01113 return false;
01114
01115 SensorBase::SensorDataPtr pdata = psensor->CreateSensorData();
01116 if( !pdata ) {
01117 RAVELOG_ERRORA(str(boost::format("Robot %s, failed to create sensor %s data\n")%probot->GetName()%probot->GetAttachedSensors()[req.sensorindex]->GetName()));
01118 return false;
01119 }
01120
01121 if( !psensor->GetSensorData(pdata) ) {
01122 RAVELOG_ERRORA(str(boost::format("Robot %s, failed to get sensor %s data\n")%probot->GetName()%probot->GetAttachedSensors().at(req.sensorindex)->GetName()));
01123 return false;
01124 }
01125
01126
01127 switch(pdata->GetType()) {
01128 case SensorBase::ST_Laser: {
01129 res.type = "laser";
01130 boost::shared_ptr<SensorBase::LaserSensorData> plaserdata = boost::static_pointer_cast<SensorBase::LaserSensorData>(pdata);
01131 int index;
01132
01133 res.laserrange.resize(3*plaserdata->ranges.size()); index = 0;
01134 FOREACH(itpos, plaserdata->ranges) {
01135 res.laserrange[3*index+0] = itpos->x;
01136 res.laserrange[3*index+1] = itpos->y;
01137 res.laserrange[3*index+2] = itpos->z;
01138 ++index;
01139 }
01140
01141 res.laserpos.resize(3*plaserdata->positions.size()); index = 0;
01142 FOREACH(itpos, plaserdata->positions) {
01143 res.laserpos[3*index+0] = itpos->x;
01144 res.laserpos[3*index+1] = itpos->y;
01145 res.laserpos[3*index+2] = itpos->z;
01146 ++index;
01147 }
01148
01149 res.laserint.resize(plaserdata->intensity.size()); index = 0;
01150 FOREACH(itint, plaserdata->intensity)
01151 res.laserint[index++] = *itint;
01152
01153 break;
01154 }
01155 case SensorBase::ST_Camera: {
01156 res.type = "camera";
01157 boost::shared_ptr<SensorBase::CameraSensorData> pcameradata = boost::static_pointer_cast<SensorBase::CameraSensorData>(pdata);
01158
01159 if( psensor->GetSensorGeometry()->GetType() != SensorBase::ST_Camera ) {
01160 RAVELOG_WARNA("sensor geometry not a camera type\n");
01161 return false;
01162 }
01163
01164 boost::shared_ptr<SensorBase::CameraGeomData> pgeom = boost::static_pointer_cast<SensorBase::CameraGeomData>(psensor->GetSensorGeometry());
01165 if( (int)pcameradata->vimagedata.size() != pgeom->width*pgeom->height*3 ) {
01166 RAVELOG_WARNA("image data wrong size %d != %d\n", pcameradata->vimagedata.size(), pgeom->width*pgeom->height*3);
01167 return false;
01168 }
01169
01170 res.caminfo.width = pgeom->width;
01171 res.caminfo.height = pgeom->height;
01172 for(int i = 0; i < 5; ++i)
01173 res.caminfo.D[i] = 0;
01174 res.caminfo.K[0] = pgeom->KK.fx; res.caminfo.K[1] = 0; res.caminfo.K[2] = pgeom->KK.cx;
01175 res.caminfo.K[3] = 0; res.caminfo.K[4] = pgeom->KK.fy; res.caminfo.K[5] = pgeom->KK.cy;
01176 res.caminfo.K[6] = 0; res.caminfo.K[7] = 0; res.caminfo.K[8] = 1;
01177
01178 TransformMatrix tKK;
01179 for(int i = 0; i < 3; ++i) {
01180 tKK.m[4*i+0] = res.caminfo.K[3*i+0];
01181 tKK.m[4*i+1] = res.caminfo.K[3*i+1];
01182 tKK.m[4*i+2] = res.caminfo.K[3*i+2];
01183 }
01184
01185 TransformMatrix tP = tKK * pcameradata->__trans.inverse();
01186
01187 res.caminfo.R[0] = 1; res.caminfo.R[1] = 0; res.caminfo.R[2] = 0;
01188 res.caminfo.R[3] = 0; res.caminfo.R[4] = 1; res.caminfo.R[5] = 0;
01189 res.caminfo.R[6] = 0; res.caminfo.R[7] = 0; res.caminfo.R[8] = 1;
01190
01191 for(int i = 0; i < 3; ++i) {
01192 res.caminfo.P[4*i+0] = tP.m[4*i+0];
01193 res.caminfo.P[4*i+1] = tP.m[4*i+1];
01194 res.caminfo.P[4*i+2] = tP.m[4*i+2];
01195 res.caminfo.P[4*i+3] = tP.trans[i];
01196 }
01197
01198 res.camimage.header.stamp = ros::Time(pcameradata->__stamp/1000000,(uint32_t)(1000*(pcameradata->__stamp%1000000)));
01199 res.camimage.width = pgeom->width;
01200 res.camimage.height = pgeom->height;
01201 res.camimage.step = pgeom->width * 3;
01202
01203 res.camimage.data = pcameradata->vimagedata;
01204 break;
01205 }
01206 default:
01207 RAVELOG_ERRORA("sensor type not serialized\n");
01208 }
01209
01210 return true;
01211 }
01212
01213 bool robot_sensorsend_srv(openraveros::robot_sensorsend::Request& req, openraveros::robot_sensorsend::Response& res)
01214 {
01215 RobotBasePtr probot = _FromROSRobot(req.robotid);
01216 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
01217 RobotBase::AttachedSensorPtr sensor = probot->GetAttachedSensors().at(req.sensorindex);
01218
01219 stringstream sout;
01220 stringstream sin;
01221 sin << req.cmd << " " << req.args;
01222 if( sensor->GetSensor()->SendCommand(sout,sin)) {
01223 res.out = sout.str();
01224 return true;
01225 }
01226
01227 RAVELOG_ERROR(str(boost::format("Robot %s sensor %d failed: \"%s\"\n")%probot->GetName()%req.sensorindex%req.cmd));
01228 return false;
01229 }
01230
01231 bool robot_setactivedofs_srv(openraveros::robot_setactivedofs::Request& req, openraveros::robot_setactivedofs::Response& res)
01232 {
01233 RobotBasePtr probot = _FromROSRobot(req.robotid);
01234 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
01235 _FromROSActiveDOFs(probot, req.active);
01236 return true;
01237 }
01238
01239 bool robot_setactivemanipulator_srv(openraveros::robot_setactivemanipulator::Request& req, openraveros::robot_setactivemanipulator::Response& res)
01240 {
01241 RobotBasePtr probot = _FromROSRobot(req.robotid);
01242 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
01243 probot->SetActiveManipulator(req.manip);
01244 return true;
01245 }
01246
01247 bool robot_setactivevalues_srv(openraveros::robot_setactivevalues::Request& req, openraveros::robot_setactivevalues::Response& res)
01248 {
01249 RobotBasePtr probot = _FromROSRobot(req.robotid);
01250 if( probot->GetActiveDOF() == 0 ) {
01251 return false;
01252 }
01253
01254 EnvironmentMutex::scoped_lock lock(GetEnv()->GetMutex());
01255 vector<dReal> vvalues;
01256
01257 if( req.indices.size() > 0 ) {
01258 if( req.indices.size() != req.values.size() ) {
01259 throw OPENRAVE_EXCEPTION_FORMAT("indices (%d) different size than joint values (%d)", req.indices.size()%req.values.size(), ORE_InvalidArguments);
01260 }
01261
01262 probot->GetActiveDOFValues(vvalues);
01263 for(size_t i = 0; i < req.indices.size(); ++i) {
01264 vvalues[req.indices[i]] = req.values[i];
01265 }
01266 }
01267 else {
01268 if( probot->GetActiveDOF() != (int)req.values.size() ) {
01269 throw OPENRAVE_EXCEPTION_FORMAT("body dof (%d) not equal to values (%d)", probot->GetDOF()%req.values.size(), ORE_InvalidArguments);
01270 }
01271
01272 vvalues.reserve(req.values.size());
01273 FOREACHC(it,req.values) {
01274 vvalues.push_back(*it);
01275 }
01276 }
01277
01278 probot->SetActiveDOFValues(vvalues, true);
01279
01280 if( !!probot->GetController() ) {
01281 probot->GetDOFValues(vvalues);
01282 probot->GetController()->SetDesired(vvalues);
01283 }
01284
01285 return true;
01286 }
01287
01288 bool robot_starttrajectory_srv(openraveros::robot_starttrajectory::Request& req, openraveros::robot_starttrajectory::Response& res)
01289 {
01290 RobotBasePtr probot = _FromROSRobot(req.robotid);
01291 OPENRAVE_ASSERT_FORMAT(!!probot,"robot id %d",req.robotid,ORE_InvalidArguments);
01292 return probot->GetController()->SetPath(_FromROSTrajectory(req.trajectory));
01293 }
01294
01295 private:
01296 void _FromROSActiveDOFs(RobotBasePtr probot, const openraveros::ActiveDOFs& active)
01297 {
01298 probot->SetActiveDOFs(active.indices, active.affine, Vector(active.rotationaxis[0], active.rotationaxis[1], active.rotationaxis[2]));
01299 }
01300
01301 void _GetROSActiveDOFs(RobotBaseConstPtr probot, openraveros::ActiveDOFs& active)
01302 {
01303 active.affine = probot->GetAffineDOF();
01304 active.indices = probot->GetActiveDOFIndices();
01305 active.rotationaxis[0] = probot->GetAffineRotationAxis().x;
01306 active.rotationaxis[1] = probot->GetAffineRotationAxis().y;
01307 active.rotationaxis[2] = probot->GetAffineRotationAxis().z;
01308 }
01309
01310 RobotBasePtr _FromROSRobot(int robotid) {
01311 RobotBasePtr probot = RaveInterfaceCast<RobotBase>(GetEnv()->GetBodyFromEnvironmentId(robotid));
01312 if(!probot) {
01313 RAVELOG_WARN(str(boost::format("robot id %d not found")%robotid));
01314 }
01315 return probot;
01316 }
01317
01318 KinBodyPtr _FromROSBody(int bodyid) {
01319 KinBodyPtr pbody = GetEnv()->GetBodyFromEnvironmentId(bodyid);
01320 if(!pbody) {
01321 RAVELOG_WARN(str(boost::format("body id %d not found")%bodyid));
01322 }
01323 return pbody;
01324 }
01325
01326 void _GetROSConfigurationSpecification(openraveros::ConfigurationSpecification& rosspec, const ConfigurationSpecification& spec)
01327 {
01328 rosspec.groups.resize(spec._vgroups.size());
01329 for(size_t i = 0; i < spec._vgroups.size(); ++i) {
01330 rosspec.groups[i].name = spec._vgroups[i].name;
01331 rosspec.groups[i].interpolation = spec._vgroups[i].interpolation;
01332 rosspec.groups[i].dof = spec._vgroups[i].dof;
01333 rosspec.groups[i].offset = spec._vgroups[i].offset;
01334 }
01335 }
01336
01337 void _FromROSConfigurationSpecification(ConfigurationSpecification& spec, const openraveros::ConfigurationSpecification& rosspec)
01338 {
01339 spec._vgroups.resize(rosspec.groups.size());
01340 for(size_t i = 0; i < rosspec.groups.size(); ++i) {
01341 spec._vgroups[i].name = rosspec.groups[i].name;
01342 spec._vgroups[i].interpolation = rosspec.groups[i].interpolation;
01343 spec._vgroups[i].dof = rosspec.groups[i].dof;
01344 spec._vgroups[i].offset = rosspec.groups[i].offset;
01345 }
01346 }
01347
01348 TrajectoryBasePtr _FromROSTrajectory(const openraveros::Trajectory& rostraj)
01349 {
01350 TrajectoryBasePtr traj = RaveCreateTrajectory(GetEnv(),rostraj.xmlid);
01351 ConfigurationSpecification spec;
01352 _FromROSConfigurationSpecification(spec,rostraj.spec);
01353 traj->Init(spec);
01354 traj->Insert(0,rostraj.points);
01355 return traj;
01356 }
01357
01358 void _GetROSTrajectory(openraveros::Trajectory& rostraj, TrajectoryBaseConstPtr traj)
01359 {
01360 rostraj.xmlid = traj->GetXMLId();
01361 _GetROSConfigurationSpecification(rostraj.spec, traj->GetConfigurationSpecification());
01362 traj->GetWaypoints(0,traj->GetNumWaypoints(),rostraj.points);
01363 }
01364
01365 openraveros::AffineTransformMatrix _GetROSAffineTransform(const TransformMatrix& tm)
01366 {
01367 openraveros::AffineTransformMatrix am;
01368 am.m[0] = tm.m[0]; am.m[3] = tm.m[1]; am.m[6] = tm.m[2];
01369 am.m[1] = tm.m[4]; am.m[4] = tm.m[5]; am.m[7] = tm.m[6];
01370 am.m[2] = tm.m[8]; am.m[5] = tm.m[9]; am.m[8] = tm.m[10];
01371 am.m[9] = tm.trans.x; am.m[10] = tm.trans.y; am.m[11] = tm.trans.z;
01372 return am;
01373 }
01374
01375 TransformMatrix _FromROSAffineTransform(const openraveros::AffineTransformMatrix& am)
01376 {
01377 TransformMatrix tm;
01378 tm.m[0] = am.m[0]; tm.m[1] = am.m[3]; tm.m[2] = am.m[6];
01379 tm.m[4] = am.m[1]; tm.m[5] = am.m[4]; tm.m[6] = am.m[7];
01380 tm.m[8] = am.m[2]; tm.m[9] = am.m[5]; tm.m[10] = am.m[8];
01381 tm.trans.x = am.m[9]; tm.trans.y = am.m[10]; tm.trans.z = am.m[11];
01382 return tm;
01383 }
01384
01385 openraveros::AffineTransformMatrix _GetROSAffineIdentity()
01386 {
01387 openraveros::AffineTransformMatrix am;
01388 am.m[0] = 1; am.m[3] = 0; am.m[6] = 0; am.m[9] = 0;
01389 am.m[1] = 0; am.m[4] = 1; am.m[7] = 0; am.m[10] = 0;
01390 am.m[2] = 0; am.m[5] = 0; am.m[8] = 1; am.m[11] = 0;
01391 return am;
01392 }
01393
01394 void _GetROSBodyInfo(KinBodyConstPtr pbody, openraveros::BodyInfo& info, uint32_t options)
01395 {
01396 info.bodyid = pbody->GetEnvironmentId();
01397 info.transform = _GetROSAffineTransform(pbody->GetTransform());
01398 info.enabled = pbody->IsEnabled();
01399 info.dof = pbody->GetDOF();
01400
01401 if( options & openraveros::BodyInfo::Req_JointValues ) {
01402 vector<dReal> vvalues; pbody->GetDOFValues(vvalues);
01403 info.jointvalues.resize(vvalues.size());
01404 for(size_t i = 0; i < vvalues.size(); ++i)
01405 info.jointvalues[i] = vvalues[i];
01406 }
01407 if( options & openraveros::BodyInfo::Req_Links ) {
01408 vector<Transform> vlinks; pbody->GetLinkTransformations(vlinks);
01409 info.links.resize(vlinks.size());
01410 for(size_t i = 0; i < vlinks.size(); ++i)
01411 info.links[i] = _GetROSAffineTransform(vlinks[i]);
01412 }
01413 if( options & openraveros::BodyInfo::Req_LinkNames ) {
01414 info.linknames.resize(pbody->GetLinks().size());
01415 for(size_t i = 0; i < pbody->GetLinks().size(); ++i)
01416 info.linknames[i] = pbody->GetLinks().at(i)->GetName();
01417 }
01418 if( options & openraveros::BodyInfo::Req_JointLimits ) {
01419 vector<dReal> vlower, vupper;
01420 pbody->GetDOFLimits(vlower,vupper);
01421 BOOST_ASSERT( vlower.size() == vupper.size() );
01422 info.lowerlimit.resize(vlower.size());
01423 info.upperlimit.resize(vupper.size());
01424 for(size_t i = 0; i < vlower.size(); ++i) {
01425 info.lowerlimit[i] = vlower[i];
01426 info.upperlimit[i] = vupper[i];
01427 }
01428 }
01429 if( options & openraveros::BodyInfo::Req_Names ) {
01430 info.filename = pbody->GetXMLFilename();
01431 info.name = pbody->GetName();
01432 info.type = pbody->GetXMLId();
01433 }
01434 if( options & openraveros::BodyInfo::Req_JointNames ) {
01435 info.jointnames.resize(pbody->GetJoints().size());
01436 for(size_t i = 0; i < pbody->GetJoints().size(); ++i)
01437 info.jointnames[i] = pbody->GetJoints().at(i)->GetName();
01438 }
01439 }
01440
01441 void _GetROSRobotInfo(RobotBasePtr probot, openraveros::RobotInfo& info, uint32_t options)
01442 {
01443 _GetROSBodyInfo(probot,info.bodyinfo,options);
01444
01445 info.activedof = probot->GetActiveDOF();
01446 info.activemanip = probot->GetActiveManipulatorIndex();
01447
01448 if( options & openraveros::RobotInfo::Req_Manipulators ) {
01449 info.manips.resize(probot->GetManipulators().size());
01450 int index = 0;
01451 FOREACHC(itmanip, probot->GetManipulators()) {
01452 openraveros::Manipulator& rosmanip = info.manips[index++];
01453 rosmanip.baselink = !!(*itmanip)->GetBase() ? (*itmanip)->GetBase()->GetIndex() : -1;
01454 rosmanip.eelink = !!(*itmanip)->GetEndEffector() ? (*itmanip)->GetEndEffector()->GetIndex() : -1;
01455 rosmanip.tgrasp = _GetROSAffineTransform((*itmanip)->GetTransform());
01456
01457 rosmanip.handjoints.resize((*itmanip)->GetGripperIndices().size());
01458 std::copy((*itmanip)->GetGripperIndices().begin(),(*itmanip)->GetGripperIndices().end(),rosmanip.handjoints.begin());
01459
01460 rosmanip.armjoints.resize((*itmanip)->GetArmIndices().size());
01461 std::copy((*itmanip)->GetArmIndices().begin(),(*itmanip)->GetArmIndices().end(),rosmanip.armjoints.begin());
01462 if( !!(*itmanip)->GetIkSolver() ) {
01463 rosmanip.iksolvername = (*itmanip)->GetIkSolver()->GetXMLId();
01464 }
01465 rosmanip.name = (*itmanip)->GetName();
01466 }
01467 }
01468 if( options & openraveros::RobotInfo::Req_Sensors ) {
01469 info.sensors.resize(probot->GetAttachedSensors().size()); int index = 0;
01470 FOREACHC(its, probot->GetAttachedSensors()) {
01471 openraveros::AttachedSensor& rossensor = info.sensors[index++];
01472 rossensor.name = (*its)->GetName();
01473 rossensor.attachedlink = (*its)->GetAttachingLink()->GetIndex();
01474 rossensor.trelative = _GetROSAffineTransform((*its)->GetRelativeTransform());
01475
01476 if( !!(*its)->GetSensor() ) {
01477 rossensor.tglobal = _GetROSAffineTransform((*its)->GetSensor()->GetTransform());
01478 rossensor.type = (*its)->GetSensor()->GetXMLId();
01479 }
01480 else {
01481 rossensor.tglobal = _GetROSAffineIdentity();
01482 rossensor.type = "";
01483 }
01484 }
01485 }
01486 if( options & openraveros::RobotInfo::Req_ActiveDOFs ) {
01487 _GetROSActiveDOFs(probot, info.active);
01488 }
01489 if( options & openraveros::RobotInfo::Req_ActiveLimits ) {
01490 vector<dReal> vlower, vupper;
01491 probot->GetActiveDOFLimits(vlower,vupper);
01492 BOOST_ASSERT( vlower.size() == vupper.size() );
01493 info.activelowerlimit.resize(vlower.size());
01494 info.activeupperlimit.resize(vupper.size());
01495 for(size_t i = 0; i < vlower.size(); ++i) {
01496 info.activelowerlimit[i] = vlower[i];
01497 info.activeupperlimit[i] = vupper[i];
01498 }
01499 }
01500 }
01501
01502 boost::function<bool(const string&,const string&)> _setviewer;
01503 map<int, PlannerBasePtr > _mapplanners;
01504 map<int, ModuleBasePtr > _mapmodules;
01505 map<int, GraphHandlePtr > _mapFigureIds;
01506 int _nNextFigureId, _nNextPlannerId, _nNextModuleId;
01507 float _fSimulationTimestep;
01508 bool _bDestroyThreads, _bWorking;
01509
01511 ViewerBasePtr _pviewer;
01512 boost::thread _threadviewer;
01513 boost::mutex _mutexViewer, _mutexModules;
01514 boost::condition _conditionViewer;
01515
01517 boost::thread _workerthread;
01518 boost::mutex _mutexWorker;
01519 list< boost::function<void()> > _listWorkers;
01520 boost::condition _conditionWorkers, _condHasWork;
01521 int _iWorkerId;
01522
01523
01524 boost::shared_ptr<ros::NodeHandle> _ros;
01525 boost::thread _threadros;
01526 std::map<std::string,ros::ServiceServer> _mapservices;
01527 };
01528
01529 ModuleBasePtr CreateROSServer(EnvironmentBasePtr penv, std::istream& sinput)
01530 {
01531 return ModuleBasePtr(new ROSServer(penv,sinput));
01532 }