00001
00002
00003
00004
00005
00006
00007
00008 #ifndef ROSTASK_H_
00009 #define ROSTASK_H_
00010
00011 #include "SynchCout.h"
00012 #include "EventSystem.h"
00013 #include "TaskResult.h"
00014
00015 #include <ros/ros.h>
00016 #include <std_msgs/String.h>
00017 #include <diagnostic_updater/diagnostic_updater.h>
00018
00019 #include <map>
00020 #include <boost/function.hpp>
00021
00022 namespace decision_making{
00023
00024 class LocalTasks{
00025 typedef decision_making::TaskResult (* callTask)(std::string, const decision_making::CallContext&, decision_making::EventQueue&);
00026 typedef std::map<std::string, callTask> callbacks;
00027 typedef boost::function<decision_making::TaskResult (std::string, const decision_making::CallContext&, decision_making::EventQueue&) > callTask_fun;
00028 typedef std::map<std::string, callTask_fun> callbacks_fun;
00029 static callbacks& get(){ static callbacks t; return t; }
00030 static callbacks_fun& get_fun(){ static callbacks_fun t; return t; }
00031 public:
00032 typedef callTask_fun Function;
00033 static void registrate(std::string task_name, callTask cb){
00034 get()[task_name]=cb;
00035 }
00036 static void registrate(std::string task_name, Function cb){
00037 get_fun()[task_name]=cb;
00038 }
00039 static bool registrated(std::string task_name){
00040 return get().find(task_name)!=get().end() or get_fun().find(task_name)!=get_fun().end();
00041 }
00042 static void unregistrated(std::string task_name){
00043 if( get().find(task_name)!=get().end() )
00044 get().erase(get().find(task_name));
00045 if( get_fun().find(task_name)!=get_fun().end() )
00046 get_fun().erase(get_fun().find(task_name));
00047 }
00048 static decision_making::TaskResult call(
00049 std::string task_name,
00050 std::string task_address,
00051 const decision_making::CallContext& call_ctx,
00052 decision_making::EventQueue& events
00053 ){
00054 if(get().find(task_name)!=get().end())
00055 return get()[task_name](task_address, call_ctx, events);
00056 if(get_fun().find(task_name)!=get_fun().end())
00057 return get_fun()[task_name](task_address, call_ctx, events);
00058 return decision_making::TaskResult::FAIL(1000,"Task Not Registrated As Local Task");
00059 }
00060 };
00061
00062
00063 decision_making::TaskResult callTask(std::string task_address, const decision_making::CallContext& call_ctx, decision_making::EventQueue& events);
00064 #define CALL_REMOTE(NAME, CALLS, EVENTS) boost::bind(&decision_making::callTask, #NAME, CALLS, EVENTS)
00065
00066 #define DECISION_MAKING_EVENTS_MACROSES
00067
00068 #define DM_SYSTEM_STOP and ros::ok()
00069
00070 #define ON_FUNCTION(FNAME) void FNAME(std::string name, std::string type, const decision_making::CallContext& call_ctx, decision_making::EventQueue& events, decision_making::TaskResult result)
00071 #define NO_RESULT decision_making::TaskResult::UNDEF()
00072
00073 ON_FUNCTION(on_fsm_start);
00074 #define ON_FSM_START(NAME, CALLS, EVENTS) on_fsm_start(NAME, "FSM", CALLS, EVENTS, NO_RESULT)
00075
00076 ON_FUNCTION(on_fsm_end);
00077 #define ON_FSM_END(NAME, CALLS, EVENTS, RESULT) on_fsm_end(NAME, "FSM", CALLS, EVENTS, RESULT)
00078
00079
00080 ON_FUNCTION(on_fsm_state_start);
00081 #define ON_FSM_STATE_START(NAME, CALLS, EVENTS) on_fsm_state_start(NAME, "FSM_STATE", decision_making::CallContext(CALLS,NAME), EVENTS, NO_RESULT)
00082 ON_FUNCTION(on_fsm_state_end);
00083 #define ON_FSM_STATE_END(NAME, CALLS, EVENTS) on_fsm_state_end(NAME, "FSM_STATE", decision_making::CallContext(CALLS,NAME), EVENTS, NO_RESULT)
00084
00085
00086 ON_FUNCTION(on_bt_node_start);
00087 #define ON_BT_NODE_START(NAME, TYPE, CALLS, EVENTS) on_bt_node_start(NAME, std::string("BT_")+TYPE, CALLS, EVENTS, NO_RESULT)
00088 ON_FUNCTION(on_bt_node_end);
00089 #define ON_BT_NODE_END(NAME, CALLS, EVENTS, RESULT) on_bt_node_end(NAME, "BT_NODE", CALLS, EVENTS, RESULT)
00090
00091
00092 ON_FUNCTION(on_tao_tree_start);
00093 #define ON_TAO_START(NAME, CALLS, EVENTS) on_tao_tree_start(NAME, "TAO", CALLS, EVENTS, NO_RESULT)
00094 ON_FUNCTION(on_tao_tree_end);
00095 #define ON_TAO_END(NAME, CALLS, EVENTS, RESULT) on_tao_tree_end(NAME, "TAO", CALLS, EVENTS, RESULT)
00096
00097 ON_FUNCTION(on_tao_plan_start);
00098 #define ON_TAO_STATE_START(NAME, CALLS, EVENTS) on_tao_plan_start(NAME, "TAO_PLAN", decision_making::CallContext(CALLS,NAME), EVENTS, NO_RESULT)
00099 ON_FUNCTION(on_tao_plan_end);
00100 #define ON_TAO_STATE_END(NAME, CALLS, EVENTS) on_tao_plan_end(NAME, "TAO_PLAN", decision_making::CallContext(CALLS,NAME), EVENTS, NO_RESULT)
00101
00102
00103 class RosConstraints{
00104 public:
00105
00106 static ros::Publisher& getAdder(){
00107 static ros::Publisher p = ros::NodeHandle().advertise<std_msgs::String>("/scriptable_monitor/add_script", 100);
00108 return p;
00109 }
00110 static ros::Publisher& getRemover(){
00111 static ros::Publisher p = ros::NodeHandle().advertise<std_msgs::String>("/scriptable_monitor/remove_script", 100);
00112 return p;
00113 }
00114
00115
00116 RosConstraints(string name, string script)
00117 : script_name(name), script(script)
00118 {
00119 std::stringstream st; st<<"#! name "<<name<<"\n#! type predicate\n"<<script;
00120 std_msgs::String msg; msg.data = preproc(st.str());
00121 getAdder().publish(msg);
00122 }
00123 ~RosConstraints(){
00124 std_msgs::String msg; msg.data = script_name;
00125 getRemover().publish(msg);
00126 }
00127
00128
00129 std::string preproc(std::string txt)const;
00130
00131 private:
00132 std::string script_name;
00133 std::string script;
00134 };
00135
00136 #define CONSTRAINTS(NAME, SCRIPT) \
00137 RosConstraints ros_constraints_##NAME(call_ctx.str()+"/"#NAME, #SCRIPT);
00138
00139
00140 class RosEventQueue:public decision_making::EventQueue{
00141 ros::Publisher publisher;
00142 ros::Subscriber subscriber;
00143 bool do_not_publish_spin;
00144 public:
00145 RosEventQueue();
00146 RosEventQueue(EventQueue* parent);
00147 RosEventQueue(EventQueue* parent, bool isTransit);
00148
00149 void onNewEvent(const std_msgs::String::ConstPtr& msg);
00150 virtual void raiseEvent(const decision_making::Event& e);
00151 virtual bool check_external_ok(){return ros::ok();}
00152
00153 void publish_spin_event(){ do_not_publish_spin = false; }
00154
00155 virtual Event waitEvent(){
00156 boost::mutex::scoped_lock l(events_mutex);
00157 while(events_system_stop==false && events.empty() DM_SYSTEM_STOP) on_new_event.timed_wait(l, boost::get_system_time()+ boost::posix_time::milliseconds(1000));
00158 events_system_stop = not (not events_system_stop DM_SYSTEM_STOP);
00159 if(events_system_stop)
00160 return Event();
00161 Event e = events.front();
00162 events.pop_front();
00163 return e;
00164 }
00165 };
00166
00167 }
00168
00169 void ros_decision_making_init(int &argc, char **argv);
00170
00171 #endif