rosserver.cpp
Go to the documentation of this file.
00001 // -*- coding: utf-8 -*-
00002 // Copyright (c) 2012 Rosen Diankov <rosen.diankov@gmail.com>
00003 //
00004 // Licensed under the Apache License, Version 2.0 (the "License");
00005 // you may not use this file except in compliance with the License.
00006 // You may obtain a copy of the License at
00007 //     http://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
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         // have to maintain a certain destruction order
00048         _threadviewer.join();
00049         _workerthread.join();
00050         _threadros.join();
00051 
00052         _bDestroyThreads = false;
00053         ModuleBase::Destroy();
00054     }
00055 
00056     virtual void Reset()
00057     {
00058         // destroy environment specific state: modules, planners, figures
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         // wait for worker thread to stop
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); // query every 1ms?
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             // transfer the current workers to a temporary list so
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(); // spin until quitmainloop is called
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(); // wait for the viewer
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     // services //
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             // if robot, should turn off any trajectory following
00406             RobotBasePtr probot = boost::static_pointer_cast<RobotBase>(pbody);
00407             if( !!probot->GetController() ) {
00408                 probot->GetDOFValues(vvalues); // reget the values since they'll go through the joint limits
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 // destroy everything
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             // add only one body
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             // add only one body
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             //if( bOneColor )
00765             figure = GetEnv()->drawtrimesh(&req.points[0],3*sizeof(req.points[0]), NULL, req.points.size()/9, vOneColor);
00766             //else
00767             //figure = GetEnv()->plot3(&req.points[0],req.points.size()/3,3*sizeof(req.points[0]),req.size,&req.colors[0], 0);
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         // fill with request
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         // serialize the data
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); // reget the values since they'll go through the joint limits
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     // ros service stuff
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


openraveros
Author(s): Rosen Diankov (rosen.diankov@gmail.com)
autogenerated on Sat Mar 23 2013 22:16:09