00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00035 #include "openraveros.h"
00036
00037 #include <openraveros/openrave_session.h>
00038
00039 using namespace ros;
00040
00041 #define REFLECT_SERVICE(srvname) \
00042 bool srvname ## _srv(srvname::Request& req, srvname::Response& res) \
00043 { \
00044 SessionState state = getstate(req); \
00045 if( !state._pserver ) { \
00046 RAVELOG_INFOA("failed to find session for service %s\n", # srvname); \
00047 return false; \
00048 } \
00049 return state._pserver->srvname ## _srv(req,res); \
00050 }
00051
00052 class SessionServer : public boost::enable_shared_from_this<SessionServer>
00053 {
00054 class SessionState
00055 {
00056 public:
00057 SessionState() {
00058 }
00059 SessionState(boost::shared_ptr<SessionServer> psessionserver) : _psessionserver(psessionserver) {
00060 }
00061 virtual ~SessionState() {
00062 _pserver.reset();
00063 _penv.reset();
00064 }
00065
00066 boost::shared_ptr<SessionServer> _psessionserver;
00067 boost::shared_ptr<ROSServer> _pserver;
00068 EnvironmentBasePtr _penv;
00069 };
00070
00071 string _sessionname;
00072 public:
00073 SessionServer() : _ok(true) {
00074 _pParentEnvironment = RaveCreateEnvironment();
00075 }
00076 virtual ~SessionServer() {
00077 Destroy();
00078 }
00079
00080 bool Init()
00081 {
00082 _ros.reset(new ros::NodeHandle());
00083
00084 _srvSession = _ros->advertiseService("openrave_session",&SessionServer::session_callback,shared_from_this());
00085 _sessionname = _ros->resolveName("openrave_session");
00086
00087
00088 _mapservices["body_destroy"] = _ros->advertiseService("body_destroy",&SessionServer::body_destroy_srv,shared_from_this());
00089 _mapservices["body_enable"] = _ros->advertiseService("body_enable",&SessionServer::body_enable_srv,shared_from_this());
00090 _mapservices["body_getaabb"] = _ros->advertiseService("body_getaabb",&SessionServer::body_getaabb_srv,shared_from_this());
00091 _mapservices["body_getaabbs"] = _ros->advertiseService("body_getaabbs",&SessionServer::body_getaabbs_srv,shared_from_this());
00092 _mapservices["body_getdof"] = _ros->advertiseService("body_getdof",&SessionServer::body_getdof_srv,shared_from_this());
00093 _mapservices["body_getjointvalues"] = _ros->advertiseService("body_getjointvalues",&SessionServer::body_getjointvalues_srv,shared_from_this());
00094 _mapservices["body_setjointvalues"] = _ros->advertiseService("body_setjointvalues",&SessionServer::body_setjointvalues_srv,shared_from_this());
00095 _mapservices["body_settransform"] = _ros->advertiseService("body_settransform",&SessionServer::body_settransform_srv,shared_from_this());
00096 _mapservices["env_checkcollision"] = _ros->advertiseService("env_checkcollision",&SessionServer::env_checkcollision_srv,shared_from_this());
00097 _mapservices["env_closefigures"] = _ros->advertiseService("env_closefigures",&SessionServer::env_closefigures_srv,shared_from_this());
00098 _mapservices["env_createbody"] = _ros->advertiseService("env_createbody",&SessionServer::env_createbody_srv,shared_from_this());
00099 _mapservices["env_createplanner"] = _ros->advertiseService("env_createplanner",&SessionServer::env_createplanner_srv,shared_from_this());
00100 _mapservices["env_createproblem"] = _ros->advertiseService("env_createproblem",&SessionServer::env_createproblem_srv,shared_from_this());
00101 _mapservices["env_createrobot"] = _ros->advertiseService("env_createrobot",&SessionServer::env_createrobot_srv,shared_from_this());
00102 _mapservices["env_destroyproblem"] = _ros->advertiseService("env_destroyproblem",&SessionServer::env_destroyproblem_srv,shared_from_this());
00103 _mapservices["env_getbodies"] = _ros->advertiseService("env_getbodies",&SessionServer::env_getbodies_srv,shared_from_this());
00104 _mapservices["env_getbody"] = _ros->advertiseService("env_getbody",&SessionServer::env_getbody_srv,shared_from_this());
00105 _mapservices["env_getrobots"] = _ros->advertiseService("env_getrobots",&SessionServer::env_getrobots_srv,shared_from_this());
00106 _mapservices["env_loadplugin"] = _ros->advertiseService("env_loadplugin",&SessionServer::env_loadplugin_srv,shared_from_this());
00107 _mapservices["env_loadscene"] = _ros->advertiseService("env_loadscene",&SessionServer::env_loadscene_srv,shared_from_this());
00108 _mapservices["env_plot"] = _ros->advertiseService("env_plot",&SessionServer::env_plot_srv,shared_from_this());
00109 _mapservices["env_raycollision"] = _ros->advertiseService("env_raycollision",&SessionServer::env_raycollision_srv,shared_from_this());
00110 _mapservices["env_set"] = _ros->advertiseService("env_set",&SessionServer::env_set_srv,shared_from_this());
00111 _mapservices["env_triangulate"] = _ros->advertiseService("env_triangulate",&SessionServer::env_triangulate_srv,shared_from_this());
00112 _mapservices["env_wait"] = _ros->advertiseService("env_wait",&SessionServer::env_wait_srv,shared_from_this());
00113 _mapservices["planner_init"] = _ros->advertiseService("planner_init",&SessionServer::planner_init_srv,shared_from_this());
00114 _mapservices["planner_plan"] = _ros->advertiseService("planner_plan",&SessionServer::planner_plan_srv,shared_from_this());
00115 _mapservices["problem_sendcommand"] = _ros->advertiseService("problem_sendcommand",&SessionServer::problem_sendcommand_srv,shared_from_this());
00116 _mapservices["robot_controllersend"] = _ros->advertiseService("robot_controllersend",&SessionServer::robot_controllersend_srv,shared_from_this());
00117 _mapservices["robot_controllerset"] = _ros->advertiseService("robot_controllerset",&SessionServer::robot_controllerset_srv,shared_from_this());
00118 _mapservices["robot_getactivevalues"] = _ros->advertiseService("robot_getactivevalues",&SessionServer::robot_getactivevalues_srv,shared_from_this());
00119 _mapservices["robot_sensorgetdata"] = _ros->advertiseService("robot_sensorgetdata",&SessionServer::robot_sensorgetdata_srv,shared_from_this());
00120 _mapservices["robot_sensorsend"] = _ros->advertiseService("robot_sensorsend",&SessionServer::robot_sensorsend_srv,shared_from_this());
00121 _mapservices["robot_setactivedofs"] = _ros->advertiseService("robot_setactivedofs",&SessionServer::robot_setactivedofs_srv,shared_from_this());
00122 _mapservices["robot_setactivemanipulator"] = _ros->advertiseService("robot_setactivemanipulator",&SessionServer::robot_setactivemanipulator_srv,shared_from_this());
00123 _mapservices["robot_setactivevalues"] = _ros->advertiseService("robot_setactivevalues",&SessionServer::robot_setactivevalues_srv,shared_from_this());
00124 _mapservices["robot_starttrajectory"] = _ros->advertiseService("robot_starttrajectory",&SessionServer::robot_starttrajectory_srv,shared_from_this());
00125
00126 _ok = true;
00127 _threadviewer = boost::thread(boost::bind(&SessionServer::ViewerThread, this));
00128 return true;
00129 }
00130
00131 void Destroy()
00132 {
00133 shutdown();
00134 _srvSession.shutdown();
00135 _mapservices.clear();
00136 _ros.reset();
00137 _threadviewer.join();
00138 }
00139
00140 virtual void shutdown()
00141 {
00142 _ok = false;
00143 boost::mutex::scoped_lock lockcreate(_mutexViewer);
00144 if( !!_penvViewer ) {
00145 if( !!_pviewer ) {
00146 _penvViewer->Remove(_pviewer);
00147 }
00148 }
00149 }
00150
00151 bool SetViewer(EnvironmentBasePtr penv, const string& viewer, const string& title)
00152 {
00153 boost::mutex::scoped_lock lock(_mutexViewer);
00154
00155
00156 if( !!_penvViewer ) {
00157 if( !!_pviewer ) {
00158 _penvViewer->Remove(_pviewer);
00159 }
00160 _conditionViewer.wait(lock);
00161 }
00162
00163 ROS_ASSERT(!_penvViewer);
00164
00165 _strviewertitle = title;
00166 _strviewer = viewer;
00167 if( viewer.size() == 0 || !penv )
00168 return false;
00169
00170 _penvViewer = penv;
00171 _conditionViewer.wait(lock);
00172 return !!_pviewer;
00173 }
00174
00175 EnvironmentBasePtr GetParentEnvironment() const {
00176 return _pParentEnvironment;
00177 }
00178
00179 protected:
00180
00181 boost::shared_ptr<ros::NodeHandle> _ros;
00182 ros::ServiceServer _srvSession;
00183 map<string,ros::ServiceServer> _mapservices;
00184
00185 map<int,SessionState> _mapsessions;
00186 boost::mutex _mutexsession;
00187 EnvironmentBasePtr _pParentEnvironment;
00188
00189
00190 ViewerBasePtr _pviewer;
00191 boost::thread _threadviewer;
00192 boost::mutex _mutexViewer;
00193 boost::condition _conditionViewer;
00194 EnvironmentBasePtr _penvViewer;
00195 string _strviewer, _strviewertitle;
00196
00197 bool _ok;
00198
00199 virtual void ViewerThread()
00200 {
00201 while(_ok) {
00202
00203 {
00204 usleep(1000);
00205 boost::mutex::scoped_lock lockcreate(_mutexViewer);
00206 if( _strviewer.size() == 0 || !_penvViewer ) {
00207 continue;
00208 }
00209
00210 _pviewer = RaveCreateViewer(_penvViewer,_strviewer);
00211 if( !!_pviewer ) {
00212 _penvViewer->AddViewer(_pviewer);
00213 _pviewer->ViewerSetSize(1024,768);
00214 }
00215
00216 if( !_pviewer )
00217 _penvViewer.reset();
00218
00219 _conditionViewer.notify_all();
00220
00221 if( !_pviewer )
00222 continue;
00223 }
00224
00225 if( _strviewertitle.size() > 0 )
00226 _pviewer->ViewerSetTitle(_strviewertitle);
00227
00228 _pviewer->main();
00229
00230 boost::mutex::scoped_lock lockcreate(_mutexViewer);
00231 RAVELOG_DEBUGA("destroying viewer\n");
00232 ROS_ASSERT(_penvViewer == _pviewer->GetEnv());
00233 if( !!_pviewer ) {
00234 _penvViewer->Remove(_pviewer);
00235 }
00236 _pviewer.reset();
00237 usleep(100000);
00238 _penvViewer.reset();
00239 _conditionViewer.notify_all();
00240 }
00241 }
00242
00243 template <class MReq>
00244 SessionState getstate(const MReq& req)
00245 {
00246 if( !req.__connection_header )
00247 return SessionState(shared_from_this());
00248
00249 ros::M_string::const_iterator it = req.__connection_header->find(_sessionname);
00250 if( it == req.__connection_header->end() )
00251 return SessionState(shared_from_this());
00252
00253 boost::mutex::scoped_lock lock(_mutexsession);
00254
00255 int sessionid = 0;
00256 stringstream ss(it->second); ss >> sessionid;
00257 if( _mapsessions.find(sessionid) == _mapsessions.end() )
00258 return SessionState(shared_from_this());
00259 return _mapsessions[sessionid];
00260 }
00261
00262 bool session_callback(openrave_session::Request& req, openrave_session::Response& res)
00263 {
00264 if( req.sessionid != 0 ) {
00265 boost::mutex::scoped_lock lock(_mutexsession);
00266
00267 if( req.sessionid == -1 ) {
00268
00269 RAVELOG_DEBUGA("destroying all sessions\n");
00270 _mapsessions.clear();
00271 }
00272 else {
00273
00274 if( _mapsessions.find(req.sessionid) == _mapsessions.end() )
00275 return false;
00276
00277 _mapsessions.erase(req.sessionid);
00278 RAVELOG_INFOA("destroyed openrave session: %d\n", req.sessionid);
00279 }
00280
00281 return true;
00282 }
00283
00284 SessionState state(shared_from_this());
00285 int id = rand();
00286 {
00287 boost::mutex::scoped_lock lock(_mutexsession);
00288 while(id == 0 || _mapsessions.find(id) != _mapsessions.end())
00289 id = rand();
00290 _mapsessions[id] = state;
00291 }
00292
00293 if( req.clone_sessionid ) {
00294
00295 SessionState clonestate(shared_from_this());
00296 {
00297 boost::mutex::scoped_lock lock(_mutexsession);
00298 clonestate = _mapsessions[req.clone_sessionid];
00299 }
00300
00301 if( !clonestate._penv )
00302 RAVELOG_INFOA("failed to find session %d\n", req.clone_sessionid);
00303 else
00304 state._penv = clonestate._penv->CloneSelf(req.clone_options);
00305 }
00306
00307 if( !state._penv ) {
00308
00309 RAVELOG_DEBUGA("cloning from parent\n");
00310 state._penv = _pParentEnvironment->CloneSelf(0);
00311 }
00312
00313 state._pserver.reset(new ROSServer(id, boost::bind(&SessionServer::SetViewer,shared_from_this(),state._penv,_1,_2), state._penv, req.physicsengine, req.collisionchecker, req.viewer));
00314 state._penv->LoadProblem(state._pserver,"");
00315
00316 boost::mutex::scoped_lock lock(_mutexsession);
00317 _mapsessions[id] = state;
00318 res.sessionid = id;
00319
00320 RAVELOG_INFOA("started openrave session: %d, total: %d\n", id, _mapsessions.size());
00321 return true;
00322 }
00323
00324 REFLECT_SERVICE(body_destroy)
00325 REFLECT_SERVICE(body_enable)
00326 REFLECT_SERVICE(body_getaabb)
00327 REFLECT_SERVICE(body_getaabbs)
00328 REFLECT_SERVICE(body_getdof)
00329 REFLECT_SERVICE(body_getjointvalues)
00330 REFLECT_SERVICE(body_setjointvalues)
00331 REFLECT_SERVICE(body_settransform)
00332 REFLECT_SERVICE(env_checkcollision)
00333 REFLECT_SERVICE(env_closefigures)
00334 REFLECT_SERVICE(env_createbody)
00335 REFLECT_SERVICE(env_createplanner)
00336 REFLECT_SERVICE(env_createproblem)
00337 REFLECT_SERVICE(env_createrobot)
00338 REFLECT_SERVICE(env_destroyproblem)
00339 REFLECT_SERVICE(env_getbodies)
00340 REFLECT_SERVICE(env_getbody)
00341 REFLECT_SERVICE(env_getrobots)
00342 REFLECT_SERVICE(env_loadplugin)
00343 REFLECT_SERVICE(env_loadscene)
00344 REFLECT_SERVICE(env_plot)
00345 REFLECT_SERVICE(env_raycollision)
00346 REFLECT_SERVICE(env_set)
00347 REFLECT_SERVICE(env_triangulate)
00348 REFLECT_SERVICE(env_wait)
00349 REFLECT_SERVICE(planner_init)
00350 REFLECT_SERVICE(planner_plan)
00351 REFLECT_SERVICE(problem_sendcommand)
00352 REFLECT_SERVICE(robot_controllersend)
00353 REFLECT_SERVICE(robot_controllerset)
00354 REFLECT_SERVICE(robot_getactivevalues)
00355 REFLECT_SERVICE(robot_sensorgetdata)
00356 REFLECT_SERVICE(robot_sensorsend)
00357 REFLECT_SERVICE(robot_setactivedofs)
00358 REFLECT_SERVICE(robot_setactivemanipulator)
00359 REFLECT_SERVICE(robot_setactivevalues)
00360 REFLECT_SERVICE(robot_starttrajectory)
00361 };
00362
00363
00364 BOOST_STATIC_ASSERT((int)Clone_Bodies==(int)openrave_session::Request::CloneBodies);
00365 BOOST_STATIC_ASSERT((int)Clone_Viewer==(int)openrave_session::Request::CloneViewer);
00366 BOOST_STATIC_ASSERT((int)Clone_Simulation==(int)openrave_session::Request::CloneSimulation);
00367 BOOST_STATIC_ASSERT((int)Clone_RealControllers==(int)openrave_session::Request::CloneRealControllers);
00368
00369 BOOST_STATIC_ASSERT((int)ActiveDOFs::DOF_X==(int)RobotBase::DOF_X);
00370 BOOST_STATIC_ASSERT((int)ActiveDOFs::DOF_Y==(int)RobotBase::DOF_Y);
00371 BOOST_STATIC_ASSERT((int)ActiveDOFs::DOF_Z==(int)RobotBase::DOF_Z);
00372 BOOST_STATIC_ASSERT((int)ActiveDOFs::DOF_RotationAxis==(int)RobotBase::DOF_RotationAxis);
00373 BOOST_STATIC_ASSERT((int)ActiveDOFs::DOF_Rotation3D==(int)RobotBase::DOF_Rotation3D);
00374 BOOST_STATIC_ASSERT((int)ActiveDOFs::DOF_RotationQuat==(int)RobotBase::DOF_RotationQuat);
00375
00376 BOOST_STATIC_ASSERT((int)env_checkcollision::Request::CO_Distance==(int)CO_Distance);
00377 BOOST_STATIC_ASSERT((int)env_checkcollision::Request::CO_UseTolerance==(int)CO_UseTolerance);
00378 BOOST_STATIC_ASSERT((int)env_checkcollision::Request::CO_Contacts==(int)CO_Contacts);
00379 BOOST_STATIC_ASSERT((int)env_checkcollision::Request::CO_RayAnyHit==(int)CO_RayAnyHit);