From bb8a4c7acf393eee97a910d9551af6fc30e9480a Mon Sep 17 00:00:00 2001 From: "Robert P. Goldman" Date: Fri, 29 Dec 2023 12:06:06 -0600 Subject: [PATCH] Easier-to-user Panda script. Use getopt argument parsing and add more options so that one can try different things without needing to edit the script. Write intermediate files into a temporary directory to avoid cluttering up the current working directory. --- pandaSolver | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100755 pandaSolver diff --git a/pandaSolver b/pandaSolver new file mode 100755 index 0000000..43d1774 --- /dev/null +++ b/pandaSolver @@ -0,0 +1,147 @@ +#!/bin/bash + +# author: Pascal Bercher (pascal.bercher@anu.edu.au) +# improved by Lijia Yuan and Pascal again; both with GPT 4.0 + +# Extended version: Robert P. Goldman (rpgoldman@sift.net) +# TODO: +# * Make it possible to change solvers to BDD or SAT +# * Make it possible to try different heuristics + + +# For MacOS, which has a crappy getopt +GETOPT=getopt +type -P ggetopt > /dev/null && GETOPT=ggetopt + +type -P pandaPIparser > /dev/null || ( echo "pandaPIparser must be added to your path." ; exit 1 ) +type -P pandaPIgrounder > /dev/null || ( echo "pandaPIgrounder must be added to your path." ; exit 1 ) +type -P pandaPIengine > /dev/null || ( echo "pandaPIengine must be added to your path." ; exit 1 ) + +# Default Timeout in seconds here 2 minutes +TIMEOUT_SECONDS=$((2 * 60)) +SAVE_TEMPDIR=false +SUBOPTIMAL=false + +VALID_ARGS=$(${GETOPT} -o hut: --long help,usage,timeout:,save-tempdir,suboptimal -- "$@") +if [[ $? -ne 0 ]]; then + echo "Error parsing arguments." + exit 1 +fi + +function usage () { + echo "$0 [--timeout t] [--save-tempdir] [--suboptimal] " + echo "Run the Panda planner (parser, grounder, engine) on and ." + echo "Optionally, set the planner timeout to t seconds. Timeout defaults to 120s/2m." + echo "By default, finds an optimal solution, unless the '--suboptimal' flag is supplied." + echo "Intermediate files from parser and grounder are written to a temporary directory," + echo "as are informational and error messages. The temporary directory will be automatically" + echo "deleted, unless an error occurs or the '--save-tempdir' option is passed, in which" + echo "case the temporary directory will be retained." +} + +eval set -- "$VALID_ARGS" +while [ : ]; do + case "$1" in + -h | --help | -u | --usage) + usage + exit 0 + ;; + -t | --timeout) + TIMEOUT_SECONDS=$2 + shift 2 + ;; + --save-tempdir) + SAVE_TEMPDIR=true + shift + ;; + --suboptimal) + SUBOPTIMAL=true + shift + ;; + --) shift; + break + ;; + esac +done + +if $SUBOPTIMAL; then + SUBOPTIMAL_ARG="--suboptimal" +else + SUBOPTIMAL_ARG="" +fi + +echo "Domain argument is $1; problem argument is $2; timeout is ${TIMEOUT_SECONDS}; SAVE_TEMPDIR is ${SAVE_TEMPDIR}" +echo "SUBOPTIMAL_ARG is ${SUBOPTIMAL_ARG}" + +if (( $# != 2 )); then + >&2 echo "$0 requires 2 positional parameters" + usage + exit 1 +fi + +SCRATCHDIR=`mktemp -d -t PandaFiles` +if $SAVE_TEMPDIR ; then + echo "Saving temporary output files to $SCRATCHDIR" +fi + +handle_timeout() { + echo "Timeout reached!" + kill 0 # Kills the current process group +} + +trap handle_timeout ALRM + +function process_problem() { + # input 1: domain file name + # input 2: problem file name + local domain="$1" + local problem="$2" + + # Parsing + PARSED_FILE="${SCRATCHDIR}/problem.parsed" + pandaPIparser "$domain" "$problem" "$PARSED_FILE" &> "${SCRATCHDIR}/panda-parser.log" + if [[ ! -f "$PARSED_FILE" ]]; then + echo "$PARSED_FILE was not generated by pandaPIparser. Exiting." + return 1 + else + echo "Domain and problem parsed successfully." + fi + + # Grounding + SAS_FILE="${SCRATCHDIR}/problem.sas" + pandaPIgrounder "$PARSED_FILE" "$SAS_FILE" 2> "${SCRATCHDIR}/panda-grounder.stderr" > "${SCRATCHDIR}/panda-grounder.stdout" + if [[ ! -f "$SAS_FILE" ]]; then + echo "$SAS_FILE was not generated. Exiting." + return 2 + else + echo "File grounded successfully." + fi + + # Planner (adapt parameters as required or put them into an additional argument) + SOLUTION_FILE="${SCRATCHDIR}/${problem}.solution" + pandaPIengine "$SAS_FILE" "${SUBOPTIMAL_ARG}" -H "rc2(h=add)" -g none > $SOLUTION_FILE 2> "${SCRATCHDIR}/panda-engine.stderr" + if [[ ! $? ]]; then + echo "Failed to successfully generate a plan. Output in ${SCRATCHDIR}." + return 3 + fi + + HDDL_PLAN=${problem}-plan.hddl + pandaPIparser -c "${SOLUTION_FILE}" "${HDDL_PLAN}" + cp "${HDDL_PLAN}" "${SCRATCHDIR}/" + echo "Successfully found a plan, written to ${HDDL_PLAN}" + + if ! $SAVE_TEMPDIR ; then + rm -r "$SCRATCHDIR" + fi + + return 0 +} + + +( + # Run the function in the background + process_problem "$1" "$2" +) & + +# Wait for the function or the timeout +sleep "${TIMEOUT_SECONDS}" && kill -ALRM $$