simple_session.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2008, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
00033  */
00034 
00035 // author: Rosen Diankov
00036 #include <ros/node_handle.h>
00037 #include <ros/session.h>
00038 #include <ros/master.h>
00039 #include <boost/thread/mutex.hpp>
00040 
00041 #include "roscpp_sessions/simple_session.h"
00042 #include "roscpp_sessions/set_variable.h"
00043 #include "roscpp_sessions/get_variable.h"
00044 #include "roscpp_sessions/add_variables.h"
00045 
00046 #include <map>
00047 
00048 using namespace std;
00049 using namespace ros;
00050 
00051 boost::shared_ptr<ros::NodeHandle> s_pmasternode;
00052 
00053 // keeps track of created variables
00054 class SimpleSessionInstance
00055 {
00056 public:
00057     void set_variable(const string& name, int val) { variables[name] = val; }
00058     int get_variable(const string& name) {
00059         ROS_ASSERT(variables.find(name)!=variables.end());
00060         return variables[name];
00061     }
00062     void add_variables(const string& result, const string& name1, const string& name2) {
00063         ROS_ASSERT(variables.find(name1)!=variables.end());
00064         ROS_ASSERT(variables.find(name2)!=variables.end());
00065         variables[result] = variables[name1] + variables[name2];
00066     }
00067 
00068 private:
00069     map<string,int> variables;
00070 };
00071 
00072 class SimpleSession
00073 {
00074     string _sessionname;
00075     ros::ServiceServer srv_simple_session;
00076     ros::ServiceServer srv_set_variable;
00077     ros::ServiceServer srv_get_variable;
00078     ros::ServiceServer srv_add_variables;
00079 public:
00080     SimpleSession()
00081     {
00082         srv_simple_session = s_pmasternode->advertiseService("simple_session",&SimpleSession::startsession,this);// ,1);
00083         _sessionname = s_pmasternode->resolveName("simple_session");
00084 
00085         // advertise persistent services, the protocol for these differs!
00086         srv_set_variable = s_pmasternode->advertiseService("set_variable",&SimpleSession::set_variable,this); //,-1);
00087         srv_get_variable = s_pmasternode->advertiseService("get_variable",&SimpleSession::get_variable,this); //,-1);
00088         srv_add_variables = s_pmasternode->advertiseService("add_variables",&SimpleSession::add_variables,this); //,-1);
00089     }
00090     virtual ~SimpleSession()
00091     {
00092         srv_simple_session.shutdown();
00093         srv_set_variable.shutdown();
00094         srv_get_variable.shutdown();
00095         srv_add_variables.shutdown();
00096         
00097     }
00098 
00099     template <class MReq>
00100     SimpleSessionInstance* getstate(const MReq& req)
00101     {
00102         if( !req.__connection_header )
00103             return NULL;
00104 
00105         ros::M_string::const_iterator it = req.__connection_header->find(_sessionname);
00106         if( it == req.__connection_header->end() ) {
00107             ROS_WARN("failed to find header key %s",_sessionname.c_str());
00108             return NULL;
00109         }
00110 
00111         boost::mutex::scoped_lock lock(map_mutex);
00112 
00113         int sessionid = atoi(it->second.c_str());
00114         if( mapsessions.find(sessionid) == mapsessions.end() ) {
00115             ROS_WARN("failed to find session id %d", sessionid);
00116             return NULL;
00117         }
00118         return mapsessions[sessionid].get();
00119     }
00120 
00121     bool startsession(roscpp_sessions::simple_session::Request& req, roscpp_sessions::simple_session::Response& res) {
00122         if( req.sessionid ) {
00123             // destroy
00124             int success = mapsessions.erase(req.sessionid)>0;
00125             cout << "terminate session: " << req.sessionid << ", success: " << success << endl;
00126         }
00127         else {
00128             // start a new session with id
00129             int id = rand();
00130             ROS_ASSERT( mapsessions.find(id) == mapsessions.end() );
00131             mapsessions[id].reset(new SimpleSessionInstance());
00132             cout << "simple session " << id << " started with options " << req.options << endl;
00133             res.sessionid = id;
00134         }
00135         return true;
00136     }
00137 
00138     bool set_variable(roscpp_sessions::set_variable::Request& req,
00139                       roscpp_sessions::set_variable::Response& res)
00140     {
00141         SimpleSessionInstance* pinst = getstate(req);
00142         if( pinst == NULL )
00143             return false;
00144         pinst->set_variable(req.variable,req.value);
00145         return true;
00146     }
00147 
00148     bool get_variable(roscpp_sessions::get_variable::Request& req,
00149                       roscpp_sessions::get_variable::Response& res)
00150     {
00151         SimpleSessionInstance* pinst = getstate(req);
00152         if( pinst == NULL )
00153             return false;
00154         res.result = pinst->get_variable(req.variable);
00155         return true;
00156     }
00157 
00158     bool add_variables(roscpp_sessions::add_variables::Request& req,
00159                       roscpp_sessions::add_variables::Response& res)
00160     {
00161         SimpleSessionInstance* pinst = getstate(req);
00162         if( pinst == NULL )
00163             return false;
00164         pinst->add_variables(req.result, req.variable1,req.variable2);
00165         return true;
00166     }
00167 
00168 private:
00169     map<int,boost::shared_ptr<SimpleSessionInstance> > mapsessions;
00170     boost::mutex map_mutex;
00171 };
00172 
00173 int main(int argc, char **argv)
00174 {
00175   ros::init(argc, argv, "simple_session");
00176   
00177   s_pmasternode.reset(new ros::NodeHandle());
00178   if( !ros::master::check() )
00179       return 1;
00180   
00181   boost::shared_ptr<SimpleSession> server(new SimpleSession());
00182   ros::spin();
00183 
00184   server.reset();
00185   s_pmasternode.reset();  
00186   return 0;
00187 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Properties Friends


session_tutorials
Author(s): Rosen Diankov / rdiankov at cs.cmu.edu
autogenerated on Sat Mar 23 2013 22:50:28