/GOApy

Goal-Oriented Action Planning implementation in Python

Primary LanguagePythonBSD 2-Clause "Simplified" LicenseBSD-2-Clause

GOAPy

Build Status Coverage Status PyPI version

Version: 0.2.0

GOAPy

Goal-Oriented Action Planning (GOAP) implementation in Python

Introduction

GOAP is a real-time planning algorithm for autonomous agents (AA). AA are able to create an action planning based on a set of actions available to the AA.

The Planner class searches for the correct set of actions from an initial state to it' goal. To perform the search the planner sets a graph using the possible world states as nodes and the available actions as edges of the graph. To search for the shortest path it uses the A* algorithm.

Usage

Using the AutomatonController class

From the AutomatonController class perspective the usage and interaction should be:

from Goap.Action import Actions
from Goap.Sensor import Sensors
from Goap.Automaton import AutomatonController


def setup_sensors():
    """ Setup your automaton sensors.
        The sensors are a collection of linux shell commads or python callables (functons or objects)
    """
    sensors = Sensors()
    # add a shell sensor that will check if a directory exist and returns a string with
    # "exists" or "not_exist"
    # The return string will update the automaton's world state
    sensors.add(
        name='SenseTmpDirState',
        shell='if [ -d "/tmp/goap_tmp" ]; then echo -n "exist"; else echo -n "not_exist"; fi',
        binding='tmp_dir_state'
    )
    sensors.add(
        name='SenseTmpDirContent',
        shell='[ -f /tmp/goap_tmp/.token ] && echo -n "token_found" || echo -n "token_not_found"',
        binding='tmp_dir_content'
    )
    return sensors


def setup_actions():
    actions = Actions()
    actions.add(
        name='CreateTmpDir',
        pre_conditions={'tmp_dir_state': 'not_exist', 'tmp_dir_content': 'token_not_found'},
        effects={'tmp_dir_state': 'exist', 'tmp_dir_content': 'token_not_found'},
        shell='mkdir -p /tmp/goap_tmp'
    )
    actions.add(
        name='CreateToken',
        pre_conditions={'tmp_dir_state': 'exist', 'tmp_dir_content': 'token_not_found'},
        effects={'tmp_dir_state': 'exist', 'tmp_dir_content': 'token_found'},
        shell='touch /tmp/goap_tmp/.token'
    )
    return actions


def setup_automaton():
    world_state_matrix = {
        "tmp_dir_state": 'Unknown',
        "tmp_dir_content": 'Unknown',
    }
    automaton = AutomatonController(
        name='directory_watcher',
        actions=setup_actions(),
        sensors=setup_sensors(),
        world_state=world_state_matrix
    )
    return automaton


def main():
    goal = {
        "tmp_dir_state": "exist",
        "tmp_dir_content": "token_found",
    }
    dir_handler = setup_automaton()
    dir_handler.goal = goal
    dir_handler.start()


if __name__ == '__main__':
    main()