clingo.py
Go to the documentation of this file.
00001 #! /usr/bin/env python
00002 
00003 import os
00004 import rospy
00005 import signal
00006 import subprocess
00007 import threading
00008 import time
00009 
00010 from .atom import Atom
00011 
00012 def parse_plan(plan_string, atom_class):
00013     atoms = [atom_class(word) for word in plan_string.split()]
00014     plan = [atom for atom in atoms if atom.type == Atom.ACTION]
00015     states = [atom for atom in atoms if atom.type == Atom.FLUENT]
00016     plan = sorted(plan, key=lambda atom: atom.time)
00017     states = sorted(states, key=lambda atom: atom.time)
00018     return plan,states
00019 
00020 class ClingoCommand(object):
00021 
00022     def __init__(self, cmd, outfile):
00023         self.cmd = cmd
00024         self.process = None
00025         self.outfile = outfile
00026 
00027     def run(self, timeout):
00028         rospy.logdebug("Running command: " + self.cmd)
00029         def target():
00030             self.process = subprocess.Popen(self.cmd, shell=True, 
00031                                             stdout=self.outfile, 
00032                                             preexec_fn=os.setsid)
00033             self.process.communicate()
00034 
00035         thread = threading.Thread(target=target)
00036         thread.start()
00037 
00038         thread.join(timeout)
00039         if thread.is_alive():
00040             os.killpg(self.process.pid, signal.SIGTERM)
00041             thread.join()
00042         rospy.logdebug("Process RetCode: " + str(self.process.returncode))
00043         self.outfile.close()
00044         return self.process.returncode
00045 
00046 class ClingoWrapper(object):
00047 
00048     def __init__(self, atom_class):
00049         self.clingo_timeout = rospy.get_param("~clingo_timeout", 60)
00050         self.clingo_steps = rospy.get_param("~clingo_steps", 15)
00051         self.clingo_threads = rospy.get_param("~clingo_threads", 6)
00052         rospy.loginfo("Clingo: Using " + str(self.clingo_threads) + " threads" +
00053                       " for " + str(self.clingo_timeout) + " seconds. max_len" +
00054                       " is set to " + str(self.clingo_steps))
00055         self.domain_semantics_file = rospy.get_param("~domain_semantics_file")
00056         self.rigid_knowledge_file = rospy.get_param("~rigid_knowledge_file")
00057         self.atom_class = atom_class
00058 
00059     def get_plan(self, additional_files):
00060 
00061         start_time = time.time()
00062  
00063         for n in range(self.clingo_steps):
00064             # Run clingo
00065             additional_files_str = " ".join(additional_files)
00066             out_file = open("result", "w")
00067             clingo_command = ClingoCommand("gringo -c n=" + str(n) +
00068                                      " " + self.domain_semantics_file + 
00069                                      " " + self.rigid_knowledge_file + 
00070                                      " " + additional_files_str + 
00071                                      " | rosrun clasp clasp -t " + 
00072                                      str(self.clingo_threads), out_file)
00073             ret_code = clingo_command.run(self.clingo_timeout)
00074 
00075             # Parse Output
00076             out_file = open("result","r")
00077             linelist = []
00078             no_plan_available = False
00079             for line in out_file:
00080                 linelist.append(line)
00081                 if line[:13] == "UNSATISFIABLE":
00082                     no_plan_available = True
00083                     break
00084                 if line[:11] == "SATISFIABLE":
00085                     optimization = n
00086                     plan_line = linelist[-2]
00087 
00088             out_file.close()
00089             if no_plan_available:
00090                 continue
00091 
00092             try:
00093                 plan, states = parse_plan(plan_line, self.atom_class)
00094             except ValueError as e:
00095                 rospy.logerr("Received plan from clasp, but unable to parse plan:" +
00096                              plan_line)
00097                 rospy.logerr("  Error: " + str(e))
00098                 return False, 0, None, None
00099 
00100             end_time = time.time()
00101             rospy.loginfo("Planning took %ss." % str(end_time - start_time))
00102 
00103             return True, optimization, plan, states
00104         return False, 0, None, None
00105 
00106     def get_plan_costs(self, additional_files):
00107 
00108         start_time = time.time()
00109 
00110         # Run clingo
00111         additional_files_str = " ".join(additional_files)
00112         result_file_str = "/tmp/result"
00113         out_file = open(result_file_str, "w")
00114         clingo_command = ClingoCommand("gringo -c n=" + str(self.clingo_steps) +
00115                                  " " + self.domain_semantics_file + 
00116                                  " " + self.rigid_knowledge_file + 
00117                                  " " + additional_files_str + 
00118                                  " | rosrun clasp clasp -t " + 
00119                                  str(self.clingo_threads), out_file)
00120         ret_code = clingo_command.run(self.clingo_timeout)
00121         rospy.loginfo("Clingo output written to " + result_file_str) 
00122 
00123         # Parse Output
00124         linelist = []
00125         plan_line = None
00126         out_file = open(result_file_str,"r")
00127         for line in out_file:
00128             linelist.append(line)
00129             if line == "UNSATISFIABLE\n":
00130                 out_file.close()
00131                 return False, 0, None, None
00132             if line[:13] == "Optimization:" and linelist[-2][:9] != "  Optimum":
00133                 optimization_line = linelist[-1]
00134                 optimization = int(optimization_line.split(' ')[1])
00135                 plan_line = linelist[-2]
00136 
00137         if not plan_line:
00138             rospy.loginfo("Unable to parse clasp output. Check " + 
00139                           result_file_str) 
00140             return False, 0, None, None
00141 
00142         try:
00143             plan, states = parse_plan(plan_line, self.atom_class)
00144             #correct_execution_order(plan, states)
00145         except ValueError as e:
00146             rospy.logerr("Received plan from clasp, but unable to parse plan:" +
00147                          plan_line)
00148             rospy.logerr("  Error: " + str(e))
00149             return False, 0, None, None
00150 
00151         out_file.close()
00152 
00153         end_time = time.time()
00154         rospy.loginfo("Planning took %ss." % str(end_time - start_time))
00155 
00156         return True, optimization, plan, states
00157 


bwi_planning
Author(s): Piyush Khandelwal , Fangkai Yang
autogenerated on Wed Aug 26 2015 10:54:52