sposh-core 3.6.1-SNAPSHOT API

This library contains Yaposh, dynamic planner based on SPOSH.

See:
          Description

Packages
cz.cuni.amis.pogamut.shady Shady - experimental POSH-like engine.
cz.cuni.amis.pogamut.sposh Classes and interfaces used with behavior class.
cz.cuni.amis.pogamut.sposh.context Context is an object shared among all primitives of the plan.
cz.cuni.amis.pogamut.sposh.elements This package contains parser for Yaposh plan, classes that represent elements of the plan and some auxiliry classes.
cz.cuni.amis.pogamut.sposh.engine Yaposh engine and its executors used to evaluate yaposh plan.
cz.cuni.amis.pogamut.sposh.engine.timer  
cz.cuni.amis.pogamut.sposh.exceptions  
cz.cuni.amis.pogamut.sposh.executor Classes for creation and execution of primitives.

 

This library contains Yaposh, dynamic planner based on SPOSH.

This library contains

Structure of Yaposh plan

Yaposh is quite similar to behavior trees, the plan itself is a Directed Acyclic Graphs (DAG). The root node of Yaposh plan is called DriveCollection (DC).

DC is a root of the plan, but not the object that stores all nodes of the plan, that would be PoshPlan. The PoshPlan contains DC of plan and all action patterns, comepetnces and adopts of the plan.

The DC has several children (at least one) called drives (DriveElement). Each drive consists from its name, trigger and reference to some other node. The trigger is a condition that must be satisfied in order for drive to be elegible for selection.

DC can also have a goal, condition that specifies when the agent has fulfilled its goal in the environment. If goal is satisfied, there is no need to evaluate the rest of the plan.

The reference to some other node is called TriggeredAction. The referenced node can be action(A), competence (C) or action pattern (AP), but not CompetenceElement or DriveElement nor Sense. Each node that can be referenced (A/AP/C) has a name. When TriggeredAction references another node, it specifies name of referenced node and arguments passed to the referenced node (e.g. name "move-home" and argument $speed=5). The engine will take the name (e.g. "move-home") and finds node with identical name (A/AP/C).

Action node is a leaf that is not defined in the plan. It is defined outside of the plan and it is responsibility of the IWorkExecutor to connect referenced name to correct action and execute the action. Actions of Yaposh are classes implementing the IAction interface.

Action patterns (AP) are nodes that represent sequence, each AP has a list of references to other nodes (actions or another APs) and its job is to execute referenced nodes in specified sequence.

Competence node is a priority selector, the competence has several (at least one) children of type CompetenceElement called choices. The choice consists from name of choice, trigger and reference to another node. Job of competence is to select one of its choices.

User shouldn't use constructors of nodes, but LapElementsFactory factory instead.

Execution of the plan

The plan works by executing nodes. Each drive has its own stack of executors, note that thare are multiple stacks. The plan is executed in steps, in each step, stack of some drive is changed. Step of the plan starts with selection of drive that should be executed. That is done by selecting first drive (i.e. the one with highest priority) with satisfied trigger.

Once drive is selected, we look at its stack and if it is empty, add executor of referenced node to the top of the stack. If drive stack is not empty, take the executor at the top of the stack and execute it. It will do execute the node and return value that says how should engine change the drive stack (e.g. add executor for another element at the top, remove top executor, clear the stack...).

We will now describe executors for nodes (they are being executed is they are on top of the drive stack).

Executor of action will take the name of action and asks IWorkExecutor to execute the action and according to returned ActionResult change stack (running - remove the executor on the top, failed - clear stack).

Executor of action pattern keeps an index into the list of its node references. Each time it is executed, it takes the referenced node with specified index and adds its executor to the top of stack. If executor has executed all its references, it removes itself from the stack.

Executor of competence finds its first choice with satisfied trigger and adds executor of the referenced node from the choice to the top of the stack.

        // plan id is used by LapPath, e.g. /P:1/.. is plan with id 1 
        int planId = 0;
        PoshPlan plan = parsePlan(planSource);
        ITimer timer = new SystemClockTimer(); 
        PoshEngine = new PoshEngine(planId, plan, timer, Logger.getLogger("Yaposh"));
        
        
        // Work executor that actually executes the primitives
        IWorkExecutor workExecutor = getWorkExecutor();
        // Execute the executor of the selected drive
        EvaluationResultInfo result = engine.evaluatePlan(workExecutor);
    

Parsing Yaposh plan

You can parse plan using PoshParser, see grammar file poshParser.jj.

        Reader planReader = new StringReader(....);
        PoshParser parser = new PoshParser(planReader);
        PoshPlan parsedPlan = parser.parsePlan();
    

Primitives

Action and sense nodes of the plan are called primitives, they are the only nodes that actually interact with the environment or agent, either by retrieving info (sense) or by changing something (action).

Primitives are executed by a class implementing IWorkExecutor, best one is StateWorkExecutor (also used by Yaposh). This executor uses instances of classes as primitives, classes implementing ISense are senses and classes implementing IAction are actions. The plan is using fully qualified names (FQN) of the classes as reference to the primitives, e.g. "cz.cuni.Turn" is a reference in the plan to an action node of the plan.

FQN names of classes are rather unpleasant for normal work with primitives, the primitive classes can have human readable name annotated using @PrimitiveInfo. The data from the annotation are used in the editor of plans Shed and the debugger Dash, so user won't see FQN, but the name specified in the annotation.

User can implement the primitive simply by implementing interface IAction, but it is better to use one of provided abstract classes:

    @PrimitiveInfo(name = "See player", description = "Does agent see any player?")
    public class SeePlayer extends StateSense<FollowContext, Boolean> {

        public SeePlayer(FollowContext ctx) {
            super(ctx);
        }

        @Override
        public Boolean query(VariableContext params) {
            return ctx.getPlayers().canSeePlayers();
        } 
    }
    

Example sense SeePlayer, it will have name "See player" in Shed editor.



Copyright © 2014 AMIS research group, Faculty of Mathematics and Physics, Charles University in Prague, Czech Republic. All Rights Reserved.