### Install Package Resources Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Installs Behavior Tree XML files, configuration files, and launch files into the `share/${PROJECT_NAME}/` directory, making them accessible to ROS 2. ```cmake install(DIRECTORY behavior_trees config launch DESTINATION share/${PROJECT_NAME}/ ) ``` -------------------------------- ### Install Executables and Libraries Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Defines installation rules for various executables and the sleep plugin library, placing them in the appropriate ROS 2 package structure (`lib/${PROJECT_NAME}`). ```cmake install(TARGETS sleep_client sleep_client_dyn sleep_server sleep_plugin subscriber_test sample_bt_executor bool_client bool_server DESTINATION lib/${PROJECT_NAME} ) ``` -------------------------------- ### Project Configuration and Dependencies Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Sets up the minimum CMake version, project name, C++ standard, and finds necessary ROS 2 and Behavior Tree packages. Ensure these packages are installed and discoverable by CMake. ```cmake cmake_minimum_required(VERSION 3.16) project(btcpp_ros2_samples) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(ament_cmake REQUIRED) find_package(behaviortree_ros2 REQUIRED) find_package(btcpp_ros2_interfaces REQUIRED) find_package(std_msgs REQUIRED) find_package(std_srvs REQUIRED) ``` -------------------------------- ### Install Behavior Tree Plugins Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Installs the `sleep_plugin` shared library into the `share/${PROJECT_NAME}/bt_plugins` directory, making it available for dynamic loading by other Behavior Tree nodes. ```cmake install(TARGETS sleep_plugin LIBRARY DESTINATION share/${PROJECT_NAME}/bt_plugins ARCHIVE DESTINATION share/${PROJECT_NAME}/bt_plugins RUNTIME DESTINATION share/${PROJECT_NAME}/bt_plugins ) ``` -------------------------------- ### Send Goal to Behavior Server (CrossDoor) Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/README.md Sends a goal to the behavior server to execute the 'CrossDoor' behavior tree. This is an example of calling a ROS Action Server from the command line. ```bash ros2 action send_goal /behavior_server btcpp_ros2_interfaces/action/ExecuteTree "{target_tree: CrossDoor}" ``` -------------------------------- ### Behavior Tree XML Definition with Static Action Name Source: https://context7.com/behaviortree/behaviortree.ros2/llms.txt Defines a behavior tree in XML, showcasing static action names for nodes like `SaySomething` and `SleepAction`. This example includes a `Timeout` decorator to limit the execution time of a `SleepAction`. ```xml ``` -------------------------------- ### Launch TreeExecutionServer Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/README.md Launches the sample Execution Server that loads plugins and BehaviorTrees from a YAML file. Refer to bt_executor_parameters.md for parameter documentation. ```bash ros2 launch btcpp_ros2_samples sample_bt_executor.launch.xml ``` -------------------------------- ### Build SetBool Client and Server Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Configures executables for a SetBool client (`bool_client`) and server (`bool_server`) to test boolean service interactions. The client also includes `set_bool_node.cpp`. ```cmake add_executable(bool_client src/bool_client.cpp src/set_bool_node.cpp) target_link_libraries(bool_client ${THIS_PACKAGE_DEPS}) add_executable(bool_server src/bool_server.cpp ) target_link_libraries(bool_server ${THIS_PACKAGE_DEPS}) ``` -------------------------------- ### Send Goal to Behavior Server (SleepActionSample) Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/README.md Sends a goal to the behavior server to execute the 'SleepActionSample' behavior. This demonstrates calling a Behavior that acts as a ROS Action or Service client. ```bash ros2 action send_goal /behavior_server btcpp_ros2_interfaces/action/ExecuteTree "{target_tree: SleepActionSample}" ``` -------------------------------- ### Build Behavior Tree Executor Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Compiles the `sample_bt_executor` executable, which likely demonstrates the core usage of the Behavior Tree library within a ROS 2 environment. Links against the defined package dependencies. ```cmake add_executable(sample_bt_executor src/sample_bt_executor.cpp) target_link_libraries(sample_bt_executor ${THIS_PACKAGE_DEPS}) ``` -------------------------------- ### Build Dynamic Sleep Action Client Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Creates the `sleep_client_dyn` executable for a dynamic action client that uses the sleep action plugin. It defines `USE_SLEEP_PLUGIN` and links against the sleep plugin library and package dependencies. ```cmake add_executable(sleep_client_dyn src/sleep_client.cpp) target_compile_definitions(sleep_client_dyn PRIVATE USE_SLEEP_PLUGIN ) target_link_libraries(sleep_client_dyn sleep_plugin ) target_link_libraries(sleep_client_dyn ${THIS_PACKAGE_DEPS}) ``` -------------------------------- ### Registering ROS Behavior Tree Plugins Source: https://context7.com/behaviortree/behaviortree.ros2/llms.txt Use macros to create loadable plugins for registering ROS behavior tree nodes at runtime. Supports single node registration or multiple nodes within a single plugin. ```cpp // Method 1: Single node registration with CreateRosNodePlugin #include "behaviortree_ros2/plugins.hpp" // In your .cpp file (NOT header), use this for a single node: CreateRosNodePlugin(SleepAction, "SleepAction"); // Method 2: Multiple nodes with BT_REGISTER_ROS_NODES #include "behaviortree_ros2/plugins.hpp" // Register multiple nodes in one plugin BT_REGISTER_ROS_NODES(factory, params) { factory.registerNodeType("ActionNodeA", params); factory.registerNodeType("ActionNodeB", params); factory.registerNodeType("ServiceNodeC", params); } // CMakeLists.txt: Add compile definition for plugin export # target_compile_definitions(my_plugin_target PRIVATE BT_PLUGIN_EXPORT) ``` -------------------------------- ### Build Static Sleep Action Client Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Creates the `sleep_client` executable for a static action client that interacts with a sleep action. It links against the package dependencies. ```cmake add_executable(sleep_client src/sleep_action.cpp src/sleep_client.cpp) target_link_libraries(sleep_client ${THIS_PACKAGE_DEPS}) ``` -------------------------------- ### ROS2 Action Server for Behavior Tree Execution Source: https://context7.com/behaviortree/behaviortree.ros2/llms.txt Implements a ROS2 Action Server to load and execute behavior trees. It subscribes to external data to update the global blackboard and provides callbacks for tree lifecycle events. ```cpp #include #include #include class MyActionServer : public BT::TreeExecutionServer { public: MyActionServer(const rclcpp::NodeOptions& options) : TreeExecutionServer(options) { // Subscribe to external data and update global blackboard sub_ = node()->create_subscription( "battery_level", 10, [this](const std_msgs::msg::Float32::SharedPtr msg) { globalBlackboard()->set("battery_level", msg->data); }); } // Called after tree is created, before execution starts void onTreeCreated(BT::Tree& tree) override { logger_ = std::make_shared(tree); } // Called after plugins loaded; register additional nodes programmatically void registerNodesIntoFactory(BT::BehaviorTreeFactory& factory) override { // factory.registerNodeType("CustomNode", params); } // Called after each tick; return NodeStatus to stop execution early std::optional onLoopAfterTick(BT::NodeStatus status) override { // Return std::nullopt to continue, or a status to stop return std::nullopt; } // Called when tree completes; return message for action result std::optional onTreeExecutionCompleted(BT::NodeStatus status, bool was_cancelled) override { logger_.reset(); return was_cancelled ? "Cancelled by user" : std::nullopt; } // Called each loop; return string to send as feedback std::optional onLoopFeedback() override { return std::nullopt; } private: std::shared_ptr logger_; rclcpp::Subscription::SharedPtr sub_; }; int main(int argc, char* argv[]) { rclcpp::init(argc, argv); rclcpp::NodeOptions options; auto action_server = std::make_shared(options); rclcpp::executors::MultiThreadedExecutor exec; exec.add_node(action_server->node()); exec.spin(); rclcpp::shutdown(); } ``` -------------------------------- ### TreeExecutionServer ROS Parameters Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/behaviortree_ros2/tree_execution_server.md Documentation for the ROS parameters used by the TreeExecutionServer. ```APIDOC ## ROS Parameters Documentation for the parameters used by the `TreeExecutionServer` can be found [here](bt_executor_parameters.md). If the parameter documentation needs updating you can regenerate it with: ```bash generate_parameter_library_markdown --input_yaml src/bt_executor_parameters.yaml --output_markdown_file bt_executor_parameters.md ``` ``` -------------------------------- ### Build Sleep Action Server Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Compiles the `sleep_server` executable, which acts as the server for the sleep action. It links against the package dependencies. ```cmake add_executable(sleep_server src/sleep_server.cpp) target_link_libraries(sleep_server ${THIS_PACKAGE_DEPS}) ``` -------------------------------- ### Package Configuration Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Finalizes the ROS 2 package configuration, including setting up build system integration and exporting dependencies. ```cmake ament_package() ``` -------------------------------- ### TreeExecutionServer ROS2 Parameter Configuration Source: https://context7.com/behaviortree/behaviortree.ros2/llms.txt Configure the TreeExecutionServer using ROS2 parameters in a YAML file. Specifies action name, tick frequency, plugins, and behavior tree XML file locations. ```yaml # sample_bt_executor.yaml bt_action_server: ros__parameters: # Name of the ROS2 action server (default: "bt_execution") action_name: "behavior_server" # Tick frequency in Hz (default: 100) tick_frequency: 100 # Port for Groot2 visualization (default: 1667) groot2_port: 1667 # Timeout for ROS plugins in ms (default: 1000) ros_plugins_timeout: 1000 # List of plugin packages to load (format: "package_name/subfolder") plugins: - behaviortree_cpp/bt_plugins - my_package/bt_plugins # List of behavior tree XML folders (format: "package_name/subfolder") behavior_trees: - my_package/behavior_trees ``` -------------------------------- ### Build Subscriber Test Node Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Creates the `subscriber_test` executable, likely for testing ROS 2 subscriber functionality within the Behavior Tree context. Links against the package dependencies. ```cmake add_executable(subscriber_test src/subscriber_test.cpp) target_link_libraries(subscriber_test ${THIS_PACKAGE_DEPS}) ``` -------------------------------- ### ROS2 Node Parameters Configuration Source: https://context7.com/behaviortree/behaviortree.ros2/llms.txt Configure ROS2 behavior tree nodes using RosNodeParams. Set the ROS node handle, default port values, and timeouts for server and discovery. ```cpp #include "behaviortree_ros2/ros_node_params.hpp" #include "behaviortree_cpp/bt_factory.h" int main(int argc, char** argv) { rclcpp::init(argc, argv); auto nh = std::make_shared("my_bt_node"); BT::BehaviorTreeFactory factory; // Configure ROS node parameters BT::RosNodeParams params; params.nh = nh; // Required: weak pointer to ROS node params.default_port_value = "my_action_server"; // Default action/service/topic name params.server_timeout = std::chrono::milliseconds(2000); // Request timeout params.wait_for_server_timeout = std::chrono::milliseconds(1000); // Discovery timeout // Shorthand constructors BT::RosNodeParams params_simple(nh); BT::RosNodeParams params_with_default(nh, "default_action_name"); // Register nodes with parameters factory.registerNodeType("MyAction", params); factory.registerNodeType("MyService", params); return 0; } ``` -------------------------------- ### ROS Topic Publisher Wrapper Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/behaviortree_ros2/ros_behavior_wrappers.md Base class for implementing ROS Topic Publisher behaviors. Users derive from this class and implement specific callbacks to publish messages. ```APIDOC ## ROS Topic Publisher Wrapper ### Description Base class for implementing ROS Topic Publisher behaviors. Users derive from this class and implement specific callbacks to publish messages. ### Methods #### `bool setMessage(TopicT& msg)` - **Description**: Required callback invoked in tick to allow the user to pass the message to be published. - **Return**: `bool` - Indicates if the message was successfully prepared for publishing. ``` -------------------------------- ### TreeExecutionServer Customization Points Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/behaviortree_ros2/tree_execution_server.md This section outlines the virtual methods of the TreeExecutionServer class that can be overridden by users to customize its behavior. ```APIDOC ## TreeExecutionServer Customization Points These are the virtual method of `TreeExecutionServer` that can be overridden by the user. ### void onTreeCreated(BT::Tree& tree) Callback invoked when a tree is created; this happens after `rclcpp_action::Server` receive a command from a client. It can be used, for instance, to initialize a logger or the global blackboard. ### void registerNodesIntoFactory(BT::BehaviorTreeFactory& factory) Called at the beginning, after all the plugins have been loaded. It can be used to register programmatically more BT.CPP Nodes. ### std::optional onLoopAfterTick(BT::NodeStatus status) Used to do something after the tree was ticked, in its execution loop. If this method returns something other than `std::nullopt`, the tree execution is interrupted an the specified `BT::NodeStatus` is returned to the `rclcpp_action::Client`. ### void onTreeExecutionCompleted(BT::NodeStatus status, bool was_cancelled) Callback when the tree execution reaches its end. This happens if: 1. Ticking the tree returns SUCCESS/FAILURE 2. The `rclcpp_action::Client` cancels the action. 3. Callback `onLoopAfterTick`cancels the execution. Argument `was_cancelled`is true in the 1st case, false otherwise. ### std::optional onLoopFeedback() This callback is invoked after `tree.tickOnce` and `onLoopAfterTick`. If it returns something other than `std::nullopt`, the provided string will be sent as feedback to the `rclcpp_action::Client`. ``` -------------------------------- ### ROS2 Action Client Wrapper Node Source: https://context7.com/behaviortree/behaviortree.ros2/llms.txt Implement a non-blocking ROS2 action client node by deriving from RosActionNode. Override setGoal() to configure the action goal and onResultReceived() to handle the result. Optional callbacks exist for feedback and error handling. ```cpp #include "behaviortree_ros2/bt_action_node.hpp" #include "btcpp_ros2_interfaces/action/sleep.hpp" using namespace BT; class SleepAction : public RosActionNode { public: SleepAction(const std::string& name, const NodeConfig& conf, const RosNodeParams& params) : RosActionNode(name, conf, params) {} // Define additional ports beyond the basic "action_name" port static BT::PortsList providedPorts() { return providedBasicPorts({ InputPort("msec") }); } // Required: Set the goal message before sending to action server bool setGoal(Goal& goal) override { auto timeout = getInput("msec"); goal.msec_timeout = timeout.value(); return true; // Return false to abort with INVALID_GOAL error } // Required: Handle the result from the action server BT::NodeStatus onResultReceived(const WrappedResult& wr) override { RCLCPP_INFO(logger(), "%s: onResultReceived. Done = %s", name().c_str(), wr.result->done ? "true" : "false"); return wr.result->done ? NodeStatus::SUCCESS : NodeStatus::FAILURE; } // Optional: Handle feedback during action execution BT::NodeStatus onFeedback(const std::shared_ptr feedback) override { // Return RUNNING to continue, or SUCCESS/FAILURE to cancel and complete return NodeStatus::RUNNING; } // Optional: Handle errors (SERVER_UNREACHABLE, SEND_GOAL_TIMEOUT, etc.) BT::NodeStatus onFailure(ActionNodeErrorCode error) override { RCLCPP_ERROR(logger(), "%s: onFailure with error: %s", name().c_str(), toStr(error)); return NodeStatus::FAILURE; } // Optional: Called when the node is halted (cancelGoal() is automatic) void onHalt() override { RCLCPP_INFO(logger(), "%s: onHalt", name().c_str()); } }; // Register as a plugin for runtime loading CreateRosNodePlugin(SleepAction, "SleepAction"); ``` -------------------------------- ### Sending Goals to ExecuteTree Action Server Source: https://context7.com/behaviortree/behaviortree.ros2/llms.txt Interact with the ExecuteTree ROS2 action to trigger behavior tree execution. Goals can specify the target tree by name and optionally include a payload. ```bash # Launch the TreeExecutionServer ros2 launch btcpp_ros2_samples sample_bt_executor.launch.xml # Execute a behavior tree by name ros2 action send_goal /behavior_server btcpp_ros2_interfaces/action/ExecuteTree "{target_tree: CrossDoor}" # Execute with optional payload ros2 action send_goal /behavior_server btcpp_ros2_interfaces/action/ExecuteTree "{target_tree: SleepActionSample, payload: 'custom_data'}" ``` -------------------------------- ### ROS2 Service Client Wrapper Node Source: https://context7.com/behaviortree/behaviortree.ros2/llms.txt Implement a non-blocking ROS2 service client node by deriving from RosServiceNode. Override setRequest() to populate the service request and onResponseReceived() to process the response. Optional error handling is available. ```cpp #include #include "std_srvs/srv/set_bool.hpp" using SetBool = std_srvs::srv::SetBool; class SetBoolService : public BT::RosServiceNode { public: explicit SetBoolService(const std::string& name, const BT::NodeConfig& conf, const BT::RosNodeParams& params) : RosServiceNode(name, conf, params) {} // Define ports: basic "service_name" port + custom "value" port static BT::PortsList providedPorts() { return providedBasicPorts({ BT::InputPort("value") }); } // Required: Populate the service request bool setRequest(Request::SharedPtr& request) override { getInput("value", request->data); return true; // Return false to abort with INVALID_REQUEST error } // Required: Handle the service response BT::NodeStatus onResponseReceived(const Response::SharedPtr& response) override { if(response->success) { RCLCPP_INFO(logger(), "SetBool service succeeded."); return BT::NodeStatus::SUCCESS; } else { RCLCPP_INFO(logger(), "SetBool service failed: %s", response->message.c_str()); return BT::NodeStatus::FAILURE; } } // Optional: Handle errors (SERVICE_UNREACHABLE, SERVICE_TIMEOUT, etc.) BT::NodeStatus onFailure(BT::ServiceNodeErrorCode error) override { RCLCPP_ERROR(logger(), "Error: %d", error); return BT::NodeStatus::FAILURE; } }; ``` -------------------------------- ### ROS2 Topic Publisher Node Source: https://context7.com/behaviortree/behaviortree.ros2/llms.txt Implement a ROS2 topic publisher node by inheriting from RosTopicPubNode. Override setMessage to populate the message before publishing. The input port 'message' is required. ```cpp #include "behaviortree_ros2/bt_topic_pub_node.hpp" #include using namespace BT; class PublishString : public RosTopicPubNode { public: PublishString(const std::string& name, const NodeConfig& conf, const RosNodeParams& params) : RosTopicPubNode(name, conf, params) {} static BT::PortsList providedPorts() { return providedBasicPorts({ InputPort("message") }); } // Required: Populate the message to publish bool setMessage(std_msgs::msg::String& msg) override { auto text = getInput("message"); if(!text) { return false; // Return false to abort (returns FAILURE) } msg.data = text.value(); return true; // Message will be published, returns SUCCESS } }; // Register for runtime loading CreateRosNodePlugin(PublishString, "PublishString"); ``` -------------------------------- ### Build Sleep Action Plugin Library Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Compiles the `sleep_plugin` as a shared library, intended for dynamic loading. It exports Behavior Tree plugin symbols and links against package dependencies. ```cmake add_library(sleep_plugin SHARED src/sleep_action.cpp) target_compile_definitions(sleep_plugin PRIVATE BT_PLUGIN_EXPORT ) target_link_libraries(sleep_plugin ${THIS_PACKAGE_DEPS}) ``` -------------------------------- ### ROS Action Behavior Wrapper Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/behaviortree_ros2/ros_behavior_wrappers.md Base class for implementing ROS Action behaviors. Users derive from this class and implement specific callbacks to interact with ROS Actions. ```APIDOC ## ROS Action Behavior Wrapper ### Description Base class for implementing ROS Action behaviors. Users derive from this class and implement specific callbacks to interact with ROS Actions. ### Methods #### `bool setGoal(Goal& goal)` - **Description**: Required callback that allows the user to set the goal message. Return false if the request should not be sent. In that case, RosActionNode::onFailure(INVALID_GOAL) will be called. - **Return**: `bool` - `true` if the goal should be sent, `false` otherwise. #### `BT::NodeStatus onResultReceived(const WrappedResult& result)` - **Description**: Required callback invoked when the result is received by the server. It is up to the user to define if the action returns SUCCESS or FAILURE. - **Return**: `BT::NodeStatus` - The status of the node (SUCCESS or FAILURE). #### `BT::NodeStatus onFeedback(const std::shared_ptr feedback)` - **Description**: Optional callback invoked when the feedback is received. It generally returns RUNNING, but the user can also use this callback to cancel the current action and return SUCCESS or FAILURE. - **Return**: `BT::NodeStatus` - The status of the node (RUNNING, SUCCESS, or FAILURE). #### `BT::NodeStatus onFailure(ActionNodeErrorCode error)` - **Description**: Optional callback invoked when something goes wrong. It must return either SUCCESS or FAILURE. - **Return**: `BT::NodeStatus` - The status of the node (SUCCESS or FAILURE). #### `void onHalt()` - **Description**: Optional callback executed when the node is halted. Note that cancelGoal() is done automatically. ``` -------------------------------- ### ROS Service Behavior Wrapper Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/behaviortree_ros2/ros_behavior_wrappers.md Base class for implementing ROS Service behaviors. Users derive from this class and implement specific callbacks to interact with ROS Services. ```APIDOC ## ROS Service Behavior Wrapper ### Description Base class for implementing ROS Service behaviors. Users derive from this class and implement specific callbacks to interact with ROS Services. ### Methods #### `setRequest(typename Request::SharedPtr& request)` - **Description**: Required callback that allows the user to set the request message (ServiceT::Request). #### `BT::NodeStatus onResponseReceived(const typename Response::SharedPtr& response)` - **Description**: Required callback invoked when the response is received by the server. It is up to the user to define if this returns SUCCESS or FAILURE. - **Return**: `BT::NodeStatus` - The status of the node (SUCCESS or FAILURE). #### `BT::NodeStatus onFailure(ServiceNodeErrorCode error)` - **Description**: Optional callback invoked when something goes wrong; you can override it. It must return either SUCCESS or FAILURE. - **Return**: `BT::NodeStatus` - The status of the node (SUCCESS or FAILURE). ``` -------------------------------- ### ROS Topic Subscriber Wrapper Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/behaviortree_ros2/ros_behavior_wrappers.md Base class for implementing ROS Topic Subscriber behaviors. Users derive from this class and implement specific callbacks to process incoming messages. ```APIDOC ## ROS Topic Subscriber Wrapper ### Description Base class for implementing ROS Topic Subscriber behaviors. Users derive from this class and implement specific callbacks to process incoming messages. ### Methods #### `NodeStatus onTick(const std::shared_ptr& last_msg)` - **Description**: Required callback invoked in the tick. You must return either SUCCESS or FAILURE. - **Return**: `NodeStatus` - The status of the node (SUCCESS or FAILURE). #### `bool latchLastMessage()` - **Description**: Optional callback to latch the message that has been processed. If returns false and no new message is received, before next call there will be no message to process. If returns true, the next call will process the same message again, if no new message received. - **Return**: `bool` - `true` to latch the last message, `false` otherwise. ``` -------------------------------- ### Define Package Dependencies Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Lists the target dependencies for the package, including the Behavior Tree ROS 2 library, message types, service types, and custom interfaces. These are used when linking executables and libraries. ```cmake set(THIS_PACKAGE_DEPS behaviortree_ros2::behaviortree_ros2 ${std_msgs_TARGETS} ${std_srvs_TARGETS} ${btcpp_ros2_interfaces_TARGETS} ) ``` -------------------------------- ### Generate ROS 2 Behavior Tree Interfaces with CMake Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_interfaces/CMakeLists.txt This CMakeLists.txt snippet configures a ROS 2 package to generate custom interfaces for behavior trees. It finds necessary packages, sets C++ standards, and uses `rosidl_generate_interfaces` to create message, service, and action definitions. ```cmake cmake_minimum_required(VERSION 3.16) project(btcpp_ros2_interfaces) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(ament_cmake REQUIRED) find_package(rosidl_default_generators REQUIRED) rosidl_generate_interfaces(btcpp_ros2_interfaces "msg/NodeStatus.msg" "srv/GetTrees.srv" "action/ExecuteTree.action" "action/Sleep.action") ament_export_dependencies(rosidl_default_runtime) ament_package() ``` -------------------------------- ### ROS2 Topic Subscriber Node Source: https://context7.com/behaviortree/behaviortree.ros2/llms.txt Implement a ROS2 topic subscriber node by inheriting from RosTopicSubNode. Override onTick to process incoming messages. Set latchLastMessage to true to retain the last message. ```cpp #include "behaviortree_ros2/bt_topic_sub_node.hpp" #include using namespace BT; class ReceiveString : public RosTopicSubNode { public: ReceiveString(const std::string& name, const NodeConfig& conf, const RosNodeParams& params) : RosTopicSubNode(name, conf, params) {} static BT::PortsList providedPorts() { return providedBasicPorts({}); // Basic "topic_name" port included } // Required: Process the latest message (nullptr if no new message since last tick) NodeStatus onTick(const std::shared_ptr& last_msg) override { if(last_msg) { RCLCPP_INFO(logger(), "[%s] new message: %s", name().c_str(), last_msg->data.c_str()); } return NodeStatus::SUCCESS; } // Optional: Return true to keep the last message for next tick (like ROS1 latched topics) bool latchLastMessage() const override { return false; } }; // Usage in main() int main(int argc, char** argv) { rclcpp::init(argc, argv); auto nh = std::make_shared("subscriber_test"); BehaviorTreeFactory factory; RosNodeParams params; params.nh = nh; params.default_port_value = "my_topic"; // Default topic name factory.registerNodeType("ReceiveString", params); auto tree = factory.createTreeFromText(R"( )"); while(rclcpp::ok()) { tree.tickWhileRunning(); } return 0; } ``` -------------------------------- ### Export Package Dependencies Source: https://github.com/behaviortree/behaviortree.ros2/blob/humble/btcpp_ros2_samples/CMakeLists.txt Declares that this package exports dependencies on `behaviortree_ros2` and `btcpp_ros2_interfaces`, allowing other ROS 2 packages to depend on them. ```cmake ament_export_dependencies(behaviortree_ros2 btcpp_ros2_interfaces) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.