Skip to content

Commit

Permalink
Publish current action (#106)
Browse files Browse the repository at this point in the history
  • Loading branch information
Flova authored Feb 18, 2024
2 parents 77db53f + 45b1932 commit badc0bc
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 31 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,5 @@ ENV/
**/docs/_out
**/docs/cppapi
**/docs/pyapi

.ruff_cache/
5 changes: 1 addition & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@ repos:
args:
- "--fix"
- "--exit-non-zero-on-fix"
- repo: https://github.com/psf/black
rev: 23.10.0 # keep this version for Ubuntu support
hooks:
- id: black
- id: ruff-format
- repo: https://github.com/pocc/pre-commit-hooks
rev: v1.3.5
hooks:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
from abc import ABCMeta
from typing import TYPE_CHECKING

from dynamic_stack_decider.abstract_stack_element import AbstractStackElement

if TYPE_CHECKING:
from dynamic_stack_decider.dsd import DSD


class AbstractActionElement(AbstractStackElement, metaclass=ABCMeta):
"""
Expand All @@ -14,19 +18,16 @@ class AbstractActionElement(AbstractStackElement, metaclass=ABCMeta):
If the action is complete, it can remove itself from the stack by performing a pop command.
"""

def __init__(self, blackboard, dsd, parameters=None):
def __init__(self, blackboard, dsd: "DSD", parameters: dict[str, bool | int | float | str]):
"""
Constructor of the action element
:param blackboard: Shared blackboard for data exchange between elements
:param dsd: The stack decider which has this element on its stack.
:param parameters: Optional parameters which serve as arguments to this element
:param parameters: Parameters which serve as arguments to this element
"""
super().__init__(blackboard, dsd, parameters)
# Reevaluation can be disabled by setting 'r' or 'reevaluate' to False
if parameters is not None:
self.never_reevaluate = not parameters.get("r", True) or not parameters.get("reevaluate", True)
else:
self.never_reevaluate = False
self.never_reevaluate = not parameters.get("r", True) or not parameters.get("reevaluate", True)

def do_not_reevaluate(self):
"""
Expand All @@ -41,6 +42,6 @@ def repr_dict(self) -> dict:
"""
return {
"type": "action",
"name": self.__class__.__name__,
"name": self.name,
"debug_data": self._debug_data,
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def repr_dict(self) -> dict:
"""
return {
"type": "decision",
"name": self.__class__.__name__,
"name": self.name,
"debug_data": self._debug_data,
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from abc import ABCMeta, abstractmethod
from typing import Union
from typing import TYPE_CHECKING, Union

from dynamic_stack_decider.logger import get_logger

if TYPE_CHECKING:
from dynamic_stack_decider.dsd import DSD


class AbstractStackElement(metaclass=ABCMeta):
"""
Expand All @@ -12,14 +15,14 @@ class AbstractStackElement(metaclass=ABCMeta):
Each element which inherits from the AbstractStackElement can be used as a root element on the stack.
"""

_dsd = None
_init_data = None
_dsd: "DSD"
parameters: dict[str, bool | int | float | str]

def __init__(self, blackboard, dsd, parameters=None):
def __init__(self, blackboard, dsd: "DSD", parameters: dict[str, bool | int | float | str]):
"""
:param blackboard: Shared blackboard for data exchange between elements
:param dsd: The stack decider which has this element on its stack.
:param parameters: Optional parameters which serve as arguments to this element
:param parameters: Parameters which serve as arguments to this element
"""
self._debug_data = {}
"""
Expand All @@ -28,8 +31,16 @@ def __init__(self, blackboard, dsd, parameters=None):
"""

self._dsd = dsd
self.parameters = parameters
self.blackboard = blackboard

@property
def name(self) -> str:
"""
Returns the name of the action
"""
return self.__class__.__name__

def pop(self):
"""
Help method which pops the element of the stack.
Expand Down Expand Up @@ -90,6 +101,6 @@ def repr_dict(self) -> dict:
"""Represent this stack element as dictionary which is JSON encodable"""
return {
"type": "abstract",
"name": self.__class__.__name__,
"name": self.name,
"debug_data": self._debug_data,
}
35 changes: 33 additions & 2 deletions dynamic_stack_decider/dynamic_stack_decider/dsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class DSD:
stack_reevaluate = False
do_not_reevaluate = False
old_representation = ""
debug_active_action_cache: Optional[str] = None

def __init__(self, blackboard, debug_topic: str = None, node: Optional[Node] = None):
"""
Expand Down Expand Up @@ -142,6 +143,10 @@ def __init__(self, blackboard, debug_topic: str = None, node: Optional[Node] = N
debug_stack_topic = f"{debug_topic}/dsd_stack"
self.debug_stack_publisher = node.create_publisher(String, debug_stack_topic, 10)
get_logger().debug(f"Debugging stack on '{debug_stack_topic}'")
# Publish the currently active action
debug_current_action_topic = f"{debug_topic}/dsd_current_action"
self.debug_current_action_publisher = node.create_publisher(String, debug_current_action_topic, 10)
get_logger().debug(f"Debugging current action on '{debug_current_action_topic}'")

def register_actions(self, module_path):
"""
Expand Down Expand Up @@ -196,7 +201,7 @@ def _bind_modules(self, element):
else:
raise ValueError(f'Unknown parser tree element type "{type(element)}" for element "{element}"!')

def _init_element(self, element):
def _init_element(self, element: AbstractTreeElement):
"""Initializes the module belonging to the given element."""
if isinstance(element, SequenceTreeElement):
initialized_actions = list()
Expand All @@ -206,7 +211,7 @@ def _init_element(self, element):
else:
return element.module(self.blackboard, self, element.parameters)

def set_start_element(self, start_element):
def set_start_element(self, start_element: AbstractTreeElement):
"""
This method defines the start element on the stack, which stays always on the bottom of the stack.
It should be called in __init__.
Expand Down Expand Up @@ -236,6 +241,7 @@ def update(self, reevaluate: bool = True):
"""
try:
self.debug_publish_stack()
self.debug_publish_current_action()

if reevaluate and not self.do_not_reevaluate:
self.stack_exec_index = 0
Expand Down Expand Up @@ -362,3 +368,28 @@ def debug_publish_tree(self):
data = self.tree.repr_dict()
msg = String(data=json.dumps(data))
self.debug_tree_publisher.publish(msg)

def debug_publish_current_action(self):
"""
Publishes the name of the currently active action
"""
# Check if debugging is active and if there is something on the stack
if not self.debug_active or len(self.stack) == 0:
return

# Get the top element
stack_top = self.stack[-1][1]
# Check if it is an action or a sequence element and retrieve the current action
if isinstance(stack_top, AbstractActionElement):
current_action = stack_top
elif isinstance(stack_top, SequenceElement):
current_action = stack_top.current_action
else:
return

# Only publish if the action changed
if current_action.name != self.debug_active_action_cache:
# Publish the name of the current action
self.debug_current_action_publisher.publish(String(data=current_action.name))
# Cache the current action name
self.debug_active_action_cache = current_action.name
20 changes: 11 additions & 9 deletions dynamic_stack_decider/dynamic_stack_decider/sequence_element.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
from typing import TYPE_CHECKING

from dynamic_stack_decider.abstract_action_element import AbstractActionElement
from dynamic_stack_decider.abstract_stack_element import AbstractStackElement

if TYPE_CHECKING:
from dynamic_stack_decider.dsd import DSD


class SequenceElement(AbstractStackElement):
"""
Expand All @@ -10,11 +16,11 @@ class SequenceElement(AbstractStackElement):
This is not an abstract class to inherit from.
"""

def __init__(self, blackboard, dsd, actions=()):
def __init__(self, blackboard, dsd: "DSD", actions: list[AbstractActionElement]):
"""
:param actions: list of initialized action elements
"""
super().__init__(blackboard, dsd)
super().__init__(blackboard, dsd, dict())
self.actions = actions
self.current_action_index = 0

Expand All @@ -40,21 +46,17 @@ def in_last_element(self):
return self.current_action_index == len(self.actions) - 1

@property
def current_action(self):
def current_action(self) -> AbstractActionElement:
"""
Returns the currently executed action of the sequence element
:rtype: AbstractActionElement
"""
return self.actions[self.current_action_index]

def repr_dict(self):
def repr_dict(self) -> dict:
"""
Represent this stack element as dictionary which is JSON encodable
:rtype: dict
"""
self.publish_debug_data("Active Element", self.current_action.__class__.__name__)
self.publish_debug_data("Active Element", self.current_action.name)
if self.current_action._debug_data:
self.publish_debug_data("Corresponding debug data", self.current_action._debug_data)
data = {
Expand Down
2 changes: 0 additions & 2 deletions dynamic_stack_decider/dynamic_stack_decider/tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ def __init__(self, name, parent, parameters=None, unset_parameters=None):
:param parent: the parent element, None for the root element
:param parameters: A dictionary of parameters
:param unset_parameters: A dictionary of parameters that must be set later
:type parent: DecisionTreeElement
"""
# Call the constructor of the superclass
super().__init__(name, parent, parameters, unset_parameters)
Expand Down Expand Up @@ -185,7 +184,6 @@ def __init__(self, name, parent, parameters=None, unset_parameters=None):
Create a new ActionTreeElement
:param name: the class name of the corresponding AbstractActionElement
:param parent: the parent element
:type parent: DecisionTreeElement
:param parameters: A dictionary of parameters
:param unset_parameters: A dictionary of parameters that must be set later
"""
Expand Down

0 comments on commit badc0bc

Please sign in to comment.