Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SCXML implementation of BT Control Nodes #58

Merged
merged 46 commits into from
Oct 25, 2024

Conversation

MarcoLm993
Copy link
Collaborator

@MarcoLm993 MarcoLm993 commented Oct 8, 2024

In this PR we introduce a new, modular way of handling Behavior Trees.
In the process of doing this, the old way of sending bt_ticks and the related responses got deprecated, in favor of custom tags that can be found in various examples (the easiest being the... battery drainer: https://github.com/convince-project/AS2FM/pull/58/files#diff-a1c8ee81a504867984b355d25488e8119194f227f5ee5bc3973a530205a382e3)
Be aware that the old plugin name mismatch (Sequences being ReactiveSequences and Fallbacks being ReactiveFallbacks) got fixed as well, so the BT.xml (or policy.xml) files need to be updated as well.

Please let me know if there is anything you find off in the PR :)

@EnricoGhiorzi EnricoGhiorzi marked this pull request as ready for review October 9, 2024 08:48
@EnricoGhiorzi EnricoGhiorzi marked this pull request as draft October 9, 2024 08:49
@EnricoGhiorzi
Copy link

Sorry @MarcoLm993, that was a mistake! Anyway, feel free to request a review from me when the PR is ready.

pyproject.toml Show resolved Hide resolved
@MarcoLm993 MarcoLm993 force-pushed the feature/scxml-for-bt-control-nodes branch from 5c96eff to 2e2ce9d Compare October 11, 2024 12:04
@MarcoLm993 MarcoLm993 force-pushed the feature/scxml-for-bt-control-nodes branch from 2e2ce9d to dab8efe Compare October 14, 2024 07:07
Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
@MarcoLm993 MarcoLm993 force-pushed the feature/scxml-for-bt-control-nodes branch from 407b836 to e00f599 Compare October 15, 2024 08:23
Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
@MarcoLm993 MarcoLm993 marked this pull request as ready for review October 15, 2024 15:07
@MarcoLm993
Copy link
Collaborator Author

For @m-morelli : for the RosCon delib. workshop from Christian, we made a tag of AS2FM (to avoid creating confusion with the new changes). In case you need it, it is the following: https://github.com/convince-project/AS2FM/tree/2024_delib_ws

Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
Signed-off-by: Marco Lampacrescia <[email protected]>
@MarcoLm993 MarcoLm993 requested a review from ct2034 October 17, 2024 07:23
Copy link

@EnricoGhiorzi EnricoGhiorzi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a heroic effort, thank you for your work! As I am unfamiliar with the codebase and even with Python, I tried to mostly get a high-level view of the code, but it all make sense to me. There are just a couple minor remarks but those are non-blocking for merging.

I do have a few general comments that I am going to report here to start a discussion, but they are not meant to be acted on in the context of this PR:

  • The BT translation creates a SCXML machine per node, as opposed to one per tree. I expect this to have a significant negative impact on the performance of verification, and it might be worth tracking this in case future issues arise.
  • The BT has no Halt semantics (yet). Are we going to need it? Critically, which Halt semantics we adopt exactly might depend on which BT runtime we use.
  • I generally worry that, in the process of (SCXML) code generation, we might introduce name-clashing. The code in the PR preserves naming faithfully, as far as I can tell. This (might) create issues in the future, for example when introducing subtrees (nodes from different subtrees might generate SCXML machines with the same name). I suggest decorating generated names with something characterizing their scope, e.g. tree_name-node_name, to make IDs unique. This could also help downstream toolchain components, such as SCAN or STORM.

docs/source/howto.rst Show resolved Hide resolved
docs/source/installation.rst Outdated Show resolved Hide resolved
@MarcoLm993
Copy link
Collaborator Author

This is a heroic effort, thank you for your work! As I am unfamiliar with the codebase and even with Python, I tried to mostly get a high-level view of the code, but it all make sense to me. There are just a couple minor remarks but those are non-blocking for merging.

