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

ActionServerBT Overhaul and Add Static TF Object #114

Merged
merged 9 commits into from
Sep 28, 2023

Conversation

egordon
Copy link
Collaborator

@egordon egordon commented Sep 28, 2023

Description

As a pre-cursor to the overhaul of the MoveIt2 behaviors, this PR does a smaller overhaul of ActionServerBT (ASBT)

The key idea is that a given ASBT object should act as a generator, where create_tree can be called numerous times with different names and get logically distinct trees. This tree creation should be entirely independent of the action server logic so that it can be used for sub-trees.

Additionally, send_goal, get_result, and get_feedback should be able to be called on any result of create_tree in order to populate / read from the tree's data to implement the action server logic.

Individual behaviors should get their ROS2 Node from setup (as per #105), but the node is currently passed to the ASBT in __init__ in order to:

  1. Be used in all the AS logic (send_goal, get_result, and get_feedback; likely just for the node clock)
  2. Be used in create_tree to handle only behaviors that don't yet get their ROS node in setup.

Once #105 is solved, it may make sense to remove node from init and pass it directly to the AS functions, but I don't think that's necessary.

Testing procedure

  • Test all MoveTo trees as documented in README (Note: AcquireFood should now fail with a 5s Timeout given an empty message, as there is no valid TF between world and empty string)
  • Test AcquireFood as documented in Add BlackboardBehavior and initial AcquireFood tree #102
  • Make sure to run AcquireFood twice to verify that MoveToVisitor is re-initialized (feedback planning_time should start again at 0).

Before opening a pull request

  • Format your code using black formatter python3 -m black .
  • Run your code through pylint and address all warnings/errors. The only warnings that are acceptable to not address is TODOs that should be addressed in a future PR. From the top-level ada_feeding directory, run: pylint --recursive=y --rcfile=.pylintrc ..

Before Merging

  • Squash & Merge

…aster logic; Next Step is MoveIt2Plan and MoveIt2Execute Behaviors
@egordon egordon self-assigned this Sep 28, 2023
@@ -92,6 +93,87 @@ def quat_between_vectors(vec_from: Vector3, vec_to: Vector3) -> Quaternion:
return ret


def add_update_static_tf(
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you ever intend to let a behavior get the transforms? (e.g., to get the food frame?) If so, I think you should make an analogous getter function for this, as opposed to letting behaviors do it themselves. (To ensure locking logic and such is handled correctly)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Nope, behaviors should get transforms through the TransformListener (get_tf_object() later in the file).

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it. In that case, why do you need to store a dict of the transforms on the blackboard? If you just publish transforms directly to the Broadcaster as this function gets called, shouldn't the Broadcaster handle overriding old transforms? I'm not sure if the dict functionality is necessary.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We do need the dict.

The STB handles the latching (i.e. holding on to the last published messages), but sendTransform just forwards the transform / list of transforms to the publisher.

Actually handling adding transforms to a list is a feature present in CPP but not Python

I'll make an issue upstream

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@@ -92,6 +93,87 @@ def quat_between_vectors(vec_from: Vector3, vec_to: Vector3) -> Quaternion:
return ret


def add_update_static_tf(
Copy link
Contributor

Choose a reason for hiding this comment

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

Name nit: add_update_static_tf seems confusing to me, why not just set_static_tf? And in the docstring you can document that if there is already a static tf for that key, it will be overridden (or you can make override a boolean flag)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Okay on the name, no need for override boolean.

project. All of these extend VisitorBase.
"""

from .moveit2_visitor import MoveIt2Visitor
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this should be called MoveToVisitor, since it is specifically for all the MoveTo trees, right?

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 agree specifically because it is for the MoveTo-style action interface.

Copy link
Contributor

Choose a reason for hiding this comment

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

Generally looks good, but how is initialization handled for visitors?

Related to the above point, when you test this as part of AcquireFood, have at least one test that involves running AcquireFood twice, to ensure the visitor is reset properly.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Good call, I'll test this.

Added a reinit function that will be called if the tree already has a MoveToVisitor on send_goal.

@egordon egordon changed the title MoveTo Action Overhaul ActionServerBT Overhaul Sep 28, 2023
@egordon egordon changed the title ActionServerBT Overhaul ActionServerBT Overhaul and Add Static TF Object Sep 28, 2023
@egordon egordon marked this pull request as ready for review September 28, 2023 18:14
Copy link
Contributor

@amalnanavati amalnanavati left a comment

Choose a reason for hiding this comment

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

LGTM

memory=True,
children=[
compute_food_frame,
py_trees.decorators.Timeout(
Copy link
Contributor

Choose a reason for hiding this comment

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

I feel like the default duration of 5secs is probably too long to wait. What do you think about 1s?

@egordon egordon merged commit fb19d55 into ros2-devel Sep 28, 2023
@egordon egordon deleted the egordon/ros2_movetooverhaul branch September 28, 2023 19:04
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.

2 participants