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
12-
13- _ = julia .Julia (compiled_modules = False )
14-
15- if UI :
16- loading_bar_handler (True )
17-
8+ _ = julia .Julia (compiled_modules = False , debug = False )
189from julia import PDDL
1910from time import time as now
20-
21-
11+ logging .getLogger ("julia" ).setLevel (logging .WARNING )
2212class AutomatedPlanner :
23- def __init__ (self , domain_path , problem_path ):
13+ def __init__ (self , domain_path , problem_path , log_level = "DEBUG" ):
14+ # Planning Tool
2415 self .pddl = PDDL
2516 self .domain = self .pddl .load_domain (domain_path )
2617 self .problem = self .pddl .load_problem (problem_path )
2718 self .initial_state = self .pddl .initialize (self .problem )
2819 self .goals = self .__flatten_goal ()
29-
30- """
31- Transition from one state to the next using an action
32- """
20+ self .available_heuristics = dict ()
21+ self .available_heuristics ["goal_count" ] = goal_count_heuristic
22+ self .available_heuristics ["zero" ] = zero_heuristic
23+
24+ # Logging
25+ logging .basicConfig (
26+ filename = "logs/main.log" ,
27+ format = "%(levelname)s:%(message)s" ,
28+ filemode = "w" ,
29+ level = log_level ,
30+ ) # Creates the log file
31+ self .logger = logging .getLogger ("automated_planning" )
32+ coloredlogs .install (level = log_level )
3333
3434 def transition (self , state , action ):
3535 return self .pddl .transition (self .domain , state , action , check = False )
3636
37- """
38- Returns all available actions from the given state
39- """
40-
4137 def available_actions (self , state ):
4238 return self .pddl .available (state , self .domain )
4339
44- """
45- Check if a vector of terms is satisfied by the given state
46- """
47-
4840 def satisfies (self , asserted_state , state ):
4941 return self .pddl .satisfy (asserted_state , state , self .domain )[0 ]
5042
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-
5643 def state_has_term (self , state , term ):
5744 if self .pddl .has_term_in_state (self .domain , state , term ):
5845 return True
5946 else :
6047 return False
6148
62- """
63- Flatten the goal to a vector of terms
64- To do: check if we can iterate over the jl vector
65- """
66-
6749 def __flatten_goal (self ):
6850 return self .pddl .flatten_goal (self .problem )
6951
70- """
71- Retrieves the linked list path
72- """
73-
7452 def __retrace_path (self , node ):
7553 if not node :
7654 return []
@@ -81,13 +59,9 @@ def __retrace_path(self, node):
8159 path .reverse ()
8260 return path
8361
84- """
85- Returns all the actions operated to reach the goal
86- """
87-
8862 def get_actions_from_path (self , path ):
8963 if not path :
90- logging .warning ("Path is empty, can't operate..." )
64+ self . logger .warning ("Path is empty, can't operate..." )
9165 return []
9266 actions = []
9367 for node in path :
@@ -99,64 +73,45 @@ def get_actions_from_path(self, path):
9973 else :
10074 return (actions , cost )
10175
102- """
103- Returns all the states that should be opened from start to goal
104- """
105-
10676 def get_state_def_from_path (self , path ):
10777 if not path :
108- logging .warning ("Path is empty, can't operate..." )
78+ self . logger .warning ("Path is empty, can't operate..." )
10979 return []
11080 trimmed_path = []
11181 for node in path :
11282 trimmed_path .append (node .state )
11383 return trimmed_path
11484
115- """
116- Runs the BFS algorithm on the loaded domain/problem
117- """
118-
11985 def breadth_first_search (self , time_it = False ):
120- if time_it :
121- start_time = now ()
12286 bfs = BreadthFirstSearch (self )
123- last_node = bfs .search ()
124- if time_it :
125- total_time = now () - start_time
87+ last_node , total_time = bfs .search ()
12688 path = self .__retrace_path (last_node )
12789 if time_it :
12890 return path , total_time
12991 else :
13092 return path , None
13193
132- """
133- Runs the DFS algorithm on the domain/problem
134- """
135-
13694 def depth_first_search (self , time_it = False ):
137- if time_it :
138- start_time = now ()
13995 dfs = DepthFirstSearch (self )
140- last_node = dfs .search ()
141- if time_it :
142- total_time = now () - start_time
96+ last_node , total_time = dfs .search ()
14397 path = self .__retrace_path (last_node )
14498 if time_it :
14599 return path , total_time
146100 else :
147101 return path , None
148102
149- """
150- Runs the Dijkstra algorithm on the domain/problem
151- """
152-
153103 def dijktra_best_first_search (self , time_it = False ):
154- if time_it :
155- start_time = now ()
156104 dijkstra = DijkstraBestFirstSearch (self )
157- last_node = dijkstra .search ()
105+ last_node , total_time = dijkstra .search ()
106+ path = self .__retrace_path (last_node )
158107 if time_it :
159- total_time = now () - start_time
108+ return path , total_time
109+ else :
110+ return path , None
111+
112+ def astar_best_first_search (self , time_it = False , heuristic = goal_count_heuristic ):
113+ astar = AStarBestFirstSearch (self , heuristic )
114+ last_node , total_time = astar .search ()
160115 path = self .__retrace_path (last_node )
161116 if time_it :
162117 return path , total_time
0 commit comments