diff --git a/src/as2fm/as2fm_common/common.py b/src/as2fm/as2fm_common/common.py index 19f26ad0..b0b494c1 100644 --- a/src/as2fm/as2fm_common/common.py +++ b/src/as2fm/as2fm_common/common.py @@ -59,16 +59,6 @@ def remove_namespace(tag: str) -> str: return tag_wo_ns -def substitute_xml_escaping(text: str) -> str: - """ - Substitute the XML escaping characters in the text. - - :param text: The text to substitute the characters in. - :return: The text with the characters substituted. - """ - return text.replace("<", "<").replace(">", ">").replace("&", "&") - - def is_comment(element: _Element) -> bool: """ Check if an element is a comment. diff --git a/src/as2fm/as2fm_common/ecmascript_interpretation.py b/src/as2fm/as2fm_common/ecmascript_interpretation.py index 13f3f479..1437f3db 100644 --- a/src/as2fm/as2fm_common/ecmascript_interpretation.py +++ b/src/as2fm/as2fm_common/ecmascript_interpretation.py @@ -22,7 +22,7 @@ import js2py -from as2fm.as2fm_common.common import ValidTypes, substitute_xml_escaping +from as2fm.as2fm_common.common import ValidTypes BasicJsTypes = Union[int, float, bool] @@ -36,7 +36,6 @@ def interpret_ecma_script_expr( :param expr: The ECMA script expression :return: The interpreted object """ - expr = substitute_xml_escaping(expr) if variables is None: variables = {} context = js2py.EvalJs(variables) diff --git a/src/as2fm/jani_generator/scxml_helpers/scxml_expression.py b/src/as2fm/jani_generator/scxml_helpers/scxml_expression.py index 617f31ee..7e92ccb5 100644 --- a/src/as2fm/jani_generator/scxml_helpers/scxml_expression.py +++ b/src/as2fm/jani_generator/scxml_helpers/scxml_expression.py @@ -22,7 +22,6 @@ import esprima -from as2fm.as2fm_common.common import substitute_xml_escaping from as2fm.jani_generator.jani_entries.jani_convince_expression_expansion import ( CALLABLE_OPERATORS_MAP, OPERATORS_TO_JANI_MAP, @@ -54,7 +53,6 @@ def parse_ecmascript_to_jani_expression( :param array_info: The type and max size of the array, if required. :return: The jani expression. """ - ecmascript = substitute_xml_escaping(ecmascript) try: ast = esprima.parseScript(ecmascript) except esprima.error_handler.Error as e: diff --git a/src/as2fm/scxml_converter/scxml_entries/scxml_bt_ticks.py b/src/as2fm/scxml_converter/scxml_entries/scxml_bt_ticks.py index a9272f97..b625613e 100644 --- a/src/as2fm/scxml_converter/scxml_entries/scxml_bt_ticks.py +++ b/src/as2fm/scxml_converter/scxml_entries/scxml_bt_ticks.py @@ -35,7 +35,11 @@ generate_bt_response_event, generate_bt_tick_event, ) -from as2fm.scxml_converter.scxml_entries.utils import is_non_empty_string +from as2fm.scxml_converter.scxml_entries.utils import ( + CallbackType, + get_plain_expression, + is_non_empty_string, +) from as2fm.scxml_converter.scxml_entries.xml_utils import assert_xml_tag_ok, get_xml_argument @@ -176,6 +180,9 @@ def __init__( def instantiate_bt_events( self, instance_id: int, children_ids: List[int] ) -> List[ScxmlTransition]: + plain_cond_expr = None + if self._condition is not None: + plain_cond_expr = get_plain_expression(self._condition, CallbackType.BT_RESPONSE) if isinstance(self._child_id, int): # Handling specific child ID, return a single transition assert self._child_id < len(children_ids), ( @@ -186,18 +193,18 @@ def instantiate_bt_events( return [ ScxmlTransition( self._target, - [generate_bt_tick_event(target_child_id)], - self._condition, + [generate_bt_response_event(target_child_id)], + plain_cond_expr, self._body, ).instantiate_bt_events(instance_id, children_ids) ] else: # Handling a generic child ID, return a transition for each child - condition_prefix = "" if self._condition is None else f"({self._condition}) && " + condition_prefix = "" if plain_cond_expr is None else f"({plain_cond_expr}) && " return [ ScxmlTransition( self._target, - [generate_bt_tick_event(child_id)], + [generate_bt_response_event(child_id)], condition_prefix + f"({self._child_id} == {child_id})", self._body, ).instantiate_bt_events(instance_id, children_ids) diff --git a/src/as2fm/scxml_converter/scxml_entries/utils.py b/src/as2fm/scxml_converter/scxml_entries/utils.py index 38f71f92..b35a7459 100644 --- a/src/as2fm/scxml_converter/scxml_entries/utils.py +++ b/src/as2fm/scxml_converter/scxml_entries/utils.py @@ -71,6 +71,7 @@ class CallbackType(Enum): ROS_ACTION_GOAL = auto() # Action callback ROS_ACTION_RESULT = auto() # Action callback ROS_ACTION_FEEDBACK = auto() # Action callback + BT_RESPONSE = auto() # BT response callback @staticmethod def get_expected_prefixes(cb_type: "CallbackType") -> List[str]: @@ -90,6 +91,8 @@ def get_expected_prefixes(cb_type: "CallbackType") -> List[str]: return ["_action.goal_id", "_wrapped_result.code", "_wrapped_result.result."] elif cb_type == CallbackType.ROS_ACTION_FEEDBACK: return ["_action.goal_id", "_feedback."] + elif cb_type == CallbackType.BT_RESPONSE: + return ["_bt.status"] @staticmethod def get_plain_callback(cb_type: "CallbackType") -> "CallbackType": @@ -147,27 +150,28 @@ def _contains_prefixes(msg_expr: str, prefixes: List[str]) -> bool: return False -def get_plain_expression(msg_expr: str, cb_type: CallbackType) -> str: +def get_plain_expression(in_expr: str, cb_type: CallbackType) -> str: """ Convert a ROS interface expressions (using ROS-specific PREFIXES) to plain SCXML. - :param msg_expr: The expression to convert. + :param in_expr: The expression to convert. :param cb_type: The type of callback the expression is used in. """ expected_prefixes = CallbackType.get_expected_prefixes(cb_type) # pre-check over the expression if PLAIN_SCXML_EVENT_PREFIX not in expected_prefixes: - assert not _contains_prefixes(msg_expr, [PLAIN_SCXML_EVENT_PREFIX]), ( - "Error: SCXML ROS conversion: " - f"unexpected {PLAIN_SCXML_EVENT_PREFIX} prefix in expr. {msg_expr}" + assert not _contains_prefixes(in_expr, [PLAIN_SCXML_EVENT_PREFIX]), ( + "Error: SCXML-ROS expression conversion: " + f"unexpected {PLAIN_SCXML_EVENT_PREFIX} prefix in expr. {in_expr}" ) forbidden_prefixes = ROS_EVENT_PREFIXES.copy() if len(expected_prefixes) == 0: forbidden_prefixes.append(PLAIN_SCXML_EVENT_PREFIX) - new_expr = _replace_ros_interface_expression(msg_expr, expected_prefixes) - assert not _contains_prefixes( - new_expr, forbidden_prefixes - ), f"Error: SCXML ROS conversion: unexpected ROS interface prefixes in expr.: {msg_expr}" + new_expr = _replace_ros_interface_expression(in_expr, expected_prefixes) + assert not _contains_prefixes(new_expr, forbidden_prefixes), ( + "Error: SCXML-ROS expression conversion: " + f"unexpected ROS interface prefixes in expr.: {in_expr}" + ) return new_expr