RobotTask.h
Go to the documentation of this file.
00001 /*
00002  * RobotTask.h
00003  *
00004  *  Created on: Sep 27, 2012
00005  *      Author: Dan Erusalimchik
00006  */
00007 
00008 #ifndef _DEF_ROBOT_TASK
00009 #define _DEF_ROBOT_TASK
00010 
00011 //#define SINGLE_GOAL
00012 #ifndef SINGLE_GOAL
00013         #define MULTI_GOAL
00014 #endif
00015 
00016 namespace robot_task{
00017 //      static const int32_t FAIL = 1;
00018 //      static const int32_t SUCCESS = 0;
00019 //      static const int32_t PLAN=-1;
00020 }
00021 
00022 #ifdef SINGLE_GOAL
00023         #include <actionlib/server/simple_action_server.h>
00024 #endif
00025 #ifdef MULTI_GOAL
00026         #include <robot_task/MultiGoalActionServer.h>
00027         #include <map>
00028         #include <boost/thread.hpp>
00029 #endif
00030 
00031 #include <robot_task/RobotTaskAction.h>
00032 #include <robot_task/StringOperations.h>
00033 #include <sstream>
00034 #include <iostream>
00035 
00036 namespace robot_task{
00037 
00038         using namespace std;
00039         using namespace robot_task;
00040         using namespace robot_task_strings;
00041 
00042         class RobotTask{
00043         public:
00044                 static const int32_t FAIL = 1;
00045                 static const int32_t SUCCESS = 0;
00046                 static const int32_t PLAN=-1;
00047 
00048         protected:
00049             typedef RobotTaskFeedback FEEDBACK;
00050             typedef RobotTaskResult RESULT;
00051 #ifdef SINGLE_GOAL
00052             typedef RobotTaskGoalConstPtr GOAL;
00053             typedef actionlib::SimpleActionServer<RobotTaskAction> Server;
00054 #endif
00055 #ifdef MULTI_GOAL
00056             typedef actionlib::MGActionServer<RobotTaskAction>::GoalHandle GOAL;
00057             typedef actionlib::MGActionServer<RobotTaskAction> Server;
00058 #endif
00059 
00060         protected:
00061             ros::NodeHandle _node;
00062             Server _server;
00063             string _name;
00064             FEEDBACK _feedback;
00065             RESULT _result;
00066 
00067             RobotTask(string name):
00068                         _node(),
00069                         _server(_node, name, boost::bind(&RobotTask::abstract_task, this, _1), false),
00070                         _name(name)
00071                 {
00072                         _server.start();
00073                         ROS_INFO("instance of %s started.",_name.c_str());
00074                 }
00075 
00076             virtual ~RobotTask(){}
00077 
00078 #ifdef SINGLE_GOAL
00079                 void finish(const int32_t& success, const std::string& description, const string& plan, bool AbortForUnsuccess = true){
00080                 #define GOAL_SUCCESS _server.setSucceeded(_result);
00081                 #define GOAL_ABORT _server.setAborted(_result);
00082                 #define GOAL_PREEMPTED _server.setPreempted();
00083 #endif
00084 #ifdef MULTI_GOAL
00085                 void finish(GOAL goalH, const int32_t& success, const std::string& description, const string& plan, bool AbortForUnsuccess = true){
00086                 #define GOAL_SUCCESS _server.setSucceeded(goalH, _result);
00087                 #define GOAL_ABORT _server.setAborted(goalH, _result);
00088                 #define GOAL_PREEMPTED _server.setPreempted(goalH);
00089 #endif
00090                         _result.success = success;
00091                         _result.description = description;
00092                         if(success <= 0)
00093                         {
00094                                 ROS_INFO("%s: Succeeded. %s", _name.c_str(), description.c_str());
00095                                 if(success == PLAN){
00096                                         ROS_INFO("%s: New plan. %s", _name.c_str(), description.c_str());
00097                                         _result.plan = plan;
00098                                 }
00099                                 GOAL_SUCCESS
00100                         }else{
00101                                 if(AbortForUnsuccess){
00102                                         ROS_INFO("%s: Aborted. %s", _name.c_str(), description.c_str());
00103                                         GOAL_ABORT
00104                                 }else{
00105                                         ROS_INFO("%s: Preempted", _name.c_str());
00106                                         GOAL_PREEMPTED
00107                                 }
00108                         }
00109                 }
00110 
00111                 class TaskResult{
00112                         friend class RobotTask;
00113                 protected:
00114                         int32_t success;
00115                         string plan;
00116                         string description;
00117                         bool preempted;
00118 
00119                         TaskResult(bool preempted)
00120                         :success(RobotTask::FAIL), plan(""), description("Preempted"), preempted(preempted){}
00121 
00122                 public:
00123                         TaskResult(const string& plan, const std::string& description )
00124                         :success(RobotTask::PLAN), plan(plan), description(description), preempted(false){}
00125 
00126                         TaskResult(const int32_t success, const std::string& description)
00127                         :success(success), plan(""), description(description), preempted(false){}
00128 
00129 
00130                         TaskResult(const TaskResult& o)
00131                         :success(o.success), plan(o.plan), description(o.description), preempted(o.preempted){ }
00132 
00133                         static TaskResult PREEMPTED(){ return TaskResult(true); }
00134                         static TaskResult FAIL(){ return TaskResult(RobotTask::FAIL,"Unexpected exception"); }
00135                         static TaskResult SUCCESS(){ return TaskResult(RobotTask::SUCCESS,"success"); }
00136                 };
00137 
00138                 virtual RobotTask::TaskResult task(const string& name, const string& uid, Arguments& args)=0;
00139 
00140 #ifdef MULTI_GOAL
00141                 std::map<boost::thread::id,GOAL> goalsByThread;
00142 #endif
00143                 bool isPreempt(){
00144 #ifdef SINGLE_GOAL
00145                         return (_server.isPreemptRequested() || !ros::ok());
00146 #endif
00147 #ifdef MULTI_GOAL
00148                         GOAL goal = goalsByThread[boost::this_thread::get_id()];
00149                         return (_server.isPreemptRequested(goal) || !ros::ok());
00150 #endif
00151                 }
00152 
00153                 void sleep(long millisec){
00154                         boost::this_thread::sleep(boost::posix_time::millisec(millisec));
00155                 }
00156 
00157 #ifdef SINGLE_GOAL
00158                 void abstract_task(const GOAL &goal){
00159 #endif
00160 #ifdef MULTI_GOAL
00161                 void abstract_task(GOAL goal_handle){
00162                         goalsByThread[boost::this_thread::get_id()]=goal_handle;
00163                         const RobotTaskGoalConstPtr& goal = goal_handle.getGoal();
00164 #endif
00165                 /* GET TASK PARAMETERS */
00166                 ROS_INFO("%s: Start: task name = %s", _name.c_str(), goal->name.c_str());
00167                 ROS_INFO("%s: Start: task id = %s", _name.c_str(), goal->uid.c_str());
00168                 ROS_INFO("%s: Start: task params = %s", _name.c_str(), goal->parameters.c_str());
00169 
00170                 /* HERE PROCESS TASK PARAMETERS */
00171                 Arguments args;
00172                 try{
00173                         args = parseArguments(goal->parameters);
00174                 }catch(...){
00175                         ROS_INFO("%s: WARNING: argument parser report about parameters problem.", _name.c_str());
00176                 }
00177 
00178                 RobotTask::TaskResult res = task(goal->name, goal->uid, args);
00179 
00180 #ifdef SINGLE_GOAL
00181                 finish( res.success, res.description, res.plan, !res.preempted);
00182 #endif
00183 #ifdef MULTI_GOAL
00184                 finish( goal_handle, res.success, res.description, res.plan, !res.preempted);
00185                         goalsByThread.erase(boost::this_thread::get_id());
00186 #endif
00187             }
00188         };
00189 
00190 
00191 }
00192 
00193 class SSTREAM{
00194         typedef const char* c_str_t;
00195         boost::shared_ptr<std::stringstream> stream;
00196 public:
00197         operator c_str_t()const{ return c_str(); }
00198         c_str_t c_str()const{ if(stream.get()) return stream->str().c_str(); return 0; }
00199         operator std::string()const{ return str(); }
00200         std::string str()const{ if(stream.get()) return stream->str(); return ""; }
00201         SSTREAM(const SSTREAM& str):stream(str.stream){}
00202         SSTREAM():stream(new std::stringstream()){}
00203         template <typename T>
00204         SSTREAM& operator<<(const T& t){ if(stream.get()) *(stream.get()) << t; return *this; }
00205 };
00206 #define STR(X) ((SSTREAM()<<X).c_str())
00207 
00208 #endif // _DEF_ROBOT_TASK


robot_task
Author(s):
autogenerated on Wed Aug 26 2015 11:16:50