8 import subprocess 
as sp
 
   29         fl = fcntl.fcntl(fd, fcntl.F_GETFL)
 
   30         fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
 
   42     _result = PDDLPlannerResult()
 
   49         search_option = rospy.get_param(
'~pddl_search_option', 
'')
 
   60             problem = goal.problem
 
   62             max_planning_time = goal.max_planning_time.to_sec()
 
   63             rospy.loginfo(
"take a message")
 
   65             rospy.loginfo(
"problem_path => %s" % problem_path)
 
   66             rospy.loginfo(
"domain_path => %s" % domain_path)
 
   70                 self.
_result.sequence = [PDDLStep(action = x.split(
' ')[1].lstrip(
"\("),
 
   71                                                   args = re.search(
"\([^\)]+\)", x).group(0).lstrip(
"\(").rstrip(
"\)").split(
' ')[1:],
 
   72                                                   start_time = re.search(
"[0-9]+.[0-9]+:" , x).group(0).rstrip(
":"),
 
   73                                                   action_duration = re.search(
"\[D[^\)]+;", x).group(0).lstrip(
"[D:").rstrip(
";")
 
   76                 self.
_result.use_durative_action = 
True 
   78                 self.
_result.sequence = [PDDLStep(action = x.split(
' ')[0],
 
   79                                                   args = x.split(
' ')[1:])
 
   82             rospy.loginfo(
"action finished with success")
 
   83         except ActionPreemptedException:
 
   84             rospy.loginfo(
"action preempted")
 
   85             self.
_as.set_preempted()
 
   87             rospy.logerr(
"Failed to parse output")
 
   88             self.
_as.set_aborted()
 
   89         except RuntimeError 
as e:
 
   90             rospy.logerr(
"Planner exited with error: %s" % e)
 
   91             self.
_as.set_aborted()
 
   92         except Exception 
as e:
 
   93             rospy.logerr(
"Unhandled Error: %s" % e)
 
   94             rospy.logerr(traceback.format_exc())
 
   95             self.
_as.set_aborted()
 
  100         step_before_after = output.split(
"step")
 
  101         if len(step_before_after) == 2:
 
  102             results = [re.sub(
"\s*$", 
"", re.sub(
r'^\s*\d+:\s*', 
"" , x))
 
  103                        for x 
in step_before_after[1].split(
"time spent")[0].split(
"\n")]
 
  104             rospy.loginfo(
"result => %s" % results)
 
  105             return filter(
lambda x: x != 
"", results)
 
  109         rospy.loginfo(output)
 
  111         step_before_after = output.split(
"step")
 
  112         if len(step_before_after) == 2:
 
  113             results = [y.group(0)
 
  114                        for y 
in [re.search(
"\([^\)]+\)", x)
 
  115                                  for x 
in step_before_after[1].split(
"Total cost")[0].split(
"\n")[1:]]
 
  117             results = filter(
lambda a: a.find(
"(REACH-GOAL)") < 0, results)
 
  118             rospy.loginfo(
"result => %s" % results)
 
  124         rospy.loginfo(output)
 
  126         duration_before_after = output.split(
"action Duration")
 
  127         if len(duration_before_after) == 2:
 
  128             results = [y.group(0)
 
  129                        for y 
in [re.search(
"[0-9][^\]]+\]", x)
 
  130                                  for x 
in duration_before_after[1].split(
"Solution number")[0].split(
"\n")[1:]]
 
  132             rospy.loginfo(
"result => %s" % results)
 
  138         plan_path = path_name
 
  140         while os.path.exists(path_name + 
"." + str(i)):
 
  141             plan_path = path_name + 
"." + str(i)
 
  143         rospy.loginfo(
"plan_path => %s" % plan_path)
 
  145         with open(plan_path) 
as f:
 
  146             plan = f.read().split(
"\n")
 
  149         results = [re.sub(
" \)$", 
")", x)
 
  151         rospy.loginfo(results)
 
  156         if max_planning_time > 0.0:
 
  157             command = [
"timeout", str(max_planning_time)] + command
 
  158         rospy.loginfo(
"Command: %s" % command)
 
  159         proc = sp.Popen(command, stdout=sp.PIPE, stderr=sp.PIPE)
 
  161             output, error = str(), str()
 
  164                 if rospy.is_shutdown():
 
  166                 if self.
_as.is_preempt_requested():
 
  168                 if proc.poll() 
is not None:
 
  173                 if type(data_out) == bytes:
 
  174                     data_out = data_out.decode(
'utf-8')
 
  175                     if type(data_err) == bytes:
 
  176                         data_err = data_err.decode(
'utf-8')
 
  182             data = proc.communicate()
 
  185             if type(data_out) == bytes:
 
  186                 data_out = data_out.decode(
'utf-8')
 
  187             if type(data_err) == bytes:
 
  188                 data_err = data_err.decode(
'utf-8')
 
  192             if proc.returncode 
not in [0, 124]:
 
  196                 msg  = 
"Output:\n" + output + 
"\n" 
  197                 msg += 
"Error:\n" + error + 
"\n" 
  198                 msg += 
"Exit code: {}\n".format(proc.poll())
 
  199                 raise RuntimeError(msg)
 
  205         if proc 
is None or proc.poll() 
is not None:
 
  209             proc.send_signal(signal.SIGINT)
 
  212             if proc.poll() 
is not None:
 
  216             proc.send_signal(signal.SIGTERM)
 
  219             if proc.poll() 
is not None:
 
  225         except Exception 
as e:
 
  226             rospy.logerr(
"Failed to kill process: %s" % e)
 
  233             output = self.
exec_process([
"rosrun", 
"ff", 
"ff", 
"-f", problem, 
"-o", domain],
 
  241             if re.search(
"final domain representation is:", output):
 
  242                 tmp = output.split(
"metric:")
 
  249             (fd, path_name) = tempfile.mkstemp(text=
True, prefix=
'plan_')
 
  250             output = self.
exec_process([
"rosrun", 
"downward", 
"plan", domain, problem] + self.
_search_option + [
"--plan-file", path_name],
 
  252             rospy.loginfo(output)
 
  262             rospy.logfatal(
"set invalid planner: %s !" % self.
_planner_name)
 
  266         search_durative = re.search(
"durative", domain.requirements)
 
  267         rospy.loginfo (
"gen_tmp_pddl_file: requirements:%s" % domain.requirements)
 
  268         if search_durative == 
None:
 
  271             return (problem_file, domain_file)
 
  275             return (problem_file, domain_file)
 
  288             if o.type 
in grouped_objects:
 
  289                 grouped_objects[o.type].append(o.name)
 
  291                 grouped_objects[o.type] = [o.name]
 
  292         return [
" ".join(grouped_objects[t]) + 
" - " + t
 
  293                 for t 
in grouped_objects.keys()]
 
  296         (fd, path_name) = tempfile.mkstemp(text=
True, prefix=
'problem_')
 
  297         path = os.fdopen(fd, 
'w')
 
  298         path.write(
"""(define (problem %s) 
  303 """ % (problem.name, problem.domain,
 
  305        ' '.join(problem.initial), problem.goal))
 
  307             path.write(
"""(:metric %s)""" % problem.metric)
 
  312         (fd, path_name) = tempfile.mkstemp(text=
True, prefix=
'domain_')
 
  313         path = os.fdopen(fd, 
'w')
 
  314         path.write(
"(define (domain %s)\n" % domain.name)
 
  315         path.write(
"(:requirements %s)\n" % domain.requirements)
 
  316         path.write(
"(:types \n")
 
  317         for i 
in domain.types:
 
  320         if len(domain.constants) > 0:
 
  321             path.write(
"(:constants \n")
 
  322             for i 
in domain.constants:
 
  325         path.write(
"(:predicates\n")
 
  326         for i 
in domain.predicates:
 
  330             path.write(
"(:functions\n")
 
  331             for i 
in domain.functions:
 
  334         for action 
in domain.actions:
 
  335             path.write(
"(:action %s\n" % action.name)
 
  336             path.write(
":parameters %s\n" % action.parameters)
 
  337             path.write(
":precondition %s\n" % action.precondition)
 
  338             path.write(
":effect %s\n" % action.effect)
 
  344         rospy.loginfo(
"domain.actions:%s" % domain.actions)
 
  345         (fd, path_name) = tempfile.mkstemp(text=
True, prefix=
'domain_')
 
  346         path = os.fdopen(fd, 
'w')
 
  347         path.write(
"(define (domain %s)\n" % domain.name)
 
  348         path.write(
"(:requirements %s)\n" % domain.requirements)
 
  349         path.write(
"(:types \n")
 
  350         for i 
in domain.types:
 
  353         if len(domain.constants) > 0:
 
  354             path.write(
"(:constants \n")
 
  355             for i 
in domain.constants:
 
  358         path.write(
"(:predicates\n")
 
  359         for i 
in domain.predicates:
 
  363             path.write(
"(:functions\n")
 
  364             for i 
in domain.functions:
 
  367         for action 
in domain.actions:
 
  368             path.write(
"(:durative-action %s\n" % action.name)
 
  369             path.write(
":parameters %s\n" % action.parameters)
 
  370             path.write(
":duration %s\n" % action.action_duration)
 
  371             path.write(
":condition %s\n" % action.precondition)
 
  372             path.write(
":effect %s\n" % action.effect)
 
  378 if __name__ == 
'__main__':
 
  379     rospy.init_node(
'pddl_planner')