Skip to content

add ros2 integration tutorials from the official BT website #102

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

Open
wants to merge 1 commit into
base: humble
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added bt_tutorials_ros2/.README.md.swp
Binary file not shown.
75 changes: 75 additions & 0 deletions bt_tutorials_ros2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
cmake_minimum_required(VERSION 3.8)
project(bt_tutorials_ros2)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
add_compile_options(-Wall -Wextra -Wpedantic)
endif()

# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(rclcpp_action REQUIRED)
find_package(action_tutorials_interfaces REQUIRED)
find_package(example_interfaces REQUIRED)
find_package(behaviortree_cpp REQUIRED)
find_package(behaviortree_ros2 REQUIRED)

# include directories
include_directories(
include
)

# add libraries
add_library(${PROJECT_NAME}_action_client src/${PROJECT_NAME}/${PROJECT_NAME}_action_client.cpp)
add_library(${PROJECT_NAME}_service_client src/${PROJECT_NAME}/${PROJECT_NAME}_service_client.cpp)

# link libraries against ros dependencies
ament_target_dependencies(${PROJECT_NAME}_action_client rclcpp behaviortree_cpp behaviortree_ros2 rclcpp_action action_tutorials_interfaces)
ament_target_dependencies(${PROJECT_NAME}_service_client rclcpp behaviortree_cpp behaviortree_ros2 example_interfaces)

# add executables
add_executable(${PROJECT_NAME}_action_client_node src/${PROJECT_NAME}_action_client_node.cpp)
add_executable(${PROJECT_NAME}_service_client_node src/${PROJECT_NAME}_service_client_node.cpp)

# link executables against libraries
target_link_libraries(${PROJECT_NAME}_action_client_node ${PROJECT_NAME}_action_client)
target_link_libraries(${PROJECT_NAME}_service_client_node ${PROJECT_NAME}_service_client)

# link executables against ros dependencies
ament_target_dependencies(${PROJECT_NAME}_action_client_node rclcpp behaviortree_cpp)
ament_target_dependencies(${PROJECT_NAME}_service_client_node rclcpp behaviortree_cpp)

# install include directories
install(
DIRECTORY include
DESTINATION include
)

# install libraries
install(
TARGETS ${PROJECT_NAME}_action_client ${PROJECT_NAME}_service_client
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
)

# install executables
install(
TARGETS ${PROJECT_NAME}_action_client_node ${PROJECT_NAME}_service_client_node
DESTINATION lib/${PROJECT_NAME}
)

if(BUILD_TESTING)
find_package(ament_lint_auto REQUIRED)
# the following line skips the linter which checks for copyrights
# comment the line when a copyright and license is added to all source files
set(ament_cmake_copyright_FOUND TRUE)
# the following line skips cpplint (only works in a git repo)
# comment the line when this package is in a git repo and when
# a copyright and license is added to all source files
set(ament_cmake_cpplint_FOUND TRUE)
ament_lint_auto_find_test_dependencies()
endif()

ament_package()
50 changes: 50 additions & 0 deletions bt_tutorials_ros2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# bt_tutorials_ros2

## Overview

