1- from .modules import loading_bar_handler
21from .bfs import BreadthFirstSearch
32from .dfs import DepthFirstSearch
43from .dijkstra import DijkstraBestFirstSearch
5- import logging
6-
7- UI = False
8-
9- if UI :
10- loading_bar_handler (False )
4+ from .a_star import AStarBestFirstSearch
5+ from .heuristics import goal_count_heuristic , zero_heuristic
6+ import coloredlogs , logging
117import julia
128
13- _ = julia .Julia (compiled_modules = False )
14-
15- if UI :
16- loading_bar_handler (True )
17-
9+ _ = julia .Julia (compiled_modules = False , debug = False )
1810from julia import PDDL
1911from time import time as now
2012
13+ logging .getLogger ("julia" ).setLevel (logging .WARNING )
14+
2115
2216class AutomatedPlanner :
23- def __init__ (self , domain_path , problem_path ):
17+ def __init__ (self , domain_path , problem_path , log_level = "DEBUG" ):
18+ # Planning Tool
2419 self .pddl = PDDL
2520 self .domain = self .pddl .load_domain (domain_path )
2621 self .problem = self .pddl .load_problem (problem_path )
2722 self .initial_state = self .pddl .initialize (self .problem )
2823 self .goals = self .__flatten_goal ()
29-
30- """
31- Transition from one state to the next using an action
32- """
24+ self .available_heuristics = dict ()
25+ self .available_heuristics ["goal_count" ] = goal_count_heuristic
26+ self .available_heuristics ["zero" ] = zero_heuristic
27+
28+ # Logging
29+ logging .basicConfig (
30+ filename = "logs/main.log" ,
31+ format = "%(levelname)s:%(message)s" ,
32+ filemode = "w" ,
33+ level = log_level ,
34+ ) # Creates the log file
35+ self .logger = logging .getLogger ("automated_planning" )
36+ coloredlogs .install (level = log_level )
3337
3438 def transition (self , state , action ):
3539 return self .pddl .transition (self .domain , state , action , check = False )
3640
37- """
38- Returns all available actions from the given state
39- """
40-
4141 def available_actions (self , state ):
4242 return self .pddl .available (state , self .domain )
4343
44- """
45- Check if a vector of terms is satisfied by the given state
46- """
47-
4844 def satisfies (self , asserted_state , state ):
4945 return self .pddl .satisfy (asserted_state , state , self .domain )[0 ]
5046
51- """
52- Check if the term is satisfied by the state
53- To do: compare if it's faster to compute the check on a vector of terms in julia or python
54- """
55-
5647 def state_has_term (self , state , term ):
5748 if self .pddl .has_term_in_state (self .domain , state , term ):
5849 return True
5950 else :
6051 return False
6152
62- """
63- Flatten the goal to a vector of terms
64- To do: check if we can iterate over the jl vector
65- """
66-
6753 def __flatten_goal (self ):
6854 return self .pddl .flatten_goal (self .problem )
6955
70- """
71- Retrieves the linked list path
72- """
73-
7456 def __retrace_path (self , node ):
7557 if not node :
7658 return []
@@ -81,13 +63,9 @@ def __retrace_path(self, node):
8163 path .reverse ()
8264 return path
8365
84- """
85- Returns all the actions operated to reach the goal
86- """
87-
8866 def get_actions_from_path (self , path ):
8967 if not path :
90- logging .warning ("Path is empty, can't operate..." )
68+ self . logger .warning ("Path is empty, can't operate..." )
9169 return []
9270 actions = []
9371 for node in path :
@@ -99,64 +77,45 @@ def get_actions_from_path(self, path):
9977 else :
10078 return (actions , cost )
10179
102- """
103- Returns all the states that should be opened from start to goal
104- """
105-
10680 def get_state_def_from_path (self , path ):
10781 if not path :
108- logging .warning ("Path is empty, can't operate..." )
82+ self . logger .warning ("Path is empty, can't operate..." )
10983 return []
11084 trimmed_path = []
11185 for node in path :
11286 trimmed_path .append (node .state )
11387 return trimmed_path
11488
115- """
116- Runs the BFS algorithm on the loaded domain/problem
117- """
118-
11989 def breadth_first_search (self , time_it = False ):
120- if time_it :
121- start_time = now ()
12290 bfs = BreadthFirstSearch (self )
123- last_node = bfs .search ()
124- if time_it :
125- total_time = now () - start_time
91+ last_node , total_time = bfs .search ()
12692 path = self .__retrace_path (last_node )
12793 if time_it :
12894 return path , total_time
12995 else :
13096 return path , None
13197
132- """
133- Runs the DFS algorithm on the domain/problem
134- """
135-
13698 def depth_first_search (self , time_it = False ):
137- if time_it :
138- start_time = now ()
13999 dfs = DepthFirstSearch (self )
140- last_node = dfs .search ()
141- if time_it :
142- total_time = now () - start_time
100+ last_node , total_time = dfs .search ()
143101 path = self .__retrace_path (last_node )
144102 if time_it :
145103 return path , total_time
146104 else :
147105 return path , None
148106
149- """
150- Runs the Dijkstra algorithm on the domain/problem
151- """
152-
153107 def dijktra_best_first_search (self , time_it = False ):
154- if time_it :
155- start_time = now ()
156108 dijkstra = DijkstraBestFirstSearch (self )
157- last_node = dijkstra .search ()
109+ last_node , total_time = dijkstra .search ()
110+ path = self .__retrace_path (last_node )
158111 if time_it :
159- total_time = now () - start_time
112+ return path , total_time
113+ else :
114+ return path , None
115+
116+ def astar_best_first_search (self , time_it = False , heuristic = goal_count_heuristic ):
117+ astar = AStarBestFirstSearch (self , heuristic )
118+ last_node , total_time = astar .search ()
160119 path = self .__retrace_path (last_node )
161120 if time_it :
162121 return path , total_time
0 commit comments