-
Notifications
You must be signed in to change notification settings - Fork 0
PDDL other types of planning
🔗 more info here
🔗 see planning.wiki
In classical PDDL you cannot give specifications about the objects in the worlds, since they are given in the problem statement. You can perform checks about the "type of the objects" (the "trivial checkings" to check before the main checks in each action precondition), but you cannot give objects neither characteristics of objects except by means of predicates.
some PDDL extension includes types: simply give a type to a parameter. Take into account only these small changes on the syntax of parameters and instances:
-
the requirement to use to apply the typing is
:typing
-
the domain contains a new tag
(types ...list of objects...)
. Each type could have a subtype; the most general (subsumed) type isobject
.for example,
;; all the types here are objects (:types site material ) ;; also this works (:types site - object material ) ;; and other variations upon the same leitmotiv ... ;; a bit cumbersome... you can sub-typing, but better to ;; not use this functionality (:types site material - object bricks cables windows - material )
-
in order to specify the type of a generic parameter, write
?param - param_type
. -
in case of many params, simply list them before spcifying the type, or give a type for each of them.
?p1 ?p2 ?p3 - tp
or?p1 - tp ?p2 - tp ?p3 - tp
. This syntax is required each time you have to declare a parameter: actions, predicates, ... -
do the same thing when you declare the object instances, for example
my-obj - tp
, or also with the listing,o1 o2 o3 - tp
. Take into account that PDDL is tabulation-free, hence you can do everything you want with this syntax. -
if a type has not been specified, the type
object
is assumed, which is the uppermost class of objects.
🔗 see PDDL2.1 on planning.wiki
🔗 see the requirements of PDDL2.1
Here's an example of requirements for PDDL2.1:
(:requirements :durative-actions :fluents :duration-inequalities)
In particular,
-
:fluents
-- it adds numerical quantities, the so-called fluents or also functions. The planner can change the value of a fluent during the planning, and use it as a predicate. -
:durative-actions
-- it adds another type of action called(:durative-action ...)
which takes into account also the duration of the action. :durative-inequalities
🔗 see also :continuous-effect
requirement on planning.wiki
(:functions
(predicate ?obj1 ?obj2 ...)
;; ...
)
Here are the operations allowed on the fluents. You can use them both in actions or in durative actions.
;; simple operations
(+ (sample-capacity) (battery-capacity))
(- (sample-capacity) (battery-capacity))
(/ (sample-capacity) (battery-capacity))
(* (sample-capacity) (battery-capacity))
;; comparison
;; > , >= , < , <= , =
;; particular operations -- increase and decrease
(increase (battery-level ?r) 10)
(decrease (battery-level ?r) 10)
;; a more complicated form
(increase (battery-level ?r) (charge-available - ?solarpanel))
(decrease (battery-level ?r) (power-needed-for-work - ?task))
;; used a lot -- continuous effect (#t is the frame time)
(increase (fuel ?tank) #t)
(decrease (battery ?battery) (* 5 #t))
;; assignment
(assign (battery-level ?r) 10)
(assign (battery-level ?r) (max-charge ?r))
🔗 see durative actions
(:durative-action <action_name>
:parameters (<arguments>)
:duration (= ?duration <duration_number>)
:condition (logical_expression)
:effect (logical_expression)
)
Condition is interesting. You can specify the conditions at the beginning of the action, at the end of the action, and at the end of the action. In particular, here are the syntaxes:
;; condition before starting the action
(at start (at ?rover ?from-waypoint))
;; condition relative to the end of the action
(at end (>= (battery-amount ?rover) 0))
;; the conditon holds for the entire action
(over all (can-move ?from-waypoint ?to-waypoint))
These statements can be employed even in the :effect
section.
Here below is an example of durative action, just to understand how it works:
(:durative-action move
:parameters
(?r - rover
?fromwp - waypoint
?towp - waypoint)
:duration
(= ?duration 5)
:condition
(and
(at start (rover ?rover))
(at start (waypoint ?from-waypoint))
(at start (waypoint ?to-waypoint))
(over all (can-move ?from-waypoint ?to-waypoint))
(at start (at ?rover ?from-waypoint))
(at start (> (battery-amount ?rover) 8)))
:effect
(and
(decrease (fuel-level ?t) (* 2 #t))
(at end (at ?rover ?to-waypoint))
(at end (been-at ?rover ?to-waypoint))
(at start (not (at ?rover ?from-waypoint)))
(at start (decrease (battery-amount ?rover) 8))
(at end (increase (distance-travelled) 5))
)
)
just use the syntax (= (<predicate> <args>) <value>)
(:init
(= (battery-amount r1) 100)
(= (recharge-rate r1) 2.5)
...
)
We could ask the planner to maximize or minimize a fluent or a list of fluents during the search of a plan.
☝️ This is NOT a replacement of the (:goal ...)
statement, but just a constraint, which could be applied or not. The planner will do (presumably) the best to satisfy this constraint.
;; try to minimize something
(:metric minimize (<numeric_operation>))
;; try to maximize something
(:metric maximize (<numeric_operation>))
It contains many features:
- numerical flows
- types
- processes : they are "durative actions" with a unspecified duration, meaning that the process keeps going as long as the preconditions are met. Each frame, the process applies its effect on the state.
- Events : an event is something "triggered" when the precondition becomes satisfied, and it is applied every time the precondition holds.
☝️ PDDL+ applies processes and events in background, meaning that a process or an event can be triggered every time a precondition becomes satisfied, regardless of the actions the planner could decide to apply. Hence, there are two levels in the planning: the actions (immediate) and the modelled dynamics of the world (the effects of an action and/or external actions by other actors).
☝️ a clever combination of processes and events lets to implement durative actions.
🔗 see requirements for PDDL+
The typical configuration for a PDDL+ domain:
(:requirements :strips :adl :typing :time)
In particular, :time
includes processes and events in your code.
🔗 see processes on planning.wiki
A process starts when the preconditions are met, and goes on until the precondition is satisfied. The syntax is the same as the actions, but with another statement.
The symbol #t
indicates the frame time, useful for continuous updates of the fluents.
(:process FALLING
:parameters (?b - ball)
:precondition (and
(not (held ?b))
(< (velocity ?b) 100)
)
:effect (and
(increase (velocity ?b) (* #t 9.8))
(decrease (distance-to-floor ?b) (* #t (velocity ?b)))
)
)
🔗 see Events on Planning.wiki
An event is triggered when the precondition is met. It could be triggered at each frame if the precondition keeps holding.
(:event HIT-GROUND
:parameters (?b - ball)
:precondition (and
(not (held ?b))
(<= (distance-to-floor ?b) 0)
(> (velocity ?b) 0)
)
:effect (
(assign (velocity ?b) (* -0.8 (velocity ?b)))
)
)