#include <ext/hash_map>
#include <vector>
+#include <queue>
+#include <pthread.h>
+#include <semaphore.h>
#include "action.h"
class Node;
+/**
+ * This class creates, holds and executes a plan.
+ */
+class Planner {
+ public:
+ /**
+ * Creates a plan given the input actions, initial state and goal.
+ *
+ * @param actions A list of actions which will be used to reach the goal.
+ * @param init The initial state which the plan will start from.
+ * @param goal The goal state which the plan will try to reach.
+ */
+ Planner(std::vector<Action> actions, Literals init, Literals goal);
+ /**
+ * Deletes all the remaining nodes and actions.
+ */
+ ~Planner();
-namespace __gnu_cxx {
+ /**
+ * Executes the plan.
+ * Creates new threads for execution of each action.
+ *
+ * If any action fail in some way, this method will try to replan and
+ * recursively call itself.
+ */
+ void execute();
- template< typename CharT, typename Traits, typename Alloc >
- struct hash< std::basic_string<CharT, Traits, Alloc> > {
- size_t operator()(const std::basic_string<CharT, Traits, Alloc>& s) const {
-
- const std::collate<CharT>& c = std::use_facet< std::collate<CharT> >(std::locale());
-
- return c.hash(s.c_str(), s.c_str() + s.size());
-}
+ protected:
- };
+ /**
+ * This method does the actual planning. Given the input node it will
+ * try to find all preconditions and create links from parent nodes
+ * to this node and, if the precondition did not have a node associated
+ * with it, create a new and recursively call this method for the newly
+ * created node.
+ *
+ * @param node The node which this method will find parent nodes for.
+ */
+ void makePlan(Node* node);
- template< typename CharT, typename Traits, typename Alloc >
- struct hash< const std::basic_string<CharT, Traits, Alloc> > { //yes you need this version aswell!
+ /**
+ * Adds this node to the internal map and vector.
+ */
+ void addNode(Node* node);
-size_t operator()(const std::basic_string<CharT, Traits, Alloc>& s) const {
-
- const std::collate<CharT>& c = std::use_facet< std::collate<CharT> >(std::locale());
-
- return c.hash(s.c_str(), s.c_str() + s.size());
- }
+ /**
+ * This method goes through the executed nodes and then calls
+ * executeChildren for these nodes.
+ */
+ void executePlan();
- };
-};
+ /**
+ * Iterates through the children of the input node and satisfies all
+ * preconditions possible with this node. The children will be executed
+ * if all preconditions have been satisfied.
+ */
+ int executeChildren(Node* node);
-class Planner {
- public:
- Planner(std::vector<Action> actions, literals init, literals goal);
+ /**
+ * Addes the remaining actions to the actions map, creates new start and
+ * finish nodes and runs makePlan.
+ */
+ void replan();
+
+ /**
+ * Deletes all nodes, updates _init and _goal, and clears the internal maps and vector.
+ */
+ int cleanupExecution();
- protected:
+ //! Semaphore which is used to signal if a new node has been executed and added to _executedNodes.
+ sem_t _nodes;
+ //! Mutex for access to _executedNodes.
+ sem_t _list;
+ //! Holds the nodes which have been executed, but the children haven't been taken care of yet.
+ std::queue<Node*> _executedNodes;
- void makePlan(Node* node);
-
+ //! The start node in the plan graph.
Node* _start;
- __gnu_cxx::hash_map<std::string,Node*> _addedNodes;
- __gnu_cxx::hash_map<std::string,Action> _actions;
+ //! The end node in the plan graph.
+ Node* _finish;
+ //! Map from all the effects which can be achieved with the already added nodes.
+ __gnu_cxx::hash_map<std::string,Node*> _addedEffects;
+ //! Map with all effects available and their corresponding actions.
+ __gnu_cxx::hash_map<std::string,Action*> _actionEffects;
+ //! The initial state.
+ Literals _init;
+ //! The goal state
+ Literals _goal;
+ //! All the nodes added to the current plan.
+ std::vector<Node*> _addedNodes;
+ //! All the non-executed actions available in the current plan.
+ std::vector<Action*> _actions;
};
#endif