learning_executor.cpp
Go to the documentation of this file.
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()); //the order of the rules must not matter
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); //this has to be before selector->savevalueinitial
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   //very practical C way of getting the current hour of day
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); //does side effect on variables
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       //if there is no new goal completeTask will be called for this task at the end of this function
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 //   if (ros::console::set_logger_level(ROSCONSOLE_DEFAULT_NAME, ros::console::levels::Debug)) {
00227 //     ros::console::notifyLoggerLevelsChanged();
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 //  create initial state
00238   LogicalNavigation setInitialState("noop");
00239   setInitialState.run();
00240 
00241  
00242 
00243   bool simulating;
00244   privateNode.param<bool>("simulation",simulating,false);
00245   
00246 //  valueDirectory = ros::package::getPath("bwi_kr_execution") +((simulating)? "/values_simulation/" : "/values/" ) ;
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   //need a pointer to the specific type for the observer
00275 //   executor = new MultiPolicyExecutor(reasoner, reasoner,selector , ActionFactory::actions(),1.5);
00276 // 
00277 //   executor->addExecutionObserver(selector);
00278 //   executor->addExecutionObserver(reward);
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 }


bwi_kr_execution
Author(s): Matteo Leonetti, Piyush Khandelwal
autogenerated on Thu Jun 6 2019 17:57:37