这里写目录标题
1. 安装FAST DOWNWARD
使用官网教程安装FAST DOWNWARD。按照官方的BUILD.md安装即可。
官方使用文档解读
使用fast-downward.py驱动程序脚本,需要指定PDDL输入文件和搜索算法。提供的搜索算法有:A* search (eager),Eager best-first search,Greedy search (eager),Eager weighted A* search,Lazy enforced hill-climbing,Iterated search,Lazy best-first search,Greedy search (lazy),(Weighted) A* search (lazy)。输入命令时可以通过加入诸多选项,从而单独运行规划器、或运行计划验证器等。
可以多个版本共存,但是需要通过build参数明确使用的版本。无异常情况下,代码返回0;如果发生错误返回其他代码,可以参考exit_code。
LP支持:CPLEX与SoPLEX,注意后者只能用来解决整数规划问题。
关于VAL的配置,在编译完成后会生成一个validate的可执行文件。注意将该文件的路径添加到系统环境变量PATH中。例如我将生成的validate转移至/downward文件下,于是在系统文件中添加途径如下:
sudo vim ~/.bashrc
export PATH="$PATH:/home/zz/downward/"
source ~/.bashrc:
为了增加更多的功能,按照官方链接继续安装。注意,这里我首先在downward文件夹下使用catkin_make编译后,然后参照官方命令完成安装,否则会发生找不到一些可执行文件的报错。
catkin_make
cmake -S src -B builds/mycustombuild
cmake --build builds/mycustombuild
*安装CPLEX
这里需要自己去IBM官网申请许可证,可以使用教育版CPLEX,官网地址。切换到安装包所在目录下,执行如下:
chmod +x cos_installer_preview-22.1.1.0.R0-M08SWML-linux-x86-64.bin
./cos_installer_preview-22.1.1.0.R0-M08SWML-linux-x86-64.bin
选择语言,选择自己的安装路径
sudo vim ~/.bashrc
export cplex_DIR=/home/zz/CPLEX/cplex
export PATH="$PATH:/home/zz/CPLEX/cplex/bin/x86-64_linux/:/home/zz/CPLEX/cpoptimizer/bin/x86-64_linux/"
source ~/.bashrc
验证是否能被规划器正常调用:
./fast-downward.py misc/tests/benchmarks/miconic/s1-0.pddl --search "astar(operatorcounting([lmcut_constraints()]))"
出现如下输出证明安装成功:
2. 示例使用
进入fastdownward.py所在目录下。
usage: fast-downward.py [-h] [-v] [--show-aliases] [--run-all] [--translate]
[--search]
[--translate-time-limit TRANSLATE_TIME_LIMIT]
[--translate-memory-limit TRANSLATE_MEMORY_LIMIT]
[--search-time-limit SEARCH_TIME_LIMIT]
[--search-memory-limit SEARCH_MEMORY_LIMIT]
[--validate-time-limit VALIDATE_TIME_LIMIT]
[--validate-memory-limit VALIDATE_ME(define (domain miconic)
(:requirements :strips)
(:predicates
(origin ?person ?floor )
;; entry of ?person is ?floor
;; inertia
(floor ?floor)
(passenger ?passenger)
(destin ?person ?floor )
;; exit of ?person is ?floor
;; inertia
(above ?floor1 ?floor2 )
;; ?floor2 is located above of ?floor1
(boarded ?person )
;; true if ?person has boarded the lift
(served ?person )
;; true if ?person has alighted as her destination
(lift-at ?floor )
;; current position of the lift is at ?floor
)
;;stop and allow boarding
(:action board
:parameters (?f ?p)
:precondition (and (floor ?f) (passenger ?p)(lift-at ?f) (origin ?p ?f))
:effect (boarded ?p))
(:action depart
:parameters (?f ?p)
:precondition (and (floor ?f) (passenger ?p) (lift-at ?f) (destin ?p ?f)
(boarded ?p))
:effect (and (not (boarded ?p))
(served ?p)))
;;drive up
(:action up
:parameters (?f1 ?f2)
:precondition (and (floor ?f1) (floor ?f2) (lift-at ?f1) (above ?f1 ?f2))
:effect (and (lift-at ?f2) (not (lift-at ?f1))))
;;drive down
(:action down
:parameters (?f1 ?f2)
:precondition (and (floor ?f1) (floor ?f2) (lift-at ?f1) (above ?f2 ?f1))
:effect (and (lift-at ?f2) (not (lift-at ?f1))))
)
MORY_LIMIT]
[--overall-time-limit OVERALL_TIME_LIMIT]
[--overall-memory-limit OVERALL_MEMORY_LIMIT]
[--alias ALIAS] [--build BUILD] [--debug] [--validate]
[--log-level {debug,info,warning}] [--plan-file FILE]
[--sas-file FILE] [--keep-sas-file] [--portfolio FILE]
[--portfolio-bound VALUE] [--portfolio-single-plan]
[--cleanup]
INPUT_FILE1 [INPUT_FILE2] [COMPONENT_OPTION ...]
EXAMPLES:
("Translate and find a plan with A* + LM-Cut:",
["misc/tests/benchmarks/gripper/prob01.pddl",
"--search", '"astar(lmcut())"']),
("Translate and run no search:",
["--translate",
"misc/tests/benchmarks/gripper/prob01.pddl"]),
("Run predefined configuration (LAMA-2011) on translated task:",
["--alias", "seq-sat-lama-2011", "output.sas"]),
("Run a portfolio on a translated task:",
["--portfolio", str(EXAMPLE_PORTFOLIO),
"--search-time-limit", "30m", "output.sas"]),
("Run the search component in debug mode (with assertions enabled) "
"and validate the resulting plan:",
["--debug", "output.sas", "--search", '"astar(ipdb())"']),
("Pass options to translator and search components:",
["misc/tests/benchmarks/gripper/prob01.pddl",
"--translate-options", "--full-encoding",
"--search-options", "--search", '"astar(lmcut())"']),
("Find a plan and validate it:",
["--validate",
"misc/tests/benchmarks/gripper/prob01.pddl",
"--search", '"astar(cegar())"']),
("Predefine an evaluator (new style):",
["misc/tests/benchmarks/gripper/prob01.pddl",
"--search", '"let(hff, ff(), eager_greedy([hff], preferred=[hff]))"']),
("Predefine an evaluator (old style):",
["misc/tests/benchmarks/gripper/prob01.pddl",
"--evaluator", '"hff=ff()"', "--search", '"eager_greedy([hff], preferred=[hff])"']),
上述是fast downward中一些接口的调用方法,挑选一些示例进行测试:
(1) 使用A* + LM-Cut算法生成计划
./fast-downward.py misc/tests/benchmarks/gripper/prob01.pddl --search "astar(lmcut())"
终端显示“Solution found.”
并且在同目录下生成sas_plan文件。
(2)只是将pddl文件翻译成sas文件
./fast-downward.py --translate misc/tests/benchmarks/gripper/prob01.pddl
终端返回exec_code 0 ,并在同目录下生成output.sas文件。
(3)使用(LAMA-2011) 算法在翻译得到的sas系统上完成规划
./fast-downward.py --alias seq-sat-lama-2011 output.sas
(4)debug模式下运行
使用命令前需安装debug
./build.py debug
./fast-downward.py --debug output.sas --search "astar(ipdb())"
(5)根据给出的problem.pddl文档生成plan并验证
./fast-downward.py --validate misc/tests/benchmarks/gripper/prob01.pddl --search "astar(cegar())"
3. 官方pddl文件示例解析
domain.pddl文件
(define (domain miconic)
(:requirements :strips)
定义domain域的名称为miconic,并且声明使用STRIPS表示法。
(:predicates
(origin ?person ?floor )
;; entry of ?person is ?floor
;; inertia
(floor ?floor)
(passenger ?passenger)
(destin ?person ?floor )
;; exit of ?person is ?floor
;; inertia
(above ?floor1 ?floor2 )
;; ?floor2 is located above of ?floor1
(boarded ?person )
;; true if ?person has boarded the lift
(served ?person )
;; true if ?person has alighted as her destination
(lift-at ?floor )
;; current position of the lift is at ?floor
)
;;stop and allow boarding
origin关键字描述人与所处楼层的关系,floor和passenger关键字用来确认人和电梯的身份,destin关键字用来表述人的目标楼层,above关键字用来表述楼层之间的关系,boarded表述人是否登上电梯, serverd关键字用来表述人是否被服务,lift-at 描述电梯当前停靠的楼层。
(:action board
:parameters (?f ?p)
:precondition (and (floor ?f) (passenger ?p)(lift-at ?f) (origin ?p ?f))
:effect (boarded ?p))
动作前置条件,确认楼层,确认乘客,确认电梯在f层,确认乘客在f层。
动作的影响,乘客处于boarded状态。
(:action depart
:parameters (?f ?p)
:precondition (and (floor ?f) (passenger ?p) (lift-at ?f) (destin ?p ?f)
(boarded ?p))
:effect (and (not (boarded ?p))
(served ?p)))
;;drive up
动作前置条件,确认楼层,确认乘客,确认电梯停留在当前楼层,确认当前楼层是乘客目标楼层,确认乘客处于登入电梯boarded状态。
动作影响,乘客离开boarded状态,乘客被服务。
(:action up
:parameters (?f1 ?f2)
:precondition (and (floor ?f1) (floor ?f2) (lift-at ?f1) (above ?f1 ?f2))
:effect (and (lift-at ?f2) (not (lift-at ?f1))))
动作前置条件,确认楼层1,确认楼层2 ,已知电梯停留在楼层1,已知楼层2在楼层1上。
动作影响,电梯在楼层2,电梯离开楼层1。
;;drive down
(:action down
:parameters (?f1 ?f2)
:precondition (and (floor ?f1) (floor ?f2) (lift-at ?f1) (above ?f2 ?f1))
:effect (and (lift-at ?f2) (not (lift-at ?f1))))
)
该动作理解方式同上。
problem.pddl文件
(define (problem mixed-f2-p1-u0-v0-g0-a0-n0-A0-B0-N0-F0-r0)
(:domain miconic)
(:objects p0
f0 f1 )
定义问题名称,引入问题使用的domain,声明问题需要的参数p0, f0, f1。
(:init
(passenger p0)
(floor f0)
(floor f1)
(above f0 f1)
(origin p0 f1)
(destin p0 f0)
(lift-at f0)
)
初始化乘客参数p0,楼层参数f0,f1, 声明f1在f0上,声明乘客p0初始状态下在楼层f1,目标楼层为f0.当前电梯停留在楼层f0。
(:goal (and
(served p0)
))
)
目标为乘客被成功served,即到达其目标楼层f0。我们来看规划器生成的plan:
(up f0 f1)
(board f1 p0)
(down f1 f0)
(depart f0 p0)
; cost = 4 (unit cost)
首先,电梯从f0升到f1,乘客登上电梯,电梯从f1下降到f0,乘客离开电梯,完成目标。