Perception, Decision, and Control

The following is the documentation for the modules in the Perception, Decision, and Control package.

Data Processing

The processing of input data in the perception part is structured as a directed acyclic graph. There may be multiple data source nodes, but only one sink node. This approach allows parallel processing of data from multiple sources. Intermediate nodes of the graph may use classes defined in this module to process the data.

Inheritance diagram

Inheritance diagram of pdc.dp


class pdc.dp.Filter

Base class for the filters.


Process curr, return processed.


curr – Float or dict. Measured value.


Abstract. To be implemented by Filter subclasses.

class pdc.dp.FiltersChain(*filters)

Chain multiple filters that are run in sequence.

When any of the filters fails, the whole FiltersChain fails. To avoid problems of sharing filters between FiltersChain classes (it’s Python) in FiltersChain constructor always call Filter constructor:


A list of filters to be applied.


Run multiple filters on curr, stop if any of the filters fails.

class pdc.dp.LowPassFilter(weight=0.5, keys=[])



Compute value of curr in Low-Pass filter fashion.

class pdc.dp.AlphaBetaFilter(a=0.85, b=0.005, x=None, v=None, dt=0.1, keys=[])



Compute value of curr in AB filter fashion.

Behavior, Query, and State

The decision and control part is structured as a directed, possibly cyclic graph. The following describes Behavior, Query, and State (BQS) classes. TL;DR: transfer between states of FSM is done by BT.

Behavior nodes correspond to control flow nodes of Behavior Tree (BT). Query nodes correspond to condition nodes of BT. State nodes correspond to root of BT, action nodes of BT, as well as states of Finite State Machine (FSM). BQS differences to BT and FSM are discussed bellow.

Behavior nodes are non-leafy nodes with the member children, which is a list of other BQS nodes. The children nodes are processed in an order corresponding to the behavior of the node subclass. The return value of the decide() method is also specific to the node subclass.

Examples of Behavior nodes are Sequence, Fallback, and Not.

Query nodes are leaf nodes that query the world in read-only fashion. The decision process cannot stop at the Query node.

Examples of Query nodes are AlwaysTrue and AlwaysFalse.

State nodes are leaf nodes where the decision process begins and ends. Every State node is the root of BT and must have had some Behavior node assigned to the change_state member.

Behavior and Query nodes must implement _decide() method.

State nodes are expected to implement _control() method.

Inheritance diagram

Inheritance diagram of pdc.bqs

Comparison to FSM

Compared to FSM, BQS has framework for transition between states. change_state is the root of the BT, the destination states are State leaves of that BT.

Comparison to BT

BQS can simulate BT when only one behavior is specified and assigned to change_state member of every State.

Each call to decide() always returns some object or False. The running state known from BT is not possible because BT is only used to change between (FSM) states. (To change between BT actions.)


Each BQS node has world member. World is shared between BQS nodes and contain the perceived information, the history, and the status (of the world).

It is possible to define multiple worlds and then assign different BQS nodes to different worlds. To share information between worlds, the State nodes of the first world can implement method that updates the second world, i.e., the _control(world) method.


class pdc.bqs.World(history_len=2)

History and status of the world.


Return current (last set) State.


Return (element of) current (last update of) world.


Include BQS nodes into the self (world).


nodes – Subclasses of BQS Node.


Begin addition of new world. Must be atomic.


Add new blank world into the history. Must be atomic.


Add copy of the last world into the history. Must be atomic.


Add new world from keywords. Must be atomic.


New world has been added, mark for read. Must be atomic.

class pdc.bqs.Node

Base node of BQS graph.

decide(*args, **kwargs)

Make a decision, return obj or False. Calls _decide().


Abstract. To be implemented by Decision subclasses.

control(*args, **kwargs)

Run a controller. Calls _control().


Abstract. To be implemented by Control subclasses.

world = <pdc.bqs.World object>

Shared history of the world.

class pdc.bqs.Behavior(*children)

Non-leaf decision node of BQS graph.

No query to world. Just tick children.

Subclasses must implement _decide() method.


A list of Node instances to be evaluated.

class pdc.bqs.Query

Read-only query to world.

Leaf node of BQS, but can’t end deciding here.

Subclasses must implement _decide() method.

class pdc.bqs.State

Leaf node where decision process begins and ends.

Read-only query to world.

Subclasses must have a Behavior assigned to change_state member.

Subclasses must implement _control() method.


Set self as the beginning state.


Transfer between states.

Needs Behavior assigned to the change_state. Return True if the State of the world has been changed and False otherwise.

class pdc.bqs.Sequence(*children)

-> in BT.


Return the last child’s return if all children succeed or False.

class pdc.bqs.Fallback(*children)

? in BT.


Return the first successfull child’s return or False.

class pdc.bqs.Not(*children)

Negation. For one child only.


Return negation of the first child.

class pdc.bqs.AlwaysTrue

Always return True.


Return True.

class pdc.bqs.AlwaysFalse

Always return False.


Return False.