5. Simulated Effects

This python notebook shows the simulated effects usage in the unified planning library.

Open In GitHub Open In Colab

5.1. Setup

First, we install unified_planning library and its dependencies from PyPi. Here, we use the --pre flag to use the latest development build.

[1]:
%pip install unified-planning[tamer]

We are now ready to use the Unified-Planning library!

5.2. Demo

5.2.1. Basic imports

The basic imports we need for this demo are abstracted in the shortcuts package.

[2]:
from unified_planning.shortcuts import *

5.2.2. Problem definition

We start the problem modeling defining the UserType and the Fluent.

[3]:
Location = UserType('Location')
Robot = UserType('Robot')

at = Fluent('at', Location, robot=Robot)
battery_charge = Fluent('battery_charge', IntType(0, 100), robot=Robot)

We define an action move with a simulated effect that models the battery consumption.

A SimulatedEffect instance can affect a list of fluent expressions, in this case only battery_charge(robot). The function fun performs the computation of the simulated effect decreasing the battery value by 10. This function receives as parameters the problem, the state in which the effect is applied, and the actual parameters of the action instance whose effect is being calculated.

[4]:
move = InstantaneousAction('move', robot=Robot, l_from=Location, l_to=Location)
robot = move.parameter('robot')
l_from = move.parameter('l_from')
l_to = move.parameter('l_to')
move.add_precondition(Equals(at(robot), l_from))
move.add_precondition(GE(battery_charge(robot), 10))
move.add_precondition(Not(Equals(l_from, l_to)))
move.add_effect(at(robot), l_to)
def fun(problem, state, actual_params):
    value = state.get_value(battery_charge(actual_params.get(robot))).constant_value()
    return [Int(value - 10)]
move.set_simulated_effect(SimulatedEffect([battery_charge(robot)], fun))

Finally, we define the Object instances and, after creating the Problem, we set the initial values and the goal.

[5]:
l1 = Object('l1', Location)
l2 = Object('l2', Location)
r1 = Object('r1', Robot)

problem = Problem('robot_with_simulated_effects')
problem.add_fluent(at)
problem.add_fluent(battery_charge)
problem.add_action(move)
problem.add_object(l1)
problem.add_object(l2)
problem.add_object(r1)

problem.set_initial_value(at(r1), l1)
problem.set_initial_value(battery_charge(r1), 100)

problem.add_goal(Equals(at(r1), l2))

5.2.3. Solving the problem

We solve the problem automatically selecting a suitable planner.

[6]:
with OneshotPlanner(problem_kind=problem.kind) as planner:
    result = planner.solve(problem)
    print("%s returned: %s" % (planner.name, result.plan))
NOTE: To disable printing of planning engine credits, add this line to your code: `up.shortcuts.get_environment().credits_stream = None`
  *** Credits ***
  * In operation mode `OneshotPlanner` at line 1 of `/tmp/ipykernel_153950/3190604266.py`, you are using the following planning engine:
  * Engine name: Tamer
  * Developers:  FBK Tamer Development Team
  * Description: Tamer offers the capability to generate a plan for classical, numerical and temporal problems.
  *              For those kind of problems tamer also offers the possibility of validating a submitted plan.

Tamer returned: [move(r1, l1, l2)]