BehaviorTree / BehaviorTree.ROS2

BehaviorTree.CPP utilities to work with ROS2
Apache License 2.0
144 stars 59 forks source link

Behavior tree execution on launch #71

Closed marj3220 closed 3 months ago

marj3220 commented 4 months ago

Solves https://github.com/BehaviorTree/BehaviorTree.ROS2/issues/70

I'm working on a project that is supossed to be autonomous, launching a behavior tree on launch of the TreeExecutionServer would be a nice addition. This PR adds a client server so user can put the wanted behavior tree in the config file to launch a behavior tree without a secondary custom node.

facontidavide commented 4 months ago

creating an entire Client for this purpose seems overkill.

Can't we just call the method execute?

marj3220 commented 4 months ago

creating an entire Client for this purpose seems overkill.

Can't we just call the method execute?

I attempted to address this issue. It's possible that my lack of expertise in C++ is a factor. However, due to the fact that the constructor and goal_ attribute of a ServerGoalHandle are protected, I couldn't find a way to generate a goal_handle to then pass to execute.

image

facontidavide commented 4 months ago

I am looking into this and even if technically possible with some work arounds, it raises a lot of questions.

What do you want to happen in case of Action aborted / suceeded / cancelled?

What do you want to happen if another client does send another action? Reject it or cancel the current one?

marj3220 commented 4 months ago

From what I've seen, Behavior Trees (BTs) in robotics often serve as the highest-level controller, with typically only one BT being used and modified in a project. I was seeking a method to statically assign BTs instead of dynamically assigning them during runtime or after launch.

For instance, in Nav2's NavigateToPose and NavigateThroughPoses navigators, there's a parameter for loading XML, which is similar to what I intend. https://github.com/ros-navigation/navigation2/blob/main/nav2_bt_navigator/src/navigators/navigate_to_pose.cpp#L72

With this PR, my main goal is to eliminate the need for creating a ROS2 node solely for sending an action goal once. This would be particularly useful for projects where the BT assignment remains static.

To clarify, I aim to introduce functionality that facilitates static assignment without altering the typical usage of TreeExecutionServer when dynamic control over BT assignment is desired. I do however understand that the cases where the action is aborted / suceeded / cancelled are not taken into account, which is problematic.

Here are my questions for this approach:

  1. Do you believe this functionality would be beneficial? If not, I'll explore alternative solutions within my project.
  2. Is this the appropriate approach to achieve this goal? Alternatively, I could develop a new class heavily inspired by TreeExecutionServer, which functions as a standard ROS2 node with parameters, rather than an action server.

Looking forward to your feedback, @facontidavide.

MarqRazz commented 4 months ago

Why not just call the Server from your launch file?

Here is an example on calling a service from a python launch file.

from launch.substitutions import FindExecutable
from launch.actions import ExecuteProcess

...

ld.add_action(
    ExecuteProcess(
        cmd=[[
            FindExecutable(name='ros2'),
            " service call ",
            "/namespace/service_to_call ",
            "example_msgs/srv/ExampleMsg ",
            '"{param_1: True, param_2: 0.0}"',
        ]],
        shell=True
    )
)
MarqRazz commented 4 months ago

What do you want to happen if another client does send another action? Reject it or cancel the current one?

Low priority for myself but I did plan on making a configuration option so users could choose if a new goal cancels a current running tree or rejects the new request. This would protect you if you did end up calling the Action from your launch file so that you don't need to worry about something else preempting it. If you have time @marj3220 I think this would be a useful addition.

marj3220 commented 4 months ago

Why not just call the Server from your launch file? @MarqRazz you are right. Thank you for that!

Low priority for myself but I did plan on making a configuration option so users could choose if a new goal cancels a current running tree or rejects the new request. This would protect you if you did end up calling the Action from your launch file so that you don't need to worry about something else preempting it. If you have time @marj3220 I think this would be a useful addition.

Good idea! I'll keep this in my mind, if I find the time.

I think I'll cancel this PR.