Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions pandaSolver
Original file line number Diff line number Diff line change
@@ -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] <domain file> <problem file>"
echo "Run the Panda planner (parser, grounder, engine) on <domain file> and <problem file>."
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 $$