diff --git a/.vscode/settings.json b/.vscode/settings.json index bf6870d6..a5eb0fe7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,11 +2,12 @@ "editor.formatOnSave": true, "black-formatter.importStrategy": "fromEnvironment", "python.testing.pytestArgs": [ - "." + ".", + "--doctest-modules" ], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, "[python]": { "editor.defaultFormatter": "ms-python.black-formatter" } -} +} \ No newline at end of file diff --git a/examples/README.md b/examples/README.md index 48ca6b67..3b9c7113 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,3 +1,113 @@ -# Example Experiments +# Experiment Resources + +This guide provides instructions for creating and structuring resource-file.json, which is used to define the behavior tree and experiment flow for robots. Currently, there are three robots with custom contexts: + +1. Atlas +2. Digit +3. Optimus + + + + +## Breakdown of {robot}-resource-file.json + +Resource files are JSON files made up of key-value pairs. The keys represent subgoals, and their values define the subgoal's context, children, behavior library, and interruptions. + +Here’s an example template: + + +```json +{ + "subgoal_A": { + "context": "...", + "children": [], + "behavior_library": [ + { + "id": "...", + "name": "...", + "in_behavior_bank": false + }, + { + "id": "...", + "name": "...", + "in_behavior_bank": true + } + ], + "interruptions": {} + }, + "subgoal_B": { + "context": "...", + "children": [], + "behavior_library": [ + { + "id": "...", + "name": "...", + "in_behavior_bank": false + }, + { + "id": "...", + "name": "...", + "in_behavior_bank": true + } + ], + "interruptions": {} + } +} +``` + +## Subgoal Structure Breakdown +- Each subgoal is represented by a unique key (e.g., "subgoal_A") with the following fields: + + +### Context +- A string describing the subgoal's background and objectives. + +Example: +```json +"context": "Atlas is assigned to retrieve medicine A from the medicine cabinet..." +``` + + +### Children +- An array of behavior IDs (strings) specifying the execution order of the subgoal's behaviors. +- Important: These IDs must exist in the behavior_library field. + +Example: +```json +"children": [ + "take_path_to_medicine_cabinet", + "unlock_cabinet", + "retrieve_medicine" +] +``` + + +### Behavior Library +- A list of all possible behaviors for the subgoal. +- Each behavior is an object with the following fields: + - id (required): Unique identifier. + - name (required): Description of the behavior. + - in_behavior_bank (optional): true if included in the behavior bank. + +Example: +```json +"behavior_library": [ + { + "id": "take_path_to_medicine_cabinet", + "name": "take acceptable path to the medicine cabinet", + "in_behavior_bank": false + }, + { + "id": "request_medicine", + "name": "request medicine from pharmacist", + "in_behavior_bank": true + } +] +``` + +### Interruptions + +Currently not used. Keep as an empty object: {} + + -This directory includes configuration files for example experiments. \ No newline at end of file diff --git a/examples/abstract-experiment.json b/examples/abstract-experiment.json deleted file mode 100644 index 881b77e8..00000000 --- a/examples/abstract-experiment.json +++ /dev/null @@ -1,129 +0,0 @@ -{ - "behavior_tree": { - "name": "Sequence A", - "type": "Sequence", - "children": [ - { - "name": "Behavior A", - "type": "Behavior", - "children": [] - }, - { - "name": "Behavior B", - "type": "Behavior", - "children": [] - }, - { - "name": "Sequence B", - "type": "Sequence", - "children": [ - { - "name": "Behavior C", - "type": "Behavior", - "children": [] - }, - { - "name": "Behavior D", - "type": "Behavior", - "children": [] - } - ] - }, - { - "name": "Sequence C", - "type": "Sequence", - "children": [ - { - "name": "Behavior E", - "type": "Behavior", - "children": [] - }, - { - "name": "Behavior F", - "type": "Behavior", - "children": [] - }, - { - "name": "Behavior G", - "type": "Behavior", - "children": [] - }, - { - "name": "Behavior H", - "type": "Behavior", - "children": [] - } - ] - } - ] - }, - "behavior_library": [ - { - "id": "001", - "display_name": "Behavior A", - "type": "Behavior", - "show": true - }, - { - "id": "002", - "display_name": "Behavior B", - "type": "Behavior", - "show": true - }, - { - "id": "003", - "display_name": "Behavior C", - "type": "Behavior", - "show": true - }, - { - "id": "004", - "display_name": "Behavior D", - "type": "Behavior", - "show": true - }, - { - "id": "005", - "display_name": "Behavior E", - "type": "Behavior", - "show": true - }, - { - "id": "006", - "display_name": "Behavior F", - "type": "Behavior", - "show": true - }, - { - "id": "007", - "display_name": "Behavior G", - "type": "Behavior", - "show": true - }, - { - "id": "008", - "display_name": "Behavior H", - "type": "Behavior", - "show": true - }, - { - "id": "009", - "display_name": "Sequence A", - "type": "Sequence", - "show": false - }, - { - "id": "010", - "display_name": "Sequence B", - "type": "Sequence", - "show": false - }, - { - "id": "011", - "display_name": "Sequence C", - "type": "Sequence", - "show": false - } - ], - "context": "This is a sample paragraph that describes the context of the environment in which the robot is operating. This context might affect the decision making, rendering some actions relevant and others less relevant." -} diff --git a/examples/atlas-resource-file.json b/examples/atlas-resource-file.json new file mode 100644 index 00000000..29e7eb59 --- /dev/null +++ b/examples/atlas-resource-file.json @@ -0,0 +1,140 @@ +{ + "pick_up_medicine": { + "context": "Atlas is assigned to retrieve medicine A from the medicine cabinet. Atlas is currently on the third floor near the nurse's desk. The medicine cabinet is located in the pharmacy room on the third floor. The medicine cabinet has a total 5 stock for medicine A. To retrieve medicine from the pharmacy room, qualified personnel must communicate with the pharmacist at the door and request the medicine they require.", + "children": [ + "take_path_to_medicine_cabinet", + "unlock_cabinet", + "retrieve_medicine" + ], + "behavior_library": [ + { + "id": "take_path_to_medicine_cabinet", + "name": "take acceptable path to the medicine cabinet", + "in_behavior_bank": false + }, + { + "id": "unlock_cabinet", + "name": "unlock the cabinet" + }, + { + "id": "retrieve_medicine", + "name": "retrieve the medicine" + }, + { + "id": "wait_for_cabinet_access", + "name": "wait at medicine cabinet until it is accessible", + "in_behavior_bank": true + }, + { + "id": "alert_adminstrator", + "name": "alert adminstrator for assistance", + "in_behavior_bank": true + }, + { + "id": "request_medicine", + "name": "request required medicine from pharmacist", + "in_behavior_bank": true + } + ], + "interruptions": { + "take_path_to_medicine_cabinet": "While moving toward the medicine cabinet, the robot is interrupted by a visitor: “Hello, I’m looking for room 536 to visit John. Can you help me find the way?”", + "unlock_cabinet": "Upon reaching the cabinet, the robot finds it locked and is unable to electronically open it with the password." + } + }, + "travel_to_desired_floor": { + "context": "Atlas has the medicine in it's posession. Atlas is now assigned to travel to Patient P's Room. Patient P is in room 405, which is on the 4th floor. Atlas is currently located on the 3rd floor in the medicine room. Atlas is designed to fit in conventional elevators. The capacity of the hospital elevator is 1500 lbs based on an average passenger weight of 150 lbs. There are currently 0 occupants in the elevator.", + "children": [ + "take_path_to_elevator", + "get_into_elevator", + "press_correct_floor_button", + "exit_elevator" + ], + "behavior_library": [ + { + "id": "take_path_to_elevator", + "name": "take acceptable path to the elevator", + "in_behavior_bank": false + }, + { + "id": "get_into_elevator", + "name": "get into the elevator", + "in_behavior_bank": false + }, + { + "id": "press_correct_floor_button", + "name": "press the correct floor button", + "in_behavior_bank": false + }, + { + "id": "exit_elevator", + "name": "exit the elevator", + "in_behavior_bank": false + }, + { + "id": "announce_presence_and_task", + "name": "announce its presence and task", + "in_behavior_bank": true + }, + { + "id": "wait_for_empty_elevator", + "name": "wait for elevator that has no occupants", + "in_behavior_bank": true + }, + { + "id": "alert_adminstrator", + "name": "alert adminstrator for assistance", + "in_behavior_bank": true + } + ], + "interruptions": { + "take_path_to_medicine_cabinet": "While moving toward the medicine cabinet, the robot is interrupted by a visitor: “Hello, I’m looking for room 536 to visit John. Can you help me find the way?”", + "unlock_cabinet": "Upon reaching the cabinet, the robot finds it locked and is unable to electronically open it with the password." + } + }, + "deliver_the_medicine": { + "context": "Atlas has the medicine in it's possession. Atlas is now assigned to deliver the medicine to Patient P. Atlas is on the 4th floor, outside the elevator lobby. Patient P is in room 405 and the door to Patient P's room is purposely left open for nurses to keep a constant eye on the patient.", + "children": [ + "take_path_to_patient_room", + "enter_room", + "hand_medicine_to_patient" + ], + "behavior_library": [ + { + "id": "take_path_to_patient_room", + "name": "take acceptable path to the patient room", + "in_behavior_bank": false + }, + { + "id": "enter_room", + "name": "enter the patient's room", + "in_behavior_bank": false + }, + { + "id": "hand_medicine_to_patient", + "name": "hand the medicine to the patient", + "in_behavior_bank": false + }, + { + "id": "announce_presence_and_task", + "name": "announce its presence and task", + "in_behavior_bank": true + }, + { + "id": "knock_on_door", + "name": "knock on the door", + "in_behavior_bank": true + }, + { + "id": "open_room_door", + "name": "open the door", + "in_behavior_bank": true + }, + { + "id": "alert_adminstrator", + "name": "alert adminstrator for assistance", + "in_behavior_bank": true + } + ], + "interruptions": {} + } +} \ No newline at end of file diff --git a/examples/digit-resource-file.json b/examples/digit-resource-file.json new file mode 100644 index 00000000..0ef56d8b --- /dev/null +++ b/examples/digit-resource-file.json @@ -0,0 +1,140 @@ +{ + "pick_up_medicine": { + "context": "Digit is assigned to retrieve medicine A from the medicine cabinet. Digit is currently on the third floor near the nurse's desk. The medicine cabinet is located in the pharmacy room on the third floor. The medicine cabinet has a total 5 stock for medicine A. To retrieve medicine from the pharmacy room, qualified personnel are allowed to enter the pharmacy room and grab the medicine they require.", + "children": [ + "take_path_to_medicine_cabinet", + "unlock_cabinet", + "retrieve_medicine" + ], + "behavior_library": [ + { + "id": "take_path_to_medicine_cabinet", + "name": "take acceptable path to the medicine cabinet", + "in_behavior_bank": false + }, + { + "id": "unlock_cabinet", + "name": "unlock the cabinet" + }, + { + "id": "retrieve_medicine", + "name": "retrieve the medicine" + }, + { + "id": "wait_for_cabinet_access", + "name": "wait at medicine cabinet until it is accessible", + "in_behavior_bank": true + }, + { + "id": "alert_adminstrator", + "name": "alert adminstrator for assistance", + "in_behavior_bank": true + }, + { + "id": "request_medicine", + "name": "request required medicine from pharmacist", + "in_behavior_bank": true + } + ], + "interruptions": { + "take_path_to_medicine_cabinet": "While moving toward the medicine cabinet, the robot is interrupted by a visitor: “Hello, I’m looking for room 536 to visit John. Can you help me find the way?”", + "unlock_cabinet": "Upon reaching the cabinet, the robot finds it locked and is unable to electronically open it with the password." + } + }, + "travel_to_desired_floor": { + "context": "Digit has the medicine in it's posession. Digit is now assigned to travel to Patient P's Room. Patient P is in room 405, which is on the 4th floor. Digit is currently located on the 3rd floor in the medicine room. Digit is designed to fit in conventional elevators. The capacity of the hospital elevator is 1500 lbs based on an average passenger weight of 150 lbs. There are currently 10 occupants in the elevator.", + "children": [ + "take_path_to_elevator", + "get_into_elevator", + "press_correct_floor_button", + "exit_elevator" + ], + "behavior_library": [ + { + "id": "take_path_to_elevator", + "name": "take acceptable path to the elevator", + "in_behavior_bank": false + }, + { + "id": "get_into_elevator", + "name": "get into the elevator", + "in_behavior_bank": false + }, + { + "id": "press_correct_floor_button", + "name": "press the correct floor button", + "in_behavior_bank": false + }, + { + "id": "exit_elevator", + "name": "exit the elevator", + "in_behavior_bank": false + }, + { + "id": "announce_presence_and_task", + "name": "announce its presence and task", + "in_behavior_bank": true + }, + { + "id": "wait_for_empty_elevator", + "name": "wait for elevator that has no occupants", + "in_behavior_bank": true + }, + { + "id": "alert_adminstrator", + "name": "alert adminstrator for assistance", + "in_behavior_bank": true + } + ], + "interruptions": { + "take_path_to_medicine_cabinet": "While moving toward the medicine cabinet, the robot is interrupted by a visitor: “Hello, I’m looking for room 536 to visit John. Can you help me find the way?”", + "unlock_cabinet": "Upon reaching the cabinet, the robot finds it locked and is unable to electronically open it with the password." + } + }, + "deliver_the_medicine": { + "context": "Digit has the medicine in it's possession. Digit is now assigned to deliver the medicine to Patient P. Digit is on the 4th floor, outside the elevator lobby. Patient P is in room 405 and the door to Patient P's room is closed for privacy reasons. Only select personnel are allowed to enter.", + "children": [ + "take_path_to_patient_room", + "enter_room", + "hand_medicine_to_patient" + ], + "behavior_library": [ + { + "id": "take_path_to_patient_room", + "name": "take acceptable path to the patient room", + "in_behavior_bank": false + }, + { + "id": "enter_room", + "name": "enter the patient's room", + "in_behavior_bank": false + }, + { + "id": "hand_medicine_to_patient", + "name": "hand the medicine to the patient", + "in_behavior_bank": false + }, + { + "id": "announce_presence_and_task", + "name": "announce its presence and task", + "in_behavior_bank": true + }, + { + "id": "knock_on_door", + "name": "knock on the door", + "in_behavior_bank": true + }, + { + "id": "open_room_door", + "name": "open the door", + "in_behavior_bank": true + }, + { + "id": "alert_adminstrator", + "name": "alert adminstrator for assistance", + "in_behavior_bank": true + } + ], + "interruptions": {} + } +} \ No newline at end of file diff --git a/examples/entering-a-room.json b/examples/entering-a-room.json deleted file mode 100644 index 2c961464..00000000 --- a/examples/entering-a-room.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "context": "A nurse assistant robot in a hospital is taking medicine to Mrs. Jones during the day. The robot has already collected the medicine and enters the corridor outside Mrs. Jones' room. It needs to enter the room to take Mrs. Jones her medicine.", - "behavior_tree": { - "name": "", - "type": "Sequence", - "children": [ - { - "name": "Approach the door", - "type": "Behavior" - }, - { - "name": "Open the door", - "type": "Behavior" - }, - { - "name": "Go through the doorway", - "type": "Behavior" - } - ] - }, - "behavior_library": [ - { - "id": "anonymous-sequence", - "name": "", - "type": "Sequence", - "show": false - }, - { - "id": "approach-door", - "name": "Approach the door", - "type": "Behavior", - "show": true - }, - { - "id": "open-door", - "name": "Open the door", - "type": "Behavior", - "show": true - }, - { - "id": "go-through-doorway", - "name": "Go through the doorway", - "type": "Behavior", - "show": true - }, - { - "id": "knock-on-the-door", - "name": "Knock on the door", - "type": "Behavior", - "show": true - }, - { - "id": "sing-a-song", - "name": "Sing a song", - "type": "Behavior", - "show": true - }, - { - "id": "announce-your-presence", - "name": "Announce your presence", - "type": "Behavior", - "show": true - }, - { - "id": "contact-supervisor-guidance", - "name": "Contact supervisor for guidance", - "type": "Behavior", - "show": true - }, - { - "id": "stop", - "name": "Stop", - "type": "Behavior", - "show": true - }, - { - "id": "return-to-charging-station", - "name": "Return to charging station", - "type": "Behavior", - "show": false - } - ] - -} diff --git a/examples/optimus-resource-file.json b/examples/optimus-resource-file.json new file mode 100644 index 00000000..94336f99 --- /dev/null +++ b/examples/optimus-resource-file.json @@ -0,0 +1,140 @@ +{ + "pick_up_medicine": { + "context": "Optimus is assigned to retrieve medicine A from the medicine cabinet. Optimus is currently on the third floor near the nurse's desk. The medicine cabinet is located in the pharmacy room on the third floor. The medicine cabinet has a total 5 stock for medicine A. To retrieve medicine from the pharmacy room, qualified personnel are allowed to enter the pharmacy room and grab the medicine they require.", + "children": [ + "take_path_to_medicine_cabinet", + "unlock_cabinet", + "retrieve_medicine" + ], + "behavior_library": [ + { + "id": "take_path_to_medicine_cabinet", + "name": "take acceptable path to the medicine cabinet", + "in_behavior_bank": false + }, + { + "id": "unlock_cabinet", + "name": "unlock the cabinet" + }, + { + "id": "retrieve_medicine", + "name": "retrieve the medicine" + }, + { + "id": "wait_for_cabinet_access", + "name": "wait at medicine cabinet until it is accessible", + "in_behavior_bank": true + }, + { + "id": "alert_adminstrator", + "name": "alert adminstrator for assistance", + "in_behavior_bank": true + }, + { + "id": "request_medicine", + "name": "request required medicine from pharmacist", + "in_behavior_bank": true + } + ], + "interruptions": { + "take_path_to_medicine_cabinet": "While moving toward the medicine cabinet, the robot is interrupted by a visitor: “Hello, I’m looking for room 536 to visit John. Can you help me find the way?”", + "unlock_cabinet": "Upon reaching the cabinet, the robot finds it locked and is unable to electronically open it with the password." + } + }, + "travel_to_desired_floor": { + "context": "Optimus has the medicine in it's posession. Optimus is now assigned to travel to Patient P's Room. Patient P is in room 405, which is on the 4th floor. Optimus is currently located on the 3rd floor in the medicine room. Optimus is designed to fit in conventional elevators. The capacity of the hospital elevator is 1500 lbs based on an average passenger weight of 150 lbs. There are currently 10 occupants in the elevator.", + "children": [ + "take_path_to_elevator", + "get_into_elevator", + "press_correct_floor_button", + "exit_elevator" + ], + "behavior_library": [ + { + "id": "take_path_to_elevator", + "name": "take acceptable path to the elevator", + "in_behavior_bank": false + }, + { + "id": "get_into_elevator", + "name": "get into the elevator", + "in_behavior_bank": false + }, + { + "id": "press_correct_floor_button", + "name": "press the correct floor button", + "in_behavior_bank": false + }, + { + "id": "exit_elevator", + "name": "exit the elevator", + "in_behavior_bank": false + }, + { + "id": "announce_presence_and_task", + "name": "announce its presence and task", + "in_behavior_bank": true + }, + { + "id": "wait_for_empty_elevator", + "name": "wait for elevator that has no occupants", + "in_behavior_bank": true + }, + { + "id": "alert_adminstrator", + "name": "alert adminstrator for assistance", + "in_behavior_bank": true + } + ], + "interruptions": { + "take_path_to_medicine_cabinet": "While moving toward the medicine cabinet, the robot is interrupted by a visitor: “Hello, I’m looking for room 536 to visit John. Can you help me find the way?”", + "unlock_cabinet": "Upon reaching the cabinet, the robot finds it locked and is unable to electronically open it with the password." + } + }, + "deliver_the_medicine": { + "context": "Optimus has the medicine in it's possession. Optimus is now assigned to deliver the medicine to Patient P. Optimus is on the 4th floor, outside the elevator lobby. Patient P is in room 405 and the door to Patient P's room is closed for privacy reasons. Only select personnel are allowed to enter.", + "children": [ + "take_path_to_patient_room", + "enter_room", + "hand_medicine_to_patient" + ], + "behavior_library": [ + { + "id": "take_path_to_patient_room", + "name": "take acceptable path to the patient room", + "in_behavior_bank": false + }, + { + "id": "enter_room", + "name": "enter the patient's room", + "in_behavior_bank": false + }, + { + "id": "hand_medicine_to_patient", + "name": "hand the medicine to the patient", + "in_behavior_bank": false + }, + { + "id": "announce_presence_and_task", + "name": "announce its presence and task", + "in_behavior_bank": true + }, + { + "id": "knock_on_door", + "name": "knock on the door", + "in_behavior_bank": true + }, + { + "id": "open_room_door", + "name": "open the door", + "in_behavior_bank": true + }, + { + "id": "alert_adminstrator", + "name": "alert adminstrator for assistance", + "in_behavior_bank": true + } + ], + "interruptions": {} + } +} \ No newline at end of file diff --git a/norms/ball.py b/norms/ball.py deleted file mode 100644 index 70321b4c..00000000 --- a/norms/ball.py +++ /dev/null @@ -1,206 +0,0 @@ -#!/usr/bin/env python -# -# License: BSD -# https://raw.githubusercontent.com/splintered-reality/py_trees/devel/LICENSE -# -############################################################################## -# Documentation -############################################################################## - -""" -A py_trees demo. - -.. argparse:: - :module: py_trees.demos.selector - :func: command_line_argument_parser - :prog: py-trees-demo-selector - -.. graphviz:: dot/demo-selector.dot - -.. image:: images/selector.gif - -""" -############################################################################## -# Imports -############################################################################## - -import argparse -import sys -import time -import typing - -import py_trees -import py_trees.console as console - -############################################################################## -# Classes -############################################################################## - - -def description() -> str: - """ - Print description and usage information about the program. - - Returns: - the program description string - """ - content = ( - "Higher priority switching and interruption in the children of a selector.\n" - ) - content += "\n" - content += "In this example the higher priority child is setup to fail initially,\n" - content += "falling back to the continually running second child. On the third\n" - content += ( - "tick, the first child succeeds and cancels the hitherto running child.\n" - ) - if py_trees.console.has_colours: - banner_line = console.green + "*" * 79 + "\n" + console.reset - s = banner_line - s += console.bold_white + "Selectors".center(79) + "\n" + console.reset - s += banner_line - s += "\n" - s += content - s += "\n" - s += banner_line - else: - s = content - return s - - -def epilog() -> typing.Optional[str]: - """ - Print a noodly epilog for --help. - - Returns: - the noodly message - """ - if py_trees.console.has_colours: - return ( - console.cyan - + "And his noodly appendage reached forth to tickle the blessed...\n" - + console.reset - ) - else: - return None - - -def command_line_argument_parser() -> argparse.ArgumentParser: - """ - Process command line arguments. - - Returns: - the argument parser - """ - parser = argparse.ArgumentParser( - description=description(), - epilog=epilog(), - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - group = parser.add_mutually_exclusive_group() - group.add_argument( - "-r", "--render", action="store_true", help="render dot tree to file" - ) - group.add_argument( - "--render-with-blackboard-variables", - action="store_true", - help="render dot tree to file with blackboard variables", - ) - group.add_argument( - "-i", - "--interactive", - action="store_true", - help="pause and wait for keypress at each tick", - ) - return parser - - -def create_root() -> py_trees.behaviour.Behaviour: - """ - Create the root behaviour and it's subtree. - - Returns: - the root behaviour - """ - root = py_trees.composites.Sequence(name="Sequence", memory=False) - - find = py_trees.behaviours.Success(name="Find Ball") - - pick_up_ball = py_trees.composites.Sequence(name="Sequence", memory=False) - - place = py_trees.behaviours.Success(name="Place Ball") - - root.add_children([find, pick_up_ball, place]) - - move_to_ball = py_trees.composites.Selector(name="Selector", memory=False) - - obtain_ball = py_trees.composites.Selector(name="Selector", memory=False) - - pick_up_ball.add_children([move_to_ball, obtain_ball]) - - isClose = py_trees.behaviours.StatusQueue( - name="Ball close?", - queue=[ - py_trees.common.Status.FAILURE, - py_trees.common.Status.FAILURE, - py_trees.common.Status.SUCCESS, - ], - eventually=py_trees.common.Status.SUCCESS, - ) - approach = py_trees.behaviours.Running(name="Approach Ball") - - move_to_ball.add_children([isClose, approach]) - - isGrasped = py_trees.behaviours.StatusQueue( - name="Ball Grasped?", - queue=[ - py_trees.common.Status.FAILURE, - py_trees.common.Status.SUCCESS, - ], - eventually=py_trees.common.Status.SUCCESS, - ) - grasp = py_trees.behaviours.Running(name="Grasp Ball") - - obtain_ball.add_children([isGrasped, grasp]) - - return root - - -############################################################################## -# Main -############################################################################## - - -def main() -> None: - """Entry point for the demo script.""" - args = command_line_argument_parser().parse_args() - print(description()) - py_trees.logging.level = py_trees.logging.Level.DEBUG - - root = create_root() - - #################### - # Rendering - #################### - if args.render: - py_trees.display.render_dot_tree(root) - sys.exit() - - #################### - # Execute - #################### - root.setup_with_descendants() - print(py_trees.display.unicode_tree(root=root, show_status=True)) - for i in range(1, 5): - try: - time.sleep(3.0) - print("\n--------- Tick {0} ---------\n".format(i)) - root.tick_once() - print("\n") - print(py_trees.display.unicode_tree(root=root, show_status=True)) - except KeyboardInterrupt: - break - print("\n") - - -if __name__ == "__main__": - main() diff --git a/norms/ball_blackboard.py b/norms/ball_blackboard.py deleted file mode 100644 index c9a0a5d7..00000000 --- a/norms/ball_blackboard.py +++ /dev/null @@ -1,220 +0,0 @@ -#!/usr/bin/env python -# -# License: BSD -# https://raw.githubusercontent.com/splintered-reality/py_trees/devel/LICENSE -# -############################################################################## -# Documentation -############################################################################## - -""" -A py_trees demo. - -.. argparse:: - :module: py_trees.demos.selector - :func: command_line_argument_parser - :prog: py-trees-demo-selector - -.. graphviz:: dot/demo-selector.dot - -.. image:: images/selector.gif - -""" -############################################################################## -# Imports -############################################################################## - -import argparse -import sys -import time -import typing -import operator - -import py_trees -import py_trees.console as console - -############################################################################## -# Classes -############################################################################## - -py_trees.logging.level = py_trees.logging.Level.DEBUG -blackboard = py_trees.blackboard.Client(name="Client") -blackboard.register_key(key="isBallClose", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="isBallGrasped", access=py_trees.common.Access.WRITE) -blackboard.isBallClose = False -blackboard.isBallGrasped = False - - -def description() -> str: - """ - Print description and usage information about the program. - - Returns: - the program description string - """ - content = ( - "Higher priority switching and interruption in the children of a selector.\n" - ) - content += "\n" - content += "In this example the higher priority child is setup to fail initially,\n" - content += "falling back to the continually running second child. On the third\n" - content += ( - "tick, the first child succeeds and cancels the hitherto running child.\n" - ) - if py_trees.console.has_colours: - banner_line = console.green + "*" * 79 + "\n" + console.reset - s = banner_line - s += console.bold_white + "Selectors".center(79) + "\n" + console.reset - s += banner_line - s += "\n" - s += content - s += "\n" - s += banner_line - else: - s = content - return s - - -def epilog() -> typing.Optional[str]: - """ - Print a noodly epilog for --help. - - Returns: - the noodly message - """ - if py_trees.console.has_colours: - return ( - console.cyan - + "And his noodly appendage reached forth to tickle the blessed...\n" - + console.reset - ) - else: - return None - - -def command_line_argument_parser() -> argparse.ArgumentParser: - """ - Process command line arguments. - - Returns: - the argument parser - """ - parser = argparse.ArgumentParser( - description=description(), - epilog=epilog(), - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - group = parser.add_mutually_exclusive_group() - group.add_argument( - "-r", "--render", action="store_true", help="render dot tree to file" - ) - group.add_argument( - "--render-with-blackboard-variables", - action="store_true", - help="render dot tree to file with blackboard variables", - ) - group.add_argument( - "-i", - "--interactive", - action="store_true", - help="pause and wait for keypress at each tick", - ) - return parser - - -def create_root() -> py_trees.behaviour.Behaviour: - """ - Create the root behaviour and it's subtree. - - Returns: - the root behaviour - """ - root = py_trees.composites.Sequence(name="Sequence", memory=False) - - find = py_trees.behaviours.Success(name="Find Ball") - - pick_up_ball = py_trees.composites.Sequence(name="Sequence", memory=False) - - place = py_trees.behaviours.Success(name="Place Ball") - - root.add_children([find, pick_up_ball, place]) - - move_to_ball = py_trees.composites.Selector(name="Selector", memory=False) - - obtain_ball = py_trees.composites.Selector(name="Selector", memory=False) - - pick_up_ball.add_children([move_to_ball, obtain_ball]) - - print(blackboard) - - isClose = py_trees.behaviours.CheckBlackboardVariableValue( - name="Ball Close?", - check=py_trees.common.ComparisonExpression( - variable="isBallClose", value=True, operator=operator.eq - ), - ) - - approach = py_trees.behaviours.Running(name="Approach Ball") - - move_to_ball.add_children([isClose, approach]) - - isGrasped = py_trees.behaviours.CheckBlackboardVariableValue( - name="Ball Grasped?", - check=py_trees.common.ComparisonExpression( - variable="isBallGrasped", value=True, operator=operator.eq - ), - ) - - grasp = py_trees.behaviours.Running(name="Grasp Ball") - - obtain_ball.add_children([isGrasped, grasp]) - - return root - - -############################################################################## -# Main -############################################################################## - - -def main() -> None: - """Entry point for the demo script.""" - args = command_line_argument_parser().parse_args() - print(description()) - # print(blackboard) - - root = create_root() - - #################### - # Rendering - #################### - if args.render: - py_trees.display.render_dot_tree(root) - sys.exit() - - #################### - # Execute - #################### - root.setup_with_descendants() - print(py_trees.display.unicode_tree(root=root, show_status=True)) - for i in range(1, 6): - try: - time.sleep(1.0) - print("\n--------- Tick {0} ---------\n".format(i)) - if i == 3: - print("Ball is now close\n") - blackboard.isBallClose = True - if i == 5: - print("Ball is now grasped\n") - blackboard.isBallGrasped = True - # blackboard.isBallClose = False - root.tick_once() - print("\n") - print(py_trees.display.unicode_tree(root=root, show_status=True)) - except KeyboardInterrupt: - break - print("\n") - - -if __name__ == "__main__": - main() diff --git a/norms/deliver_medicine.py b/norms/deliver_medicine.py deleted file mode 100644 index 2c61139d..00000000 --- a/norms/deliver_medicine.py +++ /dev/null @@ -1,324 +0,0 @@ -#!/usr/bin/env python -# -# License: BSD -# https://raw.githubusercontent.com/splintered-reality/py_trees/devel/LICENSE -# -############################################################################## -# Documentation -############################################################################## - -""" -A py_trees demo. - -.. argparse:: - :module: py_trees.demos.selector - :func: command_line_argument_parser - :prog: py-trees-demo-selector - -.. graphviz:: dot/demo-selector.dot - -.. image:: images/selector.gif - -""" -############################################################################## -# Imports -############################################################################## - -import argparse -import sys -import time -import typing -import operator - -import py_trees -import py_trees.console as console - -############################################################################## -# Classes -############################################################################## - -py_trees.logging.level = py_trees.logging.Level.INFO -blackboard = py_trees.blackboard.Client(name="Client") -blackboard.register_key(key="isCabinetUnlocked", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="isElevatorOpen", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="elevatorHasSpace", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="canEnterElevator", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="isElevatorOn7th", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="canLeaveElevator", access=py_trees.common.Access.WRITE) -blackboard.isCabinetUnlocked = False -blackboard.isElevatorOpen = False -blackboard.elevatorHasSpace = False -blackboard.canEnterElevator = False -blackboard.isElevatorOn7th = False -blackboard.canLeaveElevator = False - - -def description() -> str: - """ - Print description and usage information about the program. - - Returns: - the program description string - """ - content = ( - "Higher priority switching and interruption in the children of a selector.\n" - ) - content += "\n" - content += "In this example the higher priority child is setup to fail initially,\n" - content += "falling back to the continually running second child. On the third\n" - content += ( - "tick, the first child succeeds and cancels the hitherto running child.\n" - ) - if py_trees.console.has_colours: - banner_line = console.green + "*" * 79 + "\n" + console.reset - s = banner_line - s += console.bold_white + "Selectors".center(79) + "\n" + console.reset - s += banner_line - s += "\n" - s += content - s += "\n" - s += banner_line - else: - s = content - return s - - -def epilog() -> typing.Optional[str]: - """ - Print a noodly epilog for --help. - - Returns: - the noodly message - """ - if py_trees.console.has_colours: - return ( - console.cyan - + "And his noodly appendage reached forth to tickle the blessed...\n" - + console.reset - ) - else: - return None - - -def command_line_argument_parser() -> argparse.ArgumentParser: - """ - Process command line arguments. - - Returns: - the argument parser - """ - parser = argparse.ArgumentParser( - description=description(), - epilog=epilog(), - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - group = parser.add_mutually_exclusive_group() - group.add_argument( - "-r", "--render", action="store_true", help="render dot tree to file" - ) - group.add_argument( - "--render-with-blackboard-variables", - action="store_true", - help="render dot tree to file with blackboard variables", - ) - group.add_argument( - "-i", - "--interactive", - action="store_true", - help="pause and wait for keypress at each tick", - ) - return parser - - -def wait(name, ticks) -> py_trees.behaviours.StatusQueue: - queue = [] - for i in range(0, ticks + 1): - queue.append(py_trees.common.Status.RUNNING) - return py_trees.behaviours.StatusQueue( - name=name, - queue=queue, - eventually=py_trees.common.Status.FAILURE, - ) - - -def create_root() -> py_trees.behaviour.Behaviour: - """ - Create the root behaviour and it's subtree. - - Returns: - the root behaviour - """ - # print(blackboard) - - root = py_trees.composites.Sequence(name="Sequence", memory=False) - - get_medicine = py_trees.composites.Sequence(name="Sequence", memory=False) - - take_elevator = py_trees.composites.Sequence(name="Sequence", memory=False) - - deliver_medicine = py_trees.composites.Sequence(name="Sequence", memory=False) - - root.add_children([get_medicine, take_elevator, deliver_medicine]) - - go_to = py_trees.behaviours.Success(name="Go To Medicine Cabinet") - unlock = py_trees.composites.Selector(name="Selector", memory=False) - take = py_trees.behaviours.Success(name="Take Medicine") - get_medicine.add_children([go_to, unlock, take]) - - unlock_cabinet = py_trees.behaviours.CheckBlackboardVariableValue( - name="Unlock Cabinet", - check=py_trees.common.ComparisonExpression( - variable="isCabinetUnlocked", value=True, operator=operator.eq - ), - ) - wait_cabinet = wait("Wait for at most 3 Ticks", 3) - supervisor = py_trees.behaviours.Success(name="Call Supervisor for Virtual Unlock") - unlock.add_children([unlock_cabinet, wait_cabinet, supervisor]) - - go_to_elevator = py_trees.behaviours.Success(name="Go to Elevator") - click_up_button = py_trees.behaviours.Success(name="Click Up Button") - wait_for_elevator = py_trees.composites.Sequence(name="Sequence", memory=False) - enter_elevator = py_trees.composites.Sequence(name="Sequence", memory=False) - - take_elevator.add_children( - [go_to_elevator, click_up_button, wait_for_elevator, enter_elevator] - ) - - is_elevator_open = py_trees.composites.Selector(name="Selector", memory=False) - has_space_in_elevator = py_trees.composites.Selector(name="Selector", memory=False) - can_enter_elevator = py_trees.composites.Selector(name="Selector", memory=False) - wait_for_elevator.add_children( - [is_elevator_open, has_space_in_elevator, can_enter_elevator] - ) - - elevator_open = py_trees.behaviours.CheckBlackboardVariableValue( - name="Is Elevator Open?", - check=py_trees.common.ComparisonExpression( - variable="isElevatorOpen", value=True, operator=operator.eq - ), - ) - wait_for_open_elevator = wait("Wait for at most 5 Ticks", 5) - supervisor = py_trees.behaviours.Success( - name="Call Supervisor to Virtually Call Elevator" - ) - is_elevator_open.add_children([elevator_open, wait_for_open_elevator, supervisor]) - - elevator_space = py_trees.behaviours.CheckBlackboardVariableValue( - name=">= 9ft^2 of space in the Elevator?", - check=py_trees.common.ComparisonExpression( - variable="elevatorHasSpace", value=True, operator=operator.eq - ), - ) - wait_for_space = py_trees.behaviours.Running(name="State 'I’ll wait'") - has_space_in_elevator.add_children([elevator_space, wait_for_space]) - - elevator_enter = py_trees.behaviours.CheckBlackboardVariableValue( - name="Ask to enter Elevator", - check=py_trees.common.ComparisonExpression( - variable="canEnterElevator", value=True, operator=operator.eq - ), - ) - wait_to_enter_elevator = py_trees.behaviours.Running(name="State I’ll wait") - can_enter_elevator.add_children([elevator_enter, wait_to_enter_elevator]) - - enter_elevator_task = py_trees.behaviours.Success(name="Enter Elevator") - hit_7th_floor_button = py_trees.behaviours.Success(name="Hit 7th Floor Button") - enter_elevator.add_children([enter_elevator_task, hit_7th_floor_button]) - - exit = py_trees.composites.Sequence(name="Sequence", memory=False) - exit_statement = py_trees.behaviours.Success(name="State: I'll exit now") - go_to_patient = py_trees.behaviours.Success(name="Go to Patient") - deliver = py_trees.behaviours.Success(name="Deliver medicine to Patient") - deliver_medicine.add_children([exit, exit_statement, go_to_patient, deliver]) - - get_to_7th = py_trees.composites.Selector(name="Selector", memory=False) - can_exit_now = py_trees.composites.Selector(name="Selector", memory=False) - - exit.add_children([get_to_7th, can_exit_now]) - - is_elevator_on_7th = py_trees.behaviours.CheckBlackboardVariableValue( - name="Is Elevator on 7th?", - check=py_trees.common.ComparisonExpression( - variable="isElevatorOn7th", value=True, operator=operator.eq - ), - ) - elevator_wait = py_trees.behaviours.Running(name="Wait") - get_to_7th.add_children([is_elevator_on_7th, elevator_wait]) - - are_people_on_elevator = py_trees.behaviours.CheckBlackboardVariableValue( - name="Is >= 1 Person in Elevator?", - check=py_trees.common.ComparisonExpression( - variable="canLeaveElevator", value=True, operator=operator.eq - ), - ) - exit_elevator_wait = wait("Wait for at most 3 Ticks", 3) - can_exit_now.add_children([are_people_on_elevator, exit_elevator_wait]) - - return root - - -############################################################################## -# Main -############################################################################## - - -def main() -> None: - """Entry point for the demo script.""" - args = command_line_argument_parser().parse_args() - print(description()) - # print(blackboard) - - root = create_root() - - #################### - # Rendering - #################### - if args.render: - py_trees.display.render_dot_tree(root) - sys.exit() - - #################### - # Execute - #################### - behaviour_tree = py_trees.trees.BehaviourTree(root) - behaviour_tree.visitors.append(py_trees.visitors.DebugVisitor()) - snapshot_visitor = py_trees.visitors.SnapshotVisitor() - behaviour_tree.visitors.append(snapshot_visitor) - print(py_trees.display.unicode_tree(root=root, show_status=True)) - tree_success = False - i = 0 - while not tree_success: - try: - time.sleep(1.0) - print("\n--------- Tick {0} ---------\n".format(i)) - if i == 3: - print("Cabinet is now unlocked\n") - blackboard.isCabinetUnlocked = True - if i == 5: - # print("Ball is now grasped\n") - blackboard.isElevatorOpen = True - if i == 7: - blackboard.elevatorHasSpace = True - if i == 9: - blackboard.canEnterElevator = True - if i == 11: - blackboard.isElevatorOn7th = True - if i == 13: - blackboard.canLeaveElevator = True - - behaviour_tree.tick() - print("\n") - print(py_trees.display.unicode_tree(root=root, show_status=True)) - # ascii_tree = py_trees.display.ascii_tree( - # behaviour_tree.root) - # print(ascii_tree) - if behaviour_tree.root.status == py_trees.common.Status.SUCCESS: - tree_success = True - i += 1 - except KeyboardInterrupt: - break - print("\n") - - -if __name__ == "__main__": - main() diff --git a/norms/deliver_medicine_with_deontic.py b/norms/deliver_medicine_with_deontic.py deleted file mode 100644 index 87fce26b..00000000 --- a/norms/deliver_medicine_with_deontic.py +++ /dev/null @@ -1,375 +0,0 @@ -#!/usr/bin/env python -# -# License: BSD -# https://raw.githubusercontent.com/splintered-reality/py_trees/devel/LICENSE -# -############################################################################## -# Documentation -############################################################################## - -""" -A py_trees demo. - -.. argparse:: - :module: py_trees.demos.selector - :func: command_line_argument_parser - :prog: py-trees-demo-selector - -.. graphviz:: dot/demo-selector.dot - -.. image:: images/selector.gif - -""" -############################################################################## -# Imports -############################################################################## - -import argparse -import sys -import time -import typing -import operator - -import py_trees -import py_trees.console as console - -############################################################################## -# Classes -############################################################################## - -py_trees.logging.level = py_trees.logging.Level.INFO -blackboard = py_trees.blackboard.Client(name="Client") -blackboard.register_key(key="isCabinetUnlocked", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="isElevatorOpen", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="elevatorHasSpace", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="canEnterElevator", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="isElevatorOn7th", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="canLeaveElevator", access=py_trees.common.Access.WRITE) -blackboard.isCabinetUnlocked = False -blackboard.isElevatorOpen = False -blackboard.elevatorHasSpace = False -blackboard.canEnterElevator = False -blackboard.isElevatorOn7th = False -blackboard.canLeaveElevator = False - - -def description() -> str: - """ - Print description and usage information about the program. - - Returns: - the program description string - """ - content = ( - "This is a demonstration of a medicine delivery robot decision tree process.\n" - ) - content += "The robot needs to acquire the medicine, take the elevator to the 7th floor, and then deliver it to the patient.\n" - content += "There are failing nodes within the tree that asks the human for input to demonstrate altering the tree between ticks.\n" - content += "\n" - content += "Key:\n" - content += ( - "'--> ' - A leaf node that can return success, failure, or running when ran.\n" - ) - content += "'\{-\} Sequence' - A sequential operator with children that will be run in sequential order.\n" - content += "'\{o\} Selector' - A fallback operator with children that will be run one at a time if the previous child fails.\n" - content += "'-' - A node that has not been ran in the current tick yet.\n" - content += "'✕' - A node that has ran and failed in the current tick.\n" - content += "'✓' - A node that has ran and succeeded in the current tick.\n" - content += "'*' - A node that has ran and returned running in the current tick.\n" - - if py_trees.console.has_colours: - banner_line = console.green + "*" * 79 + "\n" + console.reset - s = banner_line - s += console.bold_white + "Selectors".center(79) + "\n" + console.reset - s += banner_line - s += "\n" - s += content - s += "\n" - s += banner_line - else: - s = content - return s - - -def epilog() -> typing.Optional[str]: - """ - Print a noodly epilog for --help. - - Returns: - the noodly message - """ - if py_trees.console.has_colours: - return ( - console.cyan - + "And his noodly appendage reached forth to tickle the blessed...\n" - + console.reset - ) - else: - return None - - -def command_line_argument_parser() -> argparse.ArgumentParser: - """ - Process command line arguments. - - Returns: - the argument parser - """ - parser = argparse.ArgumentParser( - description=description(), - epilog=epilog(), - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - group = parser.add_mutually_exclusive_group() - group.add_argument( - "-r", "--render", action="store_true", help="render dot tree to file" - ) - group.add_argument( - "--render-with-blackboard-variables", - action="store_true", - help="render dot tree to file with blackboard variables", - ) - group.add_argument( - "-i", - "--interactive", - action="store_true", - help="pause and wait for keypress at each tick", - ) - return parser - - -def wait(name, ticks) -> py_trees.behaviours.StatusQueue: - queue = [] - for i in range(0, ticks + 1): - queue.append(py_trees.common.Status.RUNNING) - return py_trees.behaviours.StatusQueue( - name=name, - queue=queue, - eventually=py_trees.common.Status.FAILURE, - ) - - -def create_root() -> py_trees.behaviour.Behaviour: - """ - Create the root behaviour and it's subtree. - - Returns: - the root behaviour - """ - # print(blackboard) - - root = py_trees.composites.Sequence(name="Sequence", memory=False) - - get_medicine = py_trees.composites.Sequence(name="Sequence", memory=False) - - take_elevator = py_trees.composites.Sequence(name="Sequence", memory=False) - - deliver_medicine = py_trees.composites.Sequence(name="Sequence", memory=False) - - root.add_children([get_medicine, take_elevator, deliver_medicine]) - - go_to = py_trees.behaviours.Success(name="Go To Medicine Cabinet") - unlock = py_trees.composites.Selector(name="Selector", memory=False) - take = py_trees.behaviours.Success(name="Pickup Medicine") - get_medicine.add_children([go_to, unlock, take]) - - unlock_cabinet = py_trees.behaviours.CheckBlackboardVariableValue( - name="Unlock Cabinet", - check=py_trees.common.ComparisonExpression( - variable="isCabinetUnlocked", value=True, operator=operator.eq - ), - ) - - wait_cabinet = py_trees.behaviours.Running(name="Wait") - supervisor = py_trees.behaviours.Success(name="Call Supervisor for Virtual Unlock") - unlock.add_children([unlock_cabinet, wait_cabinet, supervisor]) - - go_to_elevator = py_trees.behaviours.Success(name="Go to Elevator") - click_up_button = py_trees.behaviours.Success(name="Click Up Button") - wait_for_elevator = py_trees.composites.Sequence(name="Sequence", memory=False) - enter_elevator = py_trees.composites.Sequence(name="Sequence", memory=False) - - take_elevator.add_children( - [go_to_elevator, click_up_button, wait_for_elevator, enter_elevator] - ) - - is_elevator_open = py_trees.composites.Selector(name="Selector", memory=False) - has_space_in_elevator = py_trees.composites.Selector(name="Selector", memory=False) - can_enter_elevator = py_trees.composites.Selector(name="Selector", memory=False) - wait_for_elevator.add_children( - [is_elevator_open, has_space_in_elevator, can_enter_elevator] - ) - - elevator_open = py_trees.behaviours.CheckBlackboardVariableValue( - name="Is Elevator Open?", - check=py_trees.common.ComparisonExpression( - variable="isElevatorOpen", value=True, operator=operator.eq - ), - ) - wait_for_open_elevator = py_trees.behaviours.Running(name="Wait") - supervisor = py_trees.behaviours.Success( - name="Call Supervisor to Virtually Call Elevator" - ) - is_elevator_open.add_children([elevator_open, wait_for_open_elevator, supervisor]) - # is_elevator_open.add_children([elevator_open, wait_for_open_elevator]) - - elevator_space = py_trees.behaviours.CheckBlackboardVariableValue( - name=">= 9ft^2 of space in the Elevator?", - check=py_trees.common.ComparisonExpression( - variable="elevatorHasSpace", value=True, operator=operator.eq - ), - ) - wait_for_space = py_trees.behaviours.Running(name="State I’ll wait") - has_space_in_elevator.add_children([elevator_space, wait_for_space]) - - elevator_enter = py_trees.behaviours.CheckBlackboardVariableValue( - name="Ask to enter Elevator", - check=py_trees.common.ComparisonExpression( - variable="canEnterElevator", value=True, operator=operator.eq - ), - ) - wait_to_enter_elevator = py_trees.behaviours.Running(name="State I’ll wait") - can_enter_elevator.add_children([elevator_enter, wait_to_enter_elevator]) - - enter_elevator_task = py_trees.behaviours.Success(name="Enter Elevator") - hit_7th_floor_button = py_trees.behaviours.Success(name="Hit 7th Floor Button") - enter_elevator.add_children([enter_elevator_task, hit_7th_floor_button]) - - exit = py_trees.composites.Sequence(name="Sequence", memory=False) - exit_statement = py_trees.behaviours.Success(name="State: I'll exit now") - go_to_patient = py_trees.behaviours.Success(name="Go to Patient") - deliver = py_trees.behaviours.Success(name="Deliver medicine to Patient") - deliver_medicine.add_children([exit, exit_statement, go_to_patient, deliver]) - - get_to_7th = py_trees.composites.Selector(name="Selector", memory=False) - can_exit_now = py_trees.composites.Selector(name="Selector", memory=False) - - exit.add_children([get_to_7th, can_exit_now]) - - is_elevator_on_7th = py_trees.behaviours.CheckBlackboardVariableValue( - name="Is Elevator on 7th?", - check=py_trees.common.ComparisonExpression( - variable="isElevatorOn7th", value=True, operator=operator.eq - ), - ) - elevator_wait = py_trees.behaviours.Running(name="Wait") - get_to_7th.add_children([is_elevator_on_7th, elevator_wait]) - - are_people_on_elevator = py_trees.behaviours.CheckBlackboardVariableValue( - name="Is >= 1 Person in Elevator?", - check=py_trees.common.ComparisonExpression( - variable="canLeaveElevator", value=True, operator=operator.eq - ), - ) - exit_elevator_wait = wait("Wait for at most 3 Ticks", 3) - can_exit_now.add_children([are_people_on_elevator, exit_elevator_wait]) - - return root - - -############################################################################## -# Main -############################################################################## - - -def main() -> None: - """Entry point for the demo script.""" - args = command_line_argument_parser().parse_args() - print(description()) - # print(blackboard) - - root = create_root() - - #################### - # Rendering - #################### - if args.render: - py_trees.display.render_dot_tree(root) - sys.exit() - - #################### - # Execute - #################### - behaviour_tree = py_trees.trees.BehaviourTree(root) - behaviour_tree.visitors.append(py_trees.visitors.DebugVisitor()) - snapshot_visitor = py_trees.visitors.SnapshotVisitor() - behaviour_tree.visitors.append(snapshot_visitor) - print(py_trees.display.unicode_tree(root=root, show_status=True)) - tree_success = False - i = 0 - time.sleep(1) - while not tree_success: - try: - time.sleep(0.5) - print("\n--------- Tick {0} ---------\n".format(i)) - # if i == 3: - # print("Cabinet is now unlocked\n") - # blackboard.isCabinetUnlocked = True - # if i == 5: - # blackboard.isElevatorOpen = True - if i == 7: - blackboard.elevatorHasSpace = True - if i == 9: - blackboard.canEnterElevator = True - if i == 11: - blackboard.isElevatorOn7th = True - if i == 13: - blackboard.canLeaveElevator = True - # if i == 15: - # blackboard.isElevatorOpen = True - - behaviour_tree.tick() - print("\n") - print(py_trees.display.unicode_tree(root=root, show_status=True)) - # ascii_tree = py_trees.display.ascii_tree( - # behaviour_tree.root) - # print(ascii_tree) - if behaviour_tree.root.status == py_trees.common.Status.SUCCESS: - tree_success = True - elif behaviour_tree.root.status == py_trees.common.Status.FAILURE: - callSupervisor = input( - "Should the robot call it's supervisor for help on the next tick for the failed task? (1 for Yes 0 for No)\n" - ) - if callSupervisor == "1": - node = behaviour_tree.root - found = False - while not found: - for n in node.children: - if n.status == py_trees.common.Status.FAILURE: - node = n - break - if type(node) == py_trees.composites.Selector: - found = True - # supervisor = py_trees.behaviours.Success(name="Call Supervisor to " + node.name) - supervisor = py_trees.behaviours.Success( - name="Call Supervisor for help" - ) - node.add_children([supervisor]) - elif behaviour_tree.root.status == py_trees.common.Status.RUNNING: - reduceDeontic = input( - "Should the robot reduce the deontic force of the current running task to be less than the next task? (1 for Yes 0 for No)\n" - ) - if reduceDeontic == "1": - node = behaviour_tree.root - found = False - while not found: - for n in node.children: - if n.status == py_trees.common.Status.RUNNING: - node = n - break - if type(node) == py_trees.behaviours.Running: - found = True - # supervisor = py_trees.behaviours.Success(name="Call Supervisor to " + node.name) - parent = node.parent - parent.remove_child(node) - # supervisor = py_trees.behaviours.Success(name="Call Supervisor for help") - parent.add_children([node]) - - i += 1 - except KeyboardInterrupt: - break - print("\n") - - -if __name__ == "__main__": - main() diff --git a/norms/deliver_medicine_with_input.py b/norms/deliver_medicine_with_input.py deleted file mode 100644 index 3f7b0b55..00000000 --- a/norms/deliver_medicine_with_input.py +++ /dev/null @@ -1,353 +0,0 @@ -#!/usr/bin/env python -# -# License: BSD -# https://raw.githubusercontent.com/splintered-reality/py_trees/devel/LICENSE -# -############################################################################## -# Documentation -############################################################################## - -""" -A py_trees demo. - -.. argparse:: - :module: py_trees.demos.selector - :func: command_line_argument_parser - :prog: py-trees-demo-selector - -.. graphviz:: dot/demo-selector.dot - -.. image:: images/selector.gif - -""" -############################################################################## -# Imports -############################################################################## - -import argparse -import sys -import time -import typing -import operator - -import py_trees -import py_trees.console as console - -############################################################################## -# Classes -############################################################################## - -py_trees.logging.level = py_trees.logging.Level.INFO -blackboard = py_trees.blackboard.Client(name="Client") -blackboard.register_key(key="isCabinetUnlocked", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="isElevatorOpen", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="elevatorHasSpace", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="canEnterElevator", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="isElevatorOn7th", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="canLeaveElevator", access=py_trees.common.Access.WRITE) -blackboard.isCabinetUnlocked = False -blackboard.isElevatorOpen = False -blackboard.elevatorHasSpace = False -blackboard.canEnterElevator = False -blackboard.isElevatorOn7th = False -blackboard.canLeaveElevator = False - - -def description() -> str: - """ - Print description and usage information about the program. - - Returns: - the program description string - """ - content = ( - "This is a demonstration of a medicine delivery robot decision tree process.\n" - ) - content += "The robot needs to acquire the medicine, take the elevator to the 7th floor, and then deliver it to the patient.\n" - content += "There are failing nodes within the tree that asks the human for input to demonstrate altering the tree between ticks.\n" - content += "\n" - content += "Key:\n" - content += ( - "'--> ' - A leaf node that can return success, failure, or running when ran.\n" - ) - content += "'\{-\} Sequence' - A sequential operator with children that will be run in sequential order.\n" - content += "'\{o\} Selector' - A fallback operator with children that will be run one at a time if the previous child fails.\n" - content += "'-' - A node that has not been ran in the current tick yet.\n" - content += "'✕' - A node that has ran and failed in the current tick.\n" - content += "'✓' - A node that has ran and succeeded in the current tick.\n" - content += "'*' - A node that has ran and returned running in the current tick.\n" - - if py_trees.console.has_colours: - banner_line = console.green + "*" * 79 + "\n" + console.reset - s = banner_line - s += console.bold_white + "Selectors".center(79) + "\n" + console.reset - s += banner_line - s += "\n" - s += content - s += "\n" - s += banner_line - else: - s = content - return s - - -def epilog() -> typing.Optional[str]: - """ - Print a noodly epilog for --help. - - Returns: - the noodly message - """ - if py_trees.console.has_colours: - return ( - console.cyan - + "And his noodly appendage reached forth to tickle the blessed...\n" - + console.reset - ) - else: - return None - - -def command_line_argument_parser() -> argparse.ArgumentParser: - """ - Process command line arguments. - - Returns: - the argument parser - """ - parser = argparse.ArgumentParser( - description=description(), - epilog=epilog(), - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - group = parser.add_mutually_exclusive_group() - group.add_argument( - "-r", "--render", action="store_true", help="render dot tree to file" - ) - group.add_argument( - "--render-with-blackboard-variables", - action="store_true", - help="render dot tree to file with blackboard variables", - ) - group.add_argument( - "-i", - "--interactive", - action="store_true", - help="pause and wait for keypress at each tick", - ) - return parser - - -def wait(name, ticks) -> py_trees.behaviours.StatusQueue: - queue = [] - for i in range(0, ticks + 1): - queue.append(py_trees.common.Status.RUNNING) - return py_trees.behaviours.StatusQueue( - name=name, - queue=queue, - eventually=py_trees.common.Status.FAILURE, - ) - - -def create_root() -> py_trees.behaviour.Behaviour: - """ - Create the root behaviour and it's subtree. - - Returns: - the root behaviour - """ - # print(blackboard) - - root = py_trees.composites.Sequence(name="Sequence", memory=False) - - get_medicine = py_trees.composites.Sequence(name="Sequence", memory=False) - - take_elevator = py_trees.composites.Sequence(name="Sequence", memory=False) - - deliver_medicine = py_trees.composites.Sequence(name="Sequence", memory=False) - - root.add_children([get_medicine, take_elevator, deliver_medicine]) - - go_to = py_trees.behaviours.Success(name="Go To Medicine Cabinet") - unlock = py_trees.composites.Selector(name="Selector", memory=False) - take = py_trees.behaviours.Success(name="Pickup Medicine") - get_medicine.add_children([go_to, unlock, take]) - - unlock_cabinet = py_trees.behaviours.CheckBlackboardVariableValue( - name="Unlock Cabinet", - check=py_trees.common.ComparisonExpression( - variable="isCabinetUnlocked", value=True, operator=operator.eq - ), - ) - wait_cabinet = wait("Wait for at most 3 Ticks", 3) - # supervisor = py_trees.behaviours.Success(name="Call Supervisor for Virtual Unlock") - # unlock.add_children([unlock_cabinet, wait_cabinet, supervisor]) - unlock.add_children([unlock_cabinet, wait_cabinet]) - - go_to_elevator = py_trees.behaviours.Success(name="Go to Elevator") - click_up_button = py_trees.behaviours.Success(name="Click Up Button") - wait_for_elevator = py_trees.composites.Sequence(name="Sequence", memory=False) - enter_elevator = py_trees.composites.Sequence(name="Sequence", memory=False) - - take_elevator.add_children( - [go_to_elevator, click_up_button, wait_for_elevator, enter_elevator] - ) - - is_elevator_open = py_trees.composites.Selector(name="Selector", memory=False) - has_space_in_elevator = py_trees.composites.Selector(name="Selector", memory=False) - can_enter_elevator = py_trees.composites.Selector(name="Selector", memory=False) - wait_for_elevator.add_children( - [is_elevator_open, has_space_in_elevator, can_enter_elevator] - ) - - elevator_open = py_trees.behaviours.CheckBlackboardVariableValue( - name="Is Elevator Open?", - check=py_trees.common.ComparisonExpression( - variable="isElevatorOpen", value=True, operator=operator.eq - ), - ) - wait_for_open_elevator = wait("Wait for at most 5 Ticks", 5) - # supervisor = py_trees.behaviours.Success(name="Call Supervisor to Virtually Call Elevator") - # is_elevator_open.add_children([elevator_open, wait_for_open_elevator, supervisor]) - is_elevator_open.add_children([elevator_open, wait_for_open_elevator]) - - elevator_space = py_trees.behaviours.CheckBlackboardVariableValue( - name=">= 9ft^2 of space in the Elevator?", - check=py_trees.common.ComparisonExpression( - variable="elevatorHasSpace", value=True, operator=operator.eq - ), - ) - wait_for_space = py_trees.behaviours.Running(name="State 'I’ll wait'") - has_space_in_elevator.add_children([elevator_space, wait_for_space]) - - elevator_enter = py_trees.behaviours.CheckBlackboardVariableValue( - name="Ask to enter Elevator", - check=py_trees.common.ComparisonExpression( - variable="canEnterElevator", value=True, operator=operator.eq - ), - ) - wait_to_enter_elevator = py_trees.behaviours.Running(name="State I’ll wait") - can_enter_elevator.add_children([elevator_enter, wait_to_enter_elevator]) - - enter_elevator_task = py_trees.behaviours.Success(name="Enter Elevator") - hit_7th_floor_button = py_trees.behaviours.Success(name="Hit 7th Floor Button") - enter_elevator.add_children([enter_elevator_task, hit_7th_floor_button]) - - exit = py_trees.composites.Sequence(name="Sequence", memory=False) - exit_statement = py_trees.behaviours.Success(name="State: I'll exit now") - go_to_patient = py_trees.behaviours.Success(name="Go to Patient") - deliver = py_trees.behaviours.Success(name="Deliver medicine to Patient") - deliver_medicine.add_children([exit, exit_statement, go_to_patient, deliver]) - - get_to_7th = py_trees.composites.Selector(name="Selector", memory=False) - can_exit_now = py_trees.composites.Selector(name="Selector", memory=False) - - exit.add_children([get_to_7th, can_exit_now]) - - is_elevator_on_7th = py_trees.behaviours.CheckBlackboardVariableValue( - name="Is Elevator on 7th?", - check=py_trees.common.ComparisonExpression( - variable="isElevatorOn7th", value=True, operator=operator.eq - ), - ) - elevator_wait = py_trees.behaviours.Running(name="Wait") - get_to_7th.add_children([is_elevator_on_7th, elevator_wait]) - - are_people_on_elevator = py_trees.behaviours.CheckBlackboardVariableValue( - name="Is >= 1 Person in Elevator?", - check=py_trees.common.ComparisonExpression( - variable="canLeaveElevator", value=True, operator=operator.eq - ), - ) - exit_elevator_wait = wait("Wait for at most 3 Ticks", 3) - can_exit_now.add_children([are_people_on_elevator, exit_elevator_wait]) - - return root - - -############################################################################## -# Main -############################################################################## - - -def main() -> None: - """Entry point for the demo script.""" - args = command_line_argument_parser().parse_args() - print(description()) - # print(blackboard) - - root = create_root() - - #################### - # Rendering - #################### - if args.render: - py_trees.display.render_dot_tree(root) - sys.exit() - - #################### - # Execute - #################### - behaviour_tree = py_trees.trees.BehaviourTree(root) - behaviour_tree.visitors.append(py_trees.visitors.DebugVisitor()) - snapshot_visitor = py_trees.visitors.SnapshotVisitor() - behaviour_tree.visitors.append(snapshot_visitor) - print(py_trees.display.unicode_tree(root=root, show_status=True)) - tree_success = False - i = 0 - while not tree_success: - try: - time.sleep(0.5) - print("\n--------- Tick {0} ---------\n".format(i)) - # if i == 3: - # print("Cabinet is now unlocked\n") - # blackboard.isCabinetUnlocked = True - # if i == 5: - # blackboard.isElevatorOpen = True - if i == 7: - blackboard.elevatorHasSpace = True - if i == 9: - blackboard.canEnterElevator = True - if i == 11: - blackboard.isElevatorOn7th = True - if i == 13: - blackboard.canLeaveElevator = True - # if i == 15: - # blackboard.isElevatorOpen = True - - behaviour_tree.tick() - print("\n") - print(py_trees.display.unicode_tree(root=root, show_status=True)) - # ascii_tree = py_trees.display.ascii_tree( - # behaviour_tree.root) - # print(ascii_tree) - if behaviour_tree.root.status == py_trees.common.Status.SUCCESS: - tree_success = True - elif behaviour_tree.root.status == py_trees.common.Status.FAILURE: - callSupervisor = input( - "Should the robot call it's supervisor for help on the next tick for the failed task? (1 for Yes 0 for No)\n" - ) - if callSupervisor == "1": - node = behaviour_tree.root - found = False - while not found: - for n in node.children: - if n.status == py_trees.common.Status.FAILURE: - node = n - break - if type(node) == py_trees.composites.Selector: - found = True - # supervisor = py_trees.behaviours.Success(name="Call Supervisor to " + node.name) - supervisor = py_trees.behaviours.Success( - name="Call Supervisor for help" - ) - node.add_children([supervisor]) - - i += 1 - except KeyboardInterrupt: - break - print("\n") - - -if __name__ == "__main__": - main() diff --git a/norms/deliver_medicine_with_reorder.py b/norms/deliver_medicine_with_reorder.py deleted file mode 100644 index 6aa74c6c..00000000 --- a/norms/deliver_medicine_with_reorder.py +++ /dev/null @@ -1,417 +0,0 @@ -#!/usr/bin/env python -# -# License: BSD -# https://raw.githubusercontent.com/splintered-reality/py_trees/devel/LICENSE -# -############################################################################## -# Documentation -############################################################################## - -""" -A py_trees demo. - -.. argparse:: - :module: py_trees.demos.selector - :func: command_line_argument_parser - :prog: py-trees-demo-selector - -.. graphviz:: dot/demo-selector.dot - -.. image:: images/selector.gif - -""" -############################################################################## -# Imports -############################################################################## - -import argparse -import sys -import time -import typing -import operator - -import py_trees -import py_trees.console as console - -############################################################################## -# Classes -############################################################################## - -py_trees.logging.level = py_trees.logging.Level.INFO -blackboard = py_trees.blackboard.Client(name="Client") -blackboard.register_key(key="isCabinetUnlocked", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="isElevatorOpen", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="elevatorHasSpace", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="canEnterElevator", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="isElevatorOn7th", access=py_trees.common.Access.WRITE) -blackboard.register_key(key="canLeaveElevator", access=py_trees.common.Access.WRITE) -blackboard.isCabinetUnlocked = False -blackboard.isElevatorOpen = False -blackboard.elevatorHasSpace = False -blackboard.canEnterElevator = False -blackboard.isElevatorOn7th = False -blackboard.canLeaveElevator = False -# print(blackboard) -# exit() - - -def description() -> str: - """ - Print description and usage information about the program. - - Returns: - the program description string - """ - content = ( - "This is a demonstration of a medicine delivery robot decision tree process.\n" - ) - content += "The robot needs to acquire the medicine, take the elevator to the 7th floor, and then deliver it to the patient.\n" - content += "There are failing nodes within the tree that asks the human for input to demonstrate altering the tree between ticks.\n" - content += "\n" - content += "Key:\n" - content += ( - "'--> ' - A leaf node that can return success, failure, or running when ran.\n" - ) - content += "'\{-\} Sequence' - A sequential operator with children that will be run in sequential order.\n" - content += "'\{o\} Selector' - A fallback operator with children that will be run one at a time if the previous child fails.\n" - content += "'-' - A node that has not been ran in the current tick yet.\n" - content += "'✕' - A node that has ran and failed in the current tick.\n" - content += "'✓' - A node that has ran and succeeded in the current tick.\n" - content += "'*' - A node that has ran and returned running in the current tick.\n" - - if py_trees.console.has_colours: - banner_line = console.green + "*" * 79 + "\n" + console.reset - s = banner_line - s += console.bold_white + "Norms".center(79) + "\n" + console.reset - s += banner_line - s += "\n" - s += content - s += "\n" - s += banner_line - else: - s = content - return s - - -def epilog() -> typing.Optional[str]: - """ - Print a noodly epilog for --help. - - Returns: - the noodly message - """ - if py_trees.console.has_colours: - return ( - console.cyan - + "And his noodly appendage reached forth to tickle the blessed...\n" - + console.reset - ) - else: - return None - - -def command_line_argument_parser() -> argparse.ArgumentParser: - """ - Process command line arguments. - - Returns: - the argument parser - """ - parser = argparse.ArgumentParser( - description=description(), - epilog=epilog(), - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - group = parser.add_mutually_exclusive_group() - group.add_argument( - "-r", "--render", action="store_true", help="render dot tree to file" - ) - group.add_argument( - "--render-with-blackboard-variables", - action="store_true", - help="render dot tree to file with blackboard variables", - ) - group.add_argument( - "-i", - "--interactive", - action="store_true", - help="pause and wait for keypress at each tick", - ) - return parser - - -def wait(name, ticks) -> py_trees.behaviours.StatusQueue: - queue = [] - for i in range(0, ticks + 1): - queue.append(py_trees.common.Status.RUNNING) - return py_trees.behaviours.StatusQueue( - name=name, - queue=queue, - eventually=py_trees.common.Status.FAILURE, - ) - - -def create_root() -> py_trees.behaviour.Behaviour: - """ - Create the root behaviour and it's subtree. - - Returns: - the root behaviour - """ - # print(blackboard) - - root = py_trees.composites.Sequence(name="Sequence", memory=False) - - get_medicine = py_trees.composites.Sequence(name="Sequence", memory=False) - - take_elevator = py_trees.composites.Sequence(name="Sequence", memory=False) - - deliver_medicine = py_trees.composites.Sequence(name="Sequence", memory=False) - - root.add_children([get_medicine, take_elevator, deliver_medicine]) - - go_to = py_trees.behaviours.Success(name="Go To Medicine Cabinet") - unlock = py_trees.composites.Selector(name="Selector", memory=False) - take = py_trees.behaviours.Success(name="Pickup Medicine") - get_medicine.add_children([go_to, unlock, take]) - - unlock_cabinet = py_trees.behaviours.CheckBlackboardVariableValue( - name="Unlock Cabinet", - check=py_trees.common.ComparisonExpression( - variable="isCabinetUnlocked", value=True, operator=operator.eq - ), - ) - - wait_cabinet = py_trees.behaviours.Running(name="Wait") - supervisor = py_trees.behaviours.Success(name="Call Supervisor for Virtual Unlock") - unlock.add_children([unlock_cabinet, wait_cabinet, supervisor]) - - go_to_elevator = py_trees.behaviours.Success(name="Go to Elevator") - click_up_button = py_trees.behaviours.Success(name="Click Up Button") - wait_for_elevator = py_trees.composites.Sequence(name="Sequence", memory=False) - enter_elevator = py_trees.composites.Sequence(name="Sequence", memory=False) - - take_elevator.add_children( - [go_to_elevator, click_up_button, wait_for_elevator, enter_elevator] - ) - - is_elevator_open = py_trees.composites.Selector(name="Selector", memory=False) - has_space_in_elevator = py_trees.composites.Selector(name="Selector", memory=False) - can_enter_elevator = py_trees.composites.Selector(name="Selector", memory=False) - wait_for_elevator.add_children( - [is_elevator_open, has_space_in_elevator, can_enter_elevator] - ) - - elevator_open = py_trees.behaviours.CheckBlackboardVariableValue( - name="Is Elevator Open?", - check=py_trees.common.ComparisonExpression( - variable="isElevatorOpen", value=True, operator=operator.eq - ), - ) - wait_for_open_elevator = py_trees.behaviours.Running(name="Wait") - button_again = py_trees.behaviours.Running(name="Press button again") - supervisor = py_trees.behaviours.Success( - name="Call Supervisor to Virtually Call Elevator" - ) - is_elevator_open.add_children( - [ - elevator_open, - wait_for_open_elevator, - button_again, - supervisor, - ] - ) - # is_elevator_open.add_children([elevator_open, wait_for_open_elevator]) - - elevator_space = py_trees.behaviours.CheckBlackboardVariableValue( - name=">= 9ft^2 of space in the Elevator?", - check=py_trees.common.ComparisonExpression( - variable="elevatorHasSpace", value=True, operator=operator.eq - ), - ) - wait_for_space = py_trees.behaviours.Running(name="State I’ll wait") - has_space_in_elevator.add_children([elevator_space, wait_for_space]) - - elevator_enter = py_trees.behaviours.CheckBlackboardVariableValue( - name="Ask to enter Elevator", - check=py_trees.common.ComparisonExpression( - variable="canEnterElevator", value=True, operator=operator.eq - ), - ) - wait_to_enter_elevator = py_trees.behaviours.Running(name="State I’ll wait") - can_enter_elevator.add_children([elevator_enter, wait_to_enter_elevator]) - - enter_elevator_task = py_trees.behaviours.Success(name="Enter Elevator") - hit_7th_floor_button = py_trees.behaviours.Success(name="Hit 7th Floor Button") - enter_elevator.add_children([enter_elevator_task, hit_7th_floor_button]) - - exit = py_trees.composites.Sequence(name="Sequence", memory=False) - exit_statement = py_trees.behaviours.Success(name="State: I'll exit now") - go_to_patient = py_trees.behaviours.Success(name="Go to Patient") - deliver = py_trees.behaviours.Success(name="Deliver medicine to Patient") - deliver_medicine.add_children([exit, exit_statement, go_to_patient, deliver]) - - get_to_7th = py_trees.composites.Selector(name="Selector", memory=False) - can_exit_now = py_trees.composites.Selector(name="Selector", memory=False) - - exit.add_children([get_to_7th, can_exit_now]) - - is_elevator_on_7th = py_trees.behaviours.CheckBlackboardVariableValue( - name="Is Elevator on 7th?", - check=py_trees.common.ComparisonExpression( - variable="isElevatorOn7th", value=True, operator=operator.eq - ), - ) - elevator_wait = py_trees.behaviours.Running(name="Wait") - get_to_7th.add_children([is_elevator_on_7th, elevator_wait]) - - are_people_on_elevator = py_trees.behaviours.CheckBlackboardVariableValue( - name="Is >= 1 Person in Elevator?", - check=py_trees.common.ComparisonExpression( - variable="canLeaveElevator", value=True, operator=operator.eq - ), - ) - exit_elevator_wait = wait("Wait for at most 3 Ticks", 3) - can_exit_now.add_children([are_people_on_elevator, exit_elevator_wait]) - - return root - - -############################################################################## -# Main -############################################################################## - - -def main() -> None: - """Entry point for the demo script.""" - args = command_line_argument_parser().parse_args() - print(description()) - # print(blackboard) - - root = create_root() - - #################### - # Rendering - #################### - if args.render: - py_trees.display.render_dot_tree(root) - sys.exit() - - #################### - # Execute - #################### - behaviour_tree = py_trees.trees.BehaviourTree(root) - behaviour_tree.visitors.append(py_trees.visitors.DebugVisitor()) - snapshot_visitor = py_trees.visitors.SnapshotVisitor() - behaviour_tree.visitors.append(snapshot_visitor) - print(py_trees.display.unicode_tree(root=root, show_status=True)) - tree_success = False - i = 0 - time.sleep(1) - while not tree_success: - try: - time.sleep(0.5) - print("\n--------- Tick {0} ---------\n".format(i)) - # if i == 3: - # print("Cabinet is now unlocked\n") - # blackboard.isCabinetUnlocked = True - # if i == 5: - # blackboard.isElevatorOpen = True - if i == 7: - blackboard.elevatorHasSpace = True - if i == 9: - blackboard.canEnterElevator = True - if i == 11: - blackboard.isElevatorOn7th = True - if i == 13: - blackboard.canLeaveElevator = True - # if i == 15: - # blackboard.isElevatorOpen = True - - behaviour_tree.tick() - print("\n") - print(py_trees.display.unicode_tree(root=root, show_status=True)) - # ascii_tree = py_trees.display.ascii_tree( - # behaviour_tree.root) - # print(ascii_tree) - if behaviour_tree.root.status == py_trees.common.Status.SUCCESS: - tree_success = True - elif behaviour_tree.root.status == py_trees.common.Status.FAILURE: - callSupervisor = input( - "Should the robot call it's supervisor for help on the next tick for the failed task? (1 for Yes 0 for No)\n" - ) - if callSupervisor == "1": - node = behaviour_tree.root - found = False - while not found: - for n in node.children: - if n.status == py_trees.common.Status.FAILURE: - node = n - break - if type(node) == py_trees.composites.Selector: - found = True - # supervisor = py_trees.behaviours.Success(name="Call Supervisor to " + node.name) - supervisor = py_trees.behaviours.Success( - name="Call Supervisor for help" - ) - node.add_children([supervisor]) - elif behaviour_tree.root.status == py_trees.common.Status.RUNNING: - reorder = input( - "Would you like to reorder the children of the Selector that is running? (1 for Yes 0 for No)\n" - ) - if reorder == "1": - node = behaviour_tree.root - found = False - while not found: - for n in node.children: - if n.status == py_trees.common.Status.RUNNING: - node = n - break - if type(node) == py_trees.behaviours.Running: - found = True - # supervisor = py_trees.behaviours.Success(name="Call Supervisor to " + node.name) - parent = node.parent - stored_children = [] - for i in range(0, len(parent.children)): - child = parent.children[0] - print("Node", i, "-", child.name) - stored_children.append(child) - parent.remove_child(child) - print("\n") - stored = [] - for i in range(0, len(stored_children)): - valid_input = False - while not valid_input: - user_input = input( - "Which node (input number e.g. 0) would you like in position " - + str(i) - + "? " - ) - try: - node_number = int(user_input) - except ValueError: - print( - "Please enter an integer equal to one of the node numbers." - ) - continue - if node_number >= len(stored_children) or node_number < 0: - print( - "Please enter an integer equal to one of the node numbers." - ) - elif node_number in stored: - print( - "Please enter a node that hasn't been used already." - ) - else: - stored.append(node_number) - valid_input = True - parent.add_child(stored_children[node_number]) - - i += 1 - except KeyboardInterrupt: - break - print("\n") - - -if __name__ == "__main__": - main() diff --git a/norms/nest.py b/norms/nest.py deleted file mode 100644 index fc785345..00000000 --- a/norms/nest.py +++ /dev/null @@ -1,195 +0,0 @@ -#!/usr/bin/env python -# -# License: BSD -# https://raw.githubusercontent.com/splintered-reality/py_trees/devel/LICENSE -# -############################################################################## -# Documentation -############################################################################## - -""" -A py_trees demo. - -.. argparse:: - :module: py_trees.demos.selector - :func: command_line_argument_parser - :prog: py-trees-demo-selector - -.. graphviz:: dot/demo-selector.dot - -.. image:: images/selector.gif - -""" -############################################################################## -# Imports -############################################################################## - -import argparse -import sys -import time -import typing - -import py_trees -import py_trees.console as console - -############################################################################## -# Classes -############################################################################## - - -def description() -> str: - """ - Print description and usage information about the program. - - Returns: - the program description string - """ - content = ( - "Higher priority switching and interruption in the children of a selector.\n" - ) - content += "\n" - content += "In this example the higher priority child is setup to fail initially,\n" - content += "falling back to the continually running second child. On the third\n" - content += ( - "tick, the first child succeeds and cancels the hitherto running child.\n" - ) - if py_trees.console.has_colours: - banner_line = console.green + "*" * 79 + "\n" + console.reset - s = banner_line - s += console.bold_white + "Selectors".center(79) + "\n" + console.reset - s += banner_line - s += "\n" - s += content - s += "\n" - s += banner_line - else: - s = content - return s - - -def epilog() -> typing.Optional[str]: - """ - Print a noodly epilog for --help. - - Returns: - the noodly message - """ - if py_trees.console.has_colours: - return ( - console.cyan - + "And his noodly appendage reached forth to tickle the blessed...\n" - + console.reset - ) - else: - return None - - -def command_line_argument_parser() -> argparse.ArgumentParser: - """ - Process command line arguments. - - Returns: - the argument parser - """ - parser = argparse.ArgumentParser( - description=description(), - epilog=epilog(), - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - parser.add_argument( - "-r", "--render", action="store_true", help="render dot tree to file" - ) - return parser - - -def create_root() -> py_trees.behaviour.Behaviour: - """ - Create the root behaviour and it's subtree. - - Returns: - the root behaviour - """ - root = py_trees.composites.Selector(name="Selector", memory=True) - root2 = py_trees.composites.Selector(name="Selector", memory=True) - root3 = py_trees.composites.Selector(name="Selector", memory=True) - ffs = py_trees.behaviours.StatusQueue( - name="FFS", - queue=[ - py_trees.common.Status.FAILURE, - py_trees.common.Status.FAILURE, - py_trees.common.Status.SUCCESS, - ], - eventually=py_trees.common.Status.SUCCESS, - ) - always_running = py_trees.behaviours.Running(name="Running") - ffs3 = py_trees.behaviours.StatusQueue( - name="FFS", - queue=[ - py_trees.common.Status.FAILURE, - py_trees.common.Status.FAILURE, - py_trees.common.Status.SUCCESS, - ], - eventually=py_trees.common.Status.SUCCESS, - ) - always_running3 = py_trees.behaviours.Running(name="Running") - ffs2 = py_trees.behaviours.StatusQueue( - name="FFS", - queue=[ - py_trees.common.Status.FAILURE, - py_trees.common.Status.FAILURE, - py_trees.common.Status.SUCCESS, - ], - eventually=py_trees.common.Status.SUCCESS, - ) - always_running2 = py_trees.behaviours.Running(name="Running") - new_root = py_trees.composites.Selector(name="Selector", memory=False).add_children( - [root, root2, root3] - ) - # new_root.add_children([ffs, always_running]) - root.add_children([ffs]) - root2.add_children([ffs2]) - root3.add_children([ffs3, always_running]) - # root2.add_children([ffs, always_running]) - # root3.add_children([ffs2, always_running2]) - # root.add_children([ffs3, always_running3]) - return new_root - - -############################################################################## -# Main -############################################################################## - - -def main() -> None: - """Entry point for the demo script.""" - args = command_line_argument_parser().parse_args() - print(description()) - py_trees.logging.level = py_trees.logging.Level.DEBUG - - root = create_root() - - #################### - # Rendering - #################### - if args.render: - py_trees.display.render_dot_tree(root) - sys.exit() - - #################### - # Execute - #################### - root.setup_with_descendants() - for i in range(1, 12): - try: - print("\n--------- Tick {0} ---------\n".format(i)) - root.tick_once() - print("\n") - print(py_trees.display.unicode_tree(root=root, show_status=True)) - time.sleep(1.0) - except KeyboardInterrupt: - break - print("\n") - - -if __name__ == "__main__": - main() diff --git a/norms/norms.py b/norms/norms.py deleted file mode 100644 index eee6740b..00000000 --- a/norms/norms.py +++ /dev/null @@ -1,12 +0,0 @@ -print("") -print("Cabinet is locked.") -print("Would you like to change the priorities of actions?") -print("") -print("A - Try Unlocking Cabinet again") -print("B – Wait 10 seconds") -print("C – Call supervisor for remote unlock") -print("") -print("Which action should I take first? (type A, B, or C) _") -print("Which action should I take second? (type A, B, or C) _") -print("") -print("") diff --git a/norms/selector.py b/norms/selector.py deleted file mode 100644 index ba4ed2a8..00000000 --- a/norms/selector.py +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env python -# -# License: BSD -# https://raw.githubusercontent.com/splintered-reality/py_trees/devel/LICENSE -# -############################################################################## -# Documentation -############################################################################## - -""" -A py_trees demo. - -.. argparse:: - :module: py_trees.demos.selector - :func: command_line_argument_parser - :prog: py-trees-demo-selector - -.. graphviz:: dot/demo-selector.dot - -.. image:: images/selector.gif - -""" -############################################################################## -# Imports -############################################################################## - -import argparse -import sys -import time -import typing - -import py_trees -import py_trees.console as console - -############################################################################## -# Classes -############################################################################## - - -def description() -> str: - """ - Print description and usage information about the program. - - Returns: - the program description string - """ - content = ( - "Higher priority switching and interruption in the children of a selector.\n" - ) - content += "\n" - content += "In this example the higher priority child is setup to fail initially,\n" - content += "falling back to the continually running second child. On the third\n" - content += ( - "tick, the first child succeeds and cancels the hitherto running child.\n" - ) - if py_trees.console.has_colours: - banner_line = console.green + "*" * 79 + "\n" + console.reset - s = banner_line - s += console.bold_white + "Selectors".center(79) + "\n" + console.reset - s += banner_line - s += "\n" - s += content - s += "\n" - s += banner_line - else: - s = content - return s - - -def epilog() -> typing.Optional[str]: - """ - Print a noodly epilog for --help. - - Returns: - the noodly message - """ - if py_trees.console.has_colours: - return ( - console.cyan - + "And his noodly appendage reached forth to tickle the blessed...\n" - + console.reset - ) - else: - return None - - -def command_line_argument_parser() -> argparse.ArgumentParser: - """ - Process command line arguments. - - Returns: - the argument parser - """ - parser = argparse.ArgumentParser( - description=description(), - epilog=epilog(), - formatter_class=argparse.RawDescriptionHelpFormatter, - ) - parser.add_argument( - "-r", "--render", action="store_true", help="render dot tree to file" - ) - return parser - - -def create_root() -> py_trees.behaviour.Behaviour: - """ - Create the root behaviour and it's subtree. - - Returns: - the root behaviour - """ - root = py_trees.composites.Selector(name="Selector", memory=False) - ffs = py_trees.behaviours.StatusQueue( - name="FFS", - queue=[ - py_trees.common.Status.FAILURE, - py_trees.common.Status.FAILURE, - py_trees.common.Status.SUCCESS, - ], - eventually=py_trees.common.Status.SUCCESS, - ) - always_running = py_trees.behaviours.Running(name="Running") - root.add_children([ffs, always_running]) - return root - - -############################################################################## -# Main -############################################################################## - - -def main() -> None: - """Entry point for the demo script.""" - args = command_line_argument_parser().parse_args() - print(description()) - py_trees.logging.level = py_trees.logging.Level.DEBUG - - root = create_root() - - #################### - # Rendering - #################### - if args.render: - py_trees.display.render_dot_tree(root) - sys.exit() - - #################### - # Execute - #################### - root.setup_with_descendants() - for i in range(1, 4): - try: - print("\n--------- Tick {0} ---------\n".format(i)) - root.tick_once() - print("\n") - print(py_trees.display.unicode_tree(root=root, show_status=True)) - time.sleep(1.0) - except KeyboardInterrupt: - break - print("\n") - - -# main() diff --git a/norms/wsocket.html b/norms/wsocket.html deleted file mode 100644 index 628ee5d6..00000000 --- a/norms/wsocket.html +++ /dev/null @@ -1,28 +0,0 @@ - - - -
- - - -