Skip to main content

No project description provided

Project description

bscript

PyPI - Version PyPI - Python Version


bscript

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

tasks are callable singletons which wrap a generator and can be called like regular functions:

@task
def foo():
    yield 1
    return 2

assert foo() == 1
assert foo() == 2
assert foo() == 1

These "state based functions" can be used to describe complex and deliberate hierarchical behaviors:

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

    # implicit return Success

Table of Contents

Installation

# only available for python >= 3.13
pip install bscript

Basics

  • a node is usually a task -- which is a superset of a function
    • (finite state machine-ish nodes are also available)
  • each node in the hierarchy should usually return either Running (== True) or Success (== None)
  • when a node finishes its execution without returning or yielding a value, it implicitly returns None (== Success)
  • a Failure is an exception and must be raised (and caught)

actions

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

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

or as a generator:

@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 peel_banana(): yield Running
    while eat_banana(): yield Running

    # Success (implicit return None / Success)

failures and fallbacks

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

parallel execution of behaviors

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

conditions

@task
def emergency():
    # callers can make decisions based on whether this task is Running or not
    if random() > 0.9:
        yield Running
        yield Running # always running for 2 frames in a row

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

conditional parallel execution

@task
def attend_talk():
    while listen_to_talk():
        if new_message():
            read_message()
        elif hungry():
            eat_an_apple()
        yield Running

how this works

tasks

tasks are generators -- a superset of functions -- that can be called like functions. They are implemented as callable singeltons and update their parameters (local variables inside the generator namespace). 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
    # implicit return None, like regular functions

assert foo_pass() == None

@task
def foo_return():
    return 1

assert foo_return() == 1

@task
def foo_yield():
    yield 1
    # implicit return None

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

@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

bscript defines the states Running and Success. It turns out defining them like this...

Running = True
Success = None

...has pretty interesting properties, especially since each function or task always returns something -- explicitly or implicitly None:

assert True is Running is not Success
assert None is Success is not Running

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

def always_running():
    return Running

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

assert always_running() is Running
assert always_running() is not Success

while and if in combination with Running & 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:

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.2.tar.gz (11.4 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.2-py3-none-any.whl (7.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for bscript-0.0.2.tar.gz
Algorithm Hash digest
SHA256 f3d8feac17f991f2232cc0962f82012e98a4543373babba2b33489fbd4e6ecf5
MD5 6ef73cec5fb348da2b798553de62079d
BLAKE2b-256 8943f50213ad4c1547897be055742fb5cda363a3f2452fc436f082e81b18af27

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for bscript-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 9117eacacaf2e1c5274f67509f3d7ee4728428b6803ebbb4466db6f4c4d3b682
MD5 a45e325f26ec0dc8613cff8e8a683448
BLAKE2b-256 80e44d813a000287729178d979b3eeeecf7938f1075bbebfcb3aa839a636122b

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