I do have a few general comments that I am going to report here to start a discussion, but they are not meant to be acted on in the context of this PR:

  • The BT translation creates a SCXML machine per node, as opposed to one per tree. I expect this to have a significant negative impact on the performance of verification, and it might be worth tracking this in case future issues arise.
  • The BT has no Halt semantics (yet). Are we going to need it? Critically, which Halt semantics we adopt exactly might depend on which BT runtime we use.
  • I generally worry that, in the process of (SCXML) code generation, we might introduce name-clashing. The code in the PR preserves naming faithfully, as far as I can tell. This (might) create issues in the future, for example when introducing subtrees (nodes from different subtrees might generate SCXML machines with the same name). I suggest decorating generated names with something characterizing their scope, e.g. tree_name-node_name, to make IDs unique. This could also help downstream toolchain components, such as SCAN or STORM.

Hi Enrico, thanks for the review!

  • Switching to a modular BT expansion (one SCXML per node) will for sure introduce some more communication overhead, but it is definitely going to help in terms of maintainability, since the approach of generating a single state machine for the whole BT was going to require a lot of maintenance and was preventing users to introduce their own controllers, that is something that might be required at some point.
  • Halt semantics are something we should introduce at some point, at least from resetting running nodes in case of timeouts or something like that. However, we did not see them as a very urgent thing and kept postponing their implementation.
  • This is a fair thing to worry about: at the moment SubTrees are not supported but, I think, preventing the name clashing there is possible if we keep the ID counter consistent over the expanded subtrees (i.e. we do no start from 1000 each time we expand a new subtree). It might get problematic if we start having multiple Behavior Trees instances (that would have also independent ticks), but I believe this is also an implementation detail we will need to figure out when we introduce them: the problem is that nothing prevents people from using the same tree name, as far as I know. This is why a different ID generation strategy is required.

Signed-off-by: Marco Lampacrescia <[email protected]>
Copy link
Member

@ct2034 ct2034 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am fine with these. But please look at my three comments

@@ -105,6 +105,7 @@ def must_be_skipped_in_jani_conversion(self):
def is_bt_response_event(self):
"""Check if the event is a behavior tree response event (running, success, failure).
They may have no sender if the plugin does not implement it."""
# TODO: Remove it when deprecated support for running, success, failure BT events is removed
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because with the new handling we have a single bt_response event per BT node (from here https://github.com/convince-project/AS2FM/pull/58/files#diff-8021c3394c29f60e934c8bf2dff081894800c6ccead20ed8b4550085cfe4ef9cR276), containing the response result as a param. This means that, with the new version, bt_response events are expected to be always sent, and there is no reason for skipping them anymore (that was the main reason for this method to exist)

assert (
port_name not in RESERVED_BT_PORT_NAMES
), f"Error: Port name {port_name} is reserved in BT"
# All port IDs are valid
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before these IDs were referring to special fields from btlib, and therefore could not be used.
Now they are referring to the ports that are automatically filled by the processor, and hence they could be set even if they aren't declared (and used) in the scxml model of the BT plugin.

@@ -116,16 +117,30 @@ def get_executable_body(self) -> ScxmlExecutionBody:
"""Return the executable content of this transition."""
return self._body if self._body is not None else []

def instantiate_bt_events(self, instance_id: str):
def instantiate_bt_events(self, instance_id: int, children_ids: List[int]) -> "ScxmlTransition":
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def instantiate_bt_events(self, instance_id: int, children_ids: List[int]) -> "ScxmlTransition":
def instantiate_bt_events(self, instance_id: int, children_ids: List[int]) -> "List[ScxmlTransition]":

Copy link
Collaborator Author

@MarcoLm993 MarcoLm993 Oct 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, for some inherited classes, but here we always return self... Maybe we should check it once again...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made sure that all classes inheriting from ScxmlTransition (and ScxmlTransition itseldf) return a List on that method.

@MarcoLm993 MarcoLm993 merged commit 6a8f1cc into main Oct 25, 2024
4 checks passed
@MarcoLm993 MarcoLm993 deleted the feature/scxml-for-bt-control-nodes branch October 25, 2024 12:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants