BehaviorTree.CPP
BehaviorTree.CPP copied to clipboard
ROS2 example project
Hi everyone I would like to know if there is a simple package example for ROS2 in order to start learning the BehaviorTree library. I don't have a clear idea about how should I organized the project and what is required. Thanks in advanace
BehaviorTree/BehaviorTree.ROS might be a good place to start. It's written in ROS1, but the organization and basic concepts should extend to ROS2 too. It has a ROS node in the test directory that creates a BT from a string, spins a ROS node, and ticks the BT until it completes successfully (or fails). Nearly all ROS nodes that execute some action using a behavior tree are going to follow a very similar pattern: create the tree then create a loop that alternates between spinning the ROS node and ticking the BT, stop ticking the BT when it completes (BT::NodeStatus::SUCCESS
or FAILURE
) or the ROS node is shutting down.
The navigation2/nav2_behavior_tree package is a more advanced example, written in ROS2 for the Nav2 project. It provides the nav2_behavior_tree::BehaviorTreeEngine
class for easily creating and managing behavior trees. The abstraction here makes it easier to write BT-enabled ROS nodes. If you're interested in writing your own ROS2 node that uses behavior trees to perform some action, and some of the suggestions below don't fit your bill, I would recommend using this type or creating a type that's modeled after it.
The nav2_behavior_tree package also provides the nav2_behavior_tree::BtActionServer
type for creating a ROS2 action server that uses the nav2_behavior_tree::BehaviorTreeEngine
type. It's meant to be used within a lifecycle node. An example node that uses this type is nav2_bt_navigator::BtNavigator
in navigation2/nav2_bt_navigator. Note: there are a couple layers of abstraction here. nav2_bt_navigator::BtNavigator
uses a nav2_bt_navigator::Navigator
which is what creates the nav2_behavior_tree::BtActionServer
. In your own node, you could directly create a nav2_behavior_tree::BtActionServer
and skip the middle layer.
If you don't want to use lifecycle nodes, you could create your own BtActionServer
that functions in a similar manner by using nav2_behavior_tree::BehaviorTreeEngine
internally. It would be a very similar implementation but would execute the equivalent functions for the configure
and activate
transitions immediately on startup, and the deactivate
, cleanup
, and shutdown
transitions only during shutdown.
As for creating and structuring your behavior trees, I've noted a few common methods, in order of simplicity:
- Write your behavior tree in code using a string of XML.
- Write your behavior tree in an XML file, install that file as part of your build, and load that file during execution.
- Write several behaviors as XML files and select which file to load during launch or startup based on a launch argument or ROS parameter.
- Provide your behavior tree as a path to an XML file in a string field of a service request or action goal and load that file during execution. This method can fail or fall back to a simpler method if the file doesn't exist.
@asasine, thank you very much for you comprehensive and detailed response. I'll try to check all your advices. Thanks again!!!
Just to reiterate @laurafbec's comment, this response is such a useful resource! I can't believe my luck that this was asked and answered yesterday, as it's exactly what I needed today. Thanks @asasine!
Hey guys, we developed a sandbox example to test a simple publisher and subscriber in ROS2 over at Polymath Robotics. It explores the concepts you brought up :)
@facontidavide I think you can close this ticket