This package provides fully documented, runnable examples of the ROS 2 integration tutorials from the official [BehaviorTree.CPP documentation](https://www.behaviortree.dev/), allowing users to test, modify, and extend these examples in their own projects. Specifically, the following two nodes are created:

- **Fibonacci Action Client**: A BehaviorTree client node interacting with the `\fibonacci` action server from the official ROS2 examples.
- **AddTwoInts Service Client**: A BehaviorTree client node interacting with the `\add_two_ints` service server from the official ROS2 examples.

## Requirements

- **C++17**: Required for building the package.
- **ROS 2**: Tested on ROS 2 Humble.
- **BehaviorTree.CPP**: Version 4.0 or higher.
- **BehaviorTree.ROS**, i.e. this repo.

## Compiling
Compile using `colcon`, for instance as:
```
colcon build --packages-select bt_tutorials_ros2
```
## Running

### Fibonacci Action Client

Ensure the `/fibonacci` action server is running. This server is typically included with the ROS 2 installation and can be started using the following command:

```bash
ros2 run action_tutorials_cpp fibonacci_action_server
```
If the server is not available, you can follow the official ROS 2 tutorial [here](https://docs.ros.org/en/humble/Tutorials/Intermediate/Writing-an-Action-Server-Client/Cpp.html#writing-an-action-server) to compile and run it.

Once the action server is up, you can run the **Fibonacci BehaviorTree action client** node with:
```
ros2 run bt_tutorials_ros2 bt_tutorials_ros2_action_client_node
```

### AddTwoInts Service Client
Ensure the `/add_two_ints` service server is running. You can implement, compile, and run the server following the official ROS 2 tutorial [here](https://docs.ros.org/en/humble/Tutorials/Beginner-Client-Libraries/Writing-A-Simple-Cpp-Service-And-Client.html). For example, you can run the server with:
```
ros2 run cpp_srvcli server
```

Once the service server is up, you can run the **AddTwoInts BehaviorTree service client** node with:
```
ros2 run bt_tutorials_ros2 bt_tutorials_ros2_service_client_node
```

### Author
Janak Panthi (Crasun Jans)
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
/**
* @file bt_tutorials_ros2_action_client.hpp
* @brief Header file for the FibonacciActionNode, a custom BehaviorTree node for interacting with the official ROS 2
* "/fibonacci" action server.
*
* @author Janak Panthi (Crasun Jans)
*
* @details Implements the Fibonacci action client tutorial from the "Integration with ROS2" section on the
* official BehaviorTree.CPP website. This node sends goals to a Fibonacci action server, processes its feedback,
* and handles the result.
*
* @license MIT
*/

#ifndef BT_TUTORIALS_ROS2_ACTION_CLIENT_HPP
#define BT_TUTORIALS_ROS2_ACTION_CLIENT_HPP

#include <action_tutorials_interfaces/action/fibonacci.hpp> // Action definition for Fibonacci action.
#include <behaviortree_cpp/action_node.h> // Base class for action nodes in BehaviorTreeCpp.
#include <behaviortree_ros2/bt_action_node.hpp> // BT wrapper for ROS2 actions.
#include <string> // For handling string types.

namespace bt_tutorials_ros2_action_client
{
// Alias for the Fibonacci action type.
using Fibonacci = action_tutorials_interfaces::action::Fibonacci;

/**
* @brief Class representing a custom action node for the Fibonacci action in a BehaviorTree.
*
* This class derives from the `RosActionNode` provided by the `behaviortree_ros2` library.
* It implements all necessary callbacks and methods to interact with an action server
* to perform the Fibonacci action.
*/
class FibonacciActionNode : public BT::RosActionNode<Fibonacci>
{
public:
// Type alias for the GoalHandle specific to the Fibonacci action.
using GoalHandleFibonacci = rclcpp_action::ServerGoalHandle<Fibonacci>;

/**
* @brief Constructor for the FibonacciActionNode.
*
* Initializes the action node with the given name, configuration, and ROS node parameters.
* This allows the action node to interact with the ROS 2 system and communicate with the action server.
*
* @param name The name of the node in the behavior tree.
* @param conf The configuration parameters for the behavior tree node.
* @param params ROS node parameters used to configure the action node.
*/
FibonacciActionNode(const std::string &name, const BT::NodeConfig &conf, const BT::RosNodeParams &params);

/**
* @brief Provides the ports required by this action node.
*
* This static function defines the input and output ports for the node, merging the
* base class ports with any additional ones specific to this derived class.
*
* @return A list of ports this action node provides.
*/
static BT::PortsList providedPorts();

/**
* @brief Sends a request to the action server when the tree node is ticked.
*
* This function is called when the behavior tree ticks the node. It sends the goal to the
* action server.
*
* @param goal The goal to be sent to the action server.
* @return True if the goal was successfully set, otherwise false.
*/
bool setGoal(RosActionNode::Goal &goal) override;

/**
* @brief Callback executed when a result is received from the action server.
*
* This function is invoked when the action server sends a result. Based on the result,
* it will return either `SUCCESS` or `FAILURE` to indicate the outcome of the action.
*
* @param wr The wrapped result received from the action server.
* @return The status of the node after processing the result.
*/
BT::NodeStatus onResultReceived(const WrappedResult &wr) override;

/**
* @brief Callback invoked when the action client encounters a communication failure.
*
* This callback handles failure cases where the communication between the action client
* and the server fails. The node status is updated to either `SUCCESS` or `FAILURE` based on
* the error received.
*
* @param error The error code indicating the failure reason.
* @return The status of the node after handling the failure.
*/
BT::NodeStatus onFailure(BT::ActionNodeErrorCode error) override;

/**
* @brief Callback for receiving feedback from the action server.
*
* This function is invoked when feedback is received from the action server. The feedback
* can be used to determine the current progress of the action. If necessary, the action can
* be aborted based on feedback, or the node can return `SUCCESS` or `FAILURE` if the action completes.
*
* @param feedback The feedback received from the action server.
* @return The status of the node after processing the feedback.
*/
BT::NodeStatus onFeedback(const std::shared_ptr<const Feedback> feedback);

private:
std::shared_ptr<rclcpp::Node> shared_node_; // shared pointer to the ROS node
};

} // namespace bt_tutorials_ros2_action_client

#endif // BT_TUTORIALS_ROS2_ACTION_CLIENT_HPP
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* @file bt_tutorials_ros2_service_client.hpp
* @brief Header file for the AddTwoIntsNode, a custom BehaviorTree node for interacting with the official ROS 2
* "/add_two_ints" service.
*
* @author Janak Panthi (Crasun Jans)
*
* @details Implements the AddTwoInts service client tutorial from the "Integration with ROS2" section on the
* official BehaviorTree.CPP website. This node interacts with a ROS 2 service server to send two integers as a
* request and processes the resulting sum.
*
* @license MIT
*/

#ifndef BT_TUTORIALS_ROS2_SERVICE_CLIENT_HPP
#define BT_TUTORIALS_ROS2_SERVICE_CLIENT_HPP

#include <behaviortree_cpp/action_node.h> // Base class for action nodes in BehaviorTreeCpp.
#include <behaviortree_ros2/bt_service_node.hpp> // BT wrapper for ROS2 service nodes.
#include <example_interfaces/srv/add_two_ints.hpp> // Service definition for AddTwoInts service.
#include <string> // For handling string types.

namespace bt_tutorials_ros2_service_client
{
// Alias for the AddTwoInts service type.
using AddTwoInts = example_interfaces::srv::AddTwoInts;

/**
* @brief Class representing a custom service node for the AddTwoInts service in a BehaviorTree.
*
* This class derives from the `RosServiceNode` provided by the `behaviortree_ros2` library.
* It implements all necessary callbacks and methods to interact with a service server
* to perform the AddTwoInts service call.
*/
class AddTwoIntsNode : public BT::RosServiceNode<AddTwoInts>
{
public:
/**
* @brief Constructor for the AddTwoIntsNode.
*
* Initializes the service node with the given name, configuration, and ROS node parameters.
* This allows the service node to communicate with the ROS 2 system and the service server.
*
* @param name The name of the node in the behavior tree.
* @param conf The configuration parameters for the behavior tree node.
* @param params ROS node parameters used to configure the service node.
*/
AddTwoIntsNode(const std::string &name, const BT::NodeConfig &conf, const BT::RosNodeParams &params);

/**
* @brief Provides the ports required by this service node.
*
* This static function defines the input and output ports for the node, merging the
* base class ports with any additional ones specific to this derived class.
*
* @return A list of ports this service node provides.
*/
static BT::PortsList providedPorts();

/**
* @brief Sends a request to the service server when the tree node is ticked.
*
* This function is called when the behavior tree ticks the node. It sends the request to the
* service server.
*
* @param request The request to be sent to the service server.
* @return True if the request was successfully set, otherwise false.
*/
bool setRequest(Request::SharedPtr &request) override;

/**
* @brief Callback executed when a response is received from the service server.
*
* This function is invoked when the service server sends a response. Based on the response,
* it will return either `SUCCESS` or `FAILURE` to indicate the outcome of the service call.
*
* @param response The response received from the service server.
* @return The status of the node after processing the response.
*/
BT::NodeStatus onResponseReceived(const Response::SharedPtr &response) override;

/**
* @brief Callback invoked when the service client encounters a communication failure.
*
* This callback handles failure cases where the communication between the service client
* and the server fails. The node status is updated to either `SUCCESS` or `FAILURE` based on
* the error received.
*
* @param error The error code indicating the failure reason.
* @return The status of the node after handling the failure.
*/
BT::NodeStatus onFailure(BT::ServiceNodeErrorCode error) override;

private:
std::shared_ptr<rclcpp::Node> shared_node_; // Shared pointer to the ROS node for logging and other tasks.
};

} // namespace bt_tutorials_ros2_service_client

#endif // BT_TUTORIALS_ROS2_SERVICE_CLIENT_HPP
26 changes: 26 additions & 0 deletions bt_tutorials_ros2/package.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3">
<name>bt_tutorials_ros2</name>
<version>0.0.0</version>
<description>Implementation of the Integration with ROS2 Tutorials from the behaviortree.dev Website</description>
<maintainer email="[email protected]">Janak Panthi</maintainer>
<license>MIT</license>
<author>Janak Panthi</author>

<buildtool_depend>ament_cmake</buildtool_depend>

<depend>rclcpp</depend>
<depend>rclcpp_action</depend>
<depend>action_tutorials_interfaces</depend>
<depend>example_interfaces</depend>
<depend>behaviortree_cpp</depend>
<depend>behaviortree_ros2</depend>

<test_depend>ament_lint_auto</test_depend>
<test_depend>ament_lint_common</test_depend>

<export>
<build_type>ament_cmake</build_type>
</export>
</package>
Loading