00001
00002 #include "msgs_utils.h"
00003 #include "RemoteReasoner.h"
00004 #include "StaticFacts.h"
00005
00006 #include "learning/SarsaActionSelector.h"
00007 #include "learning/TimeReward.h"
00008 #include "learning/DefaultTimes.h"
00009 #include "learning/ActionLogger.h"
00010
00011 #include "bwi_kr_execution/ExecutePlanAction.h"
00012
00013 #include "actasp/action_utils.h"
00014 #include "actasp/executors/PartialPolicyExecutor.h"
00015 #include <actasp/reasoners/Clingo4_2.h>
00016
00017 #include "actions/ActionFactory.h"
00018 #include "actions/LogicalNavigation.h"
00019
00020
00021 #include <actionlib/server/simple_action_server.h>
00022
00023 #include <ros/ros.h>
00024 #include <ros/package.h>
00025 #include <ros/console.h>
00026
00027 #include <boost/filesystem.hpp>
00028
00029 #include <string>
00030 #include <fstream>
00031 #include <ctime>
00032
00033 const int MAX_N = 20;
00034 const std::string queryDirectory("/tmp/bwi_action_execution/");
00035 const std::string value_directory_base("/var/tmp/my_bwi_action_execution/");
00036 std::string valueDirectory;
00037
00038
00039 using namespace std;
00040 using namespace bwi_krexec;
00041 using namespace actasp;
00042
00043 typedef actionlib::SimpleActionServer<bwi_kr_execution::ExecutePlanAction> Server;
00044
00045 ActionExecutor *executor;
00046 SarsaActionSelector *selector;
00047 ActionLogger *action_logger;
00048
00049 struct PrintFluent {
00050
00051 PrintFluent(ostream& stream) : stream(stream) {}
00052
00053 string operator()(const AspFluent& fluent) {
00054 stream << fluent.toString() << " ";
00055 }
00056
00057 ostream &stream;
00058
00059 };
00060
00061 struct Observer : public ExecutionObserver {
00062
00063 void actionStarted(const AspFluent& action) throw() {
00064 ROS_INFO_STREAM("Starting execution: " << action.toString());
00065 }
00066
00067 void actionTerminated(const AspFluent& action) throw() {
00068 ROS_INFO_STREAM("Terminating execution: " << action.toString());
00069 }
00070
00071
00072 void goalChanged(std::vector<actasp::AspRule> newGoalRules) throw() {}
00073
00074 void policyChanged(PartialPolicy* policy) throw() {}
00075
00076 };
00077
00078 std::string rulesToFileName(const vector<AspRule> &rules) {
00079
00080 stringstream ruleString;
00081 vector<string> ruleStringVector;
00082
00083
00084
00085 vector<AspRule>::const_iterator ruleIt = rules.begin();
00086
00087 for(; ruleIt != rules.end(); ++ruleIt) {
00088
00089 vector<AspFluent>::const_iterator headIt = ruleIt->head.begin();
00090
00091 for(; headIt != ruleIt->head.end(); ++headIt)
00092 ruleString << headIt->toString(0);
00093
00094 ruleString << ":-";
00095
00096 vector<AspFluent>::const_iterator bodyIt = ruleIt->body.begin();
00097
00098 for(; bodyIt != ruleIt->body.end(); ++bodyIt)
00099 ruleString << bodyIt->toString(0);
00100
00101 ruleString << "--";
00102
00103 ruleStringVector.push_back(ruleString.str());
00104 ruleString.str(string());
00105 }
00106
00107 sort(ruleStringVector.begin(), ruleStringVector.end());
00108
00109 vector<string>::const_iterator stringIt = ruleStringVector.begin();
00110 for(; stringIt != ruleStringVector.end(); ++stringIt)
00111 ruleString << *stringIt;
00112
00113 return valueDirectory + ruleString.str();
00114 }
00115
00116
00117 void completeTask(const string& valueFileName, const ros::Time& begin, const string& time_string) {
00118
00119 ros::Time end = ros::Time::now();
00120
00121 selector->episodeEnded();
00122
00123 ofstream time_file((valueFileName+"_time").c_str(), ofstream::app);
00124 if(executor->goalReached())
00125 time_file << 1 << " " ;
00126 else {
00127 time_file << 0 << " " ;
00128 }
00129 time_file << (end - begin).toSec() << " " << time_string << endl;
00130 time_file.close();
00131
00132
00133 action_logger->taskCompleted();
00134
00135 ofstream valueFileOut(valueFileName.c_str());
00136 selector->writeTo(valueFileOut);
00137 valueFileOut.close();
00138
00139 }
00140
00141 void initiateTask(const bwi_kr_execution::ExecutePlanGoalConstPtr& plan, string &valueFileName, ros::Time& begin, char* time_string) {
00142
00143 begin = ros::Time::now();
00144
00145 vector<AspRule> goalRules;
00146
00147 transform(plan->aspGoal.begin(),plan->aspGoal.end(),back_inserter(goalRules),TranslateRule());
00148
00149 executor->setGoal(goalRules);
00150
00151 valueFileName = rulesToFileName(goalRules);
00152 ifstream valueFileIn(valueFileName.c_str());
00153 selector->readFrom(valueFileIn);
00154 valueFileIn.close();
00155 selector->saveValueInitialState(valueFileName + "_initial");
00156
00157 action_logger->setFile((valueFileName+"_actions"));
00158
00159
00160 time_t rawtime;
00161 struct tm * timeinfo;
00162 time (&rawtime);
00163 timeinfo = localtime (&rawtime);
00164 strftime (time_string,10,"%R",timeinfo);
00165
00166 }
00167
00168 void executePlan(const bwi_kr_execution::ExecutePlanGoalConstPtr& plan, Server* as) {
00169
00170 string valueFileName;
00171 char time_string[10];
00172 ros::Time begin;
00173
00174 initiateTask(plan,valueFileName,begin,time_string);
00175
00176 ros::Rate loop(10);
00177
00178 while (!executor->goalReached() && !executor->failed() && as->isActive() && ros::ok()) {
00179
00180 if (!as->isPreemptRequested()) {
00181 executor->executeActionStep();
00182 } else {
00183
00184 as->setPreempted();
00185
00186 if (executor->goalReached())
00187 ROS_INFO("Preempted, but execution succeded");
00188 else
00189 ROS_INFO("Preempted, execution aborted");
00190
00191
00192
00193 if (as->isNewGoalAvailable()) {
00194
00195 completeTask(valueFileName,begin,time_string);
00196
00197 const bwi_kr_execution::ExecutePlanGoalConstPtr& newGoal = as->acceptNewGoal();
00198
00199 initiateTask(newGoal,valueFileName,begin,time_string);
00200
00201 }
00202
00203 }
00204
00205 loop.sleep();
00206 }
00207
00208 if (executor->goalReached()) {
00209 ROS_INFO("Execution succeded");
00210 if(as->isActive())
00211 as->setSucceeded();
00212 } else {
00213 ROS_INFO("Execution failed");
00214 if(as->isActive())
00215 as->setAborted();
00216 }
00217
00218 completeTask(valueFileName,begin,time_string);
00219
00220 }
00221
00222 int main(int argc, char**argv) {
00223 ros::init(argc, argv, "action_executor");
00224 ros::NodeHandle n;
00225
00226
00227
00228
00229
00230 ros::NodeHandle privateNode("~");
00231 string domainDirectory;
00232 n.param<std::string>("bwi_kr_execution/domain_directory", domainDirectory, ros::package::getPath("bwi_kr_execution")+"/domain/");
00233
00234 if (domainDirectory.at(domainDirectory.size()-1) != '/')
00235 domainDirectory += '/';
00236
00237
00238 LogicalNavigation setInitialState("noop");
00239 setInitialState.run();
00240
00241
00242
00243 bool simulating;
00244 privateNode.param<bool>("simulation",simulating,false);
00245
00246
00247 valueDirectory = value_directory_base + ((simulating)? "values_simulation/" : "values/" );
00248 boost::filesystem::create_directories(valueDirectory);
00249
00250 ActionFactory::setSimulation(simulating);
00251
00252 boost::filesystem::create_directories(queryDirectory);
00253
00254 FilteringQueryGenerator *generator = new Clingo4_2("n",queryDirectory,domainDirectory,actionMapToSet(ActionFactory::actions()),20);
00255 FilteringKR *reasoner = new RemoteReasoner(generator,MAX_N,actionMapToSet(ActionFactory::actions()));
00256
00257 StaticFacts::retrieveStaticFacts(reasoner, domainDirectory);
00258
00259 TimeReward<SarsaActionSelector::State> *reward = new TimeReward<SarsaActionSelector::State>();
00260 DefaultActionValue *timeValue = new DefaultTimes();
00261
00262 SarsaParams params;
00263 params.alpha = 0.2;
00264 params.gamma = 0.9999;
00265 params.lambda = 0.9;
00266 params.epsilon = 0.2;
00267
00268 selector = new SarsaActionSelector(reasoner,timeValue,reward,params);
00269
00270 executor = new PartialPolicyExecutor(reasoner, reasoner,selector,ActionFactory::actions(),1.5);
00271 executor->addExecutionObserver(selector);
00272 executor->addExecutionObserver(reward);
00273
00274
00275
00276
00277
00278
00279
00280 Observer observer;
00281 executor->addExecutionObserver(&observer);
00282
00283 action_logger = new ActionLogger();
00284 executor->addExecutionObserver(action_logger);
00285
00286 Server server(privateNode, "execute_plan", boost::bind(&executePlan, _1, &server), false);
00287 server.start();
00288
00289 ros::spin();
00290
00291 server.shutdown();
00292
00293 delete executor;
00294 delete action_logger;
00295 delete selector;
00296 delete timeValue;
00297 delete reward;
00298 delete reasoner;
00299 delete generator;
00300
00301 return 0;
00302 }