Skip to main content

No project description provided

Project description

bscript

PyPI - Version PyPI - Python Version


Table of Contents

bscript

Only works with python>=3.13.

bscript is a behavior specification library for agents respectively robots. It is similar to hierarchical finite state machine approaches, but primarily uses decorated python generators -- called tasks -- instead of finite state machines. bscript enables an imperative scripting like approach to behavior engineering.

tasks are callable singletons which wrap a "global" generator state for each underlying generator. These "state based functions" can be used to describe complex and deliberate hierarchical behaviors.

from bscript import task, Running

@task
def travel():
    while walk_to(next_bus_stop()): listen_to_music() and eat_an_apple()
        yield Running

    while not destination_reached(): sit_in_bus() and (read_a_book() or idle())
        yield Running
    ...

this should pretty much do what you literally read....

Installation

pip install bscript

Basics

python functions

in this context particular important properties of regular python functions (and tasks aswell)

def foo():
    pass
    # implicit return None

assert foo() == None

def bar():
    return # implicit None

assert bar() == None

tasks

tasks are generators -- a super set of functions -- that can be called "like functions". They have a global state each and their parameter get updated at each call. tasks are implemented as callable singeltons. Furthermore they update their parameters (local variables inside the generator namespace) at each call and a StopIteration is transformed into a return statement like behavior.

A task is pretty much a "function with an internal state" or a "function with yield statements".

yield and return statements can be mixed inside python generators -- and therefor inside tasks aswell. They behave as expected:

  • yield returns a value and resumes the execution
  • return returns a value and restarts the execution

the result is pretty similar to functions:

from bscript import task

@task
def foo_pass():
    pass

assert foo_pass() == None

@task
def foo_return():
    return 1

assert foo_return() == 1

@task
def foo_yield():
    yield 1

assert foo_yield() == 1
assert foo_yield() == None

@task
def foobar():
    yield 1
    yield 2
    return 99
    yield 4

assert foobar() == 1
assert foobar() == 2
assert foobar() == 99
assert foobar() == 1

@task
def foox(x):
    yield x
    yield x

assert foox(4) == 4
assert foox(9) == 9
assert foox(1) == None

Running, Success, Failure

inspired by behavior trees, bscript defines the states Running, Success and Failure. It turns out defining them like this...

Running = True
Success = None
class Failure(Exception): ...

...has pretty interesting properties, especially since each function or task always returns something -- explicitly or implicitly None (which is equivalent to Success):

from bscript import Running, Success

assert Running is not Success
assert Success is not Running

def always_successful():
    pass
    # implicit return None / Success

def always_running():
    return not None

assert always_successful() is Success
assert always_successful() is not Running

assert always_running() is Running
assert always_running() is not Success
  • while do_something() is equivalent to

    • while do_something() is Running
    • while do_something() is not Success
  • if something() is equivalent to:

    • if something() is Running
    • if something() is not Success
  • do_something() and do_something_else() is equivalent to

    • if do_something() is Running: do_something_else()
    • if do_something() is not Success: do_something_else()
  • do_something() or do_something_else() is equivalent to

    • if do_something() is not Running: do_something_else()
    • if do_something() is Success: do_something_else()
  • a Failure is raised and traverses up the behavior tree until it gets caught

All those sentences are valid python code and actually work when all nodes use Running and Success as return values.

These are the basic building blocks for bscript behaviors.

actions

low level nodes that execute actions can often be written as regular functions:

def drive_to(target):
    output().target = target
    return Success if target_reached(target) else Running

or as a task:

@task
def drive_to(target):
    while not target_reached(target):
        output().target = target
        yield Running

    # Success (implicit return None / Success)

high level behaviors

sequence of sub behaviors

@task
def eat():
    while peal_banana(): yield Running
    while eat_banana(): yield Running

    # Success (implicit return None / Success)

failures and fallbacks

If a (sub) behavior raises a Failure (Exception) it traverse upwards the call tree until it gets caught and handled -- as exceptions naturally do, which complies with behavior tree failures and makes a lot of sense in behaviors:

@task
def eat():
    try:
        while eat_banana(): yield Running
    except Failure:
        while eat_apple(): yield Running

parallel execution of behaviors

@task
def travel():
    while walk_to(next_bus_stop()): listen_to_music() and eat_an_apple()
        yield Running

    while not destination_reached(): sit_in_bus() and (read_a_book() or idle())
        yield Running

    ...

conditions

@task
def emergency():
    if random() > 0.9:
        yield "ALARM"
        yield "ALARM"

    # implicit return None == not Running

def some_behavior():
    if emergency():
        run_away()
        return Running
    else:
        return do_something()

this is similar to behavior tree decorators

finite state machin-ish nodes, context handling, input & output and more

-> docs/details.md

Examples

The lunch behavior and the irsim behavior show basic example applications.

License

bscript is distributed under the terms of the MIT license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

bscript-0.0.1.tar.gz (13.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

bscript-0.0.1-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file bscript-0.0.1.tar.gz.

File metadata

  • Download URL: bscript-0.0.1.tar.gz
  • Upload date:
  • Size: 13.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.28.1

File hashes

Hashes for bscript-0.0.1.tar.gz
Algorithm Hash digest
SHA256 bbceb1f96c5c7776a5166d920df1e8fe4c68d350e7130ebc9a943c84dc001ea0
MD5 02fdf9818d79fcd608b450efc0004166
BLAKE2b-256 87d94ecddab5f7e5a0615599c4f8f29d25103f857bb759bf946a81b7c3455aaa

See more details on using hashes here.

File details

Details for the file bscript-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: bscript-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 7.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.28.1

File hashes

Hashes for bscript-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 dd38dee71b694aa357561dd86f3d2609c9159ab8df2b56b9a5a31513cbc616fe
MD5 13d593a66c9c463207587c8940239a3f
BLAKE2b-256 b3b1d279b46e35dfbd2c8e7d99dde82bfa66c0f39a7339f9493cccf3b6e7c18c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page