1- #include < rclcpp/rclcpp.hpp>
2- #include < rclcpp_action/rclcpp_action.hpp>
3- #include < btcpp_ros2_interfaces/action/execute_tree.hpp>
1+ #include " behaviortree_ros2/tools/client/tree_execution_client.hpp"
42
5- class TreeExecutionClient : public rclcpp ::Node
3+ TreeExecutionClient::TreeExecutionClient (const std::string &target_tree, const rclcpp::NodeOptions &options)
4+ : Node(" tree_execution_client" , options)
65{
7- public:
8- using ExecuteTree = btcpp_ros2_interfaces::action::ExecuteTree;
9- using GoalHandleExecuteTree = rclcpp_action::ClientGoalHandle<ExecuteTree>;
6+ action_client_ = rclcpp_action::create_client<ExecuteTree>(this , " /bt_action_server_example" );
107
11- explicit TreeExecutionClient (const std::string& target_tree, const rclcpp::NodeOptions &options = rclcpp::NodeOptions())
12- : Node(" tree_execution_client" , options)
8+ if (!action_client_->wait_for_action_server (std::chrono::seconds (10 )))
139 {
14- action_client_ = rclcpp_action::create_client<ExecuteTree>(this , " /bt_action_server_example" );
15-
16- if (!action_client_->wait_for_action_server (std::chrono::seconds (10 )))
17- {
18- RCLCPP_ERROR (this ->get_logger (), " Action server not available after waiting" );
19- rclcpp::shutdown ();
20- return ;
21- }
22-
23- if (target_tree.empty ())
24- {
25- RCLCPP_ERROR (this ->get_logger (), " Target tree name must be specified" );
26- rclcpp::shutdown ();
27- return ;
28- }
10+ RCLCPP_ERROR (this ->get_logger (), " Action server not available after waiting" );
11+ rclcpp::shutdown ();
12+ return ;
13+ }
2914
30- send_goal (target_tree);
15+ if (target_tree.empty ())
16+ {
17+ RCLCPP_ERROR (this ->get_logger (), " Target tree name must be specified" );
18+ rclcpp::shutdown ();
19+ return ;
3120 }
3221
33- private:
34- rclcpp_action::Client<ExecuteTree>::SharedPtr action_client_;
22+ send_goal (target_tree);
23+ }
3524
36- void send_goal (const std::string &target_tree)
37- {
38- auto goal_msg = ExecuteTree::Goal ();
39- goal_msg.target_tree = target_tree;
40- goal_msg.payload = " " ; // Optional payload can be set here
25+ void TreeExecutionClient:: send_goal (const std::string &target_tree)
26+ {
27+ auto goal_msg = ExecuteTree::Goal ();
28+ goal_msg.target_tree = target_tree;
29+ goal_msg.payload = " " ; // Optional payload
4130
42- RCLCPP_INFO (this ->get_logger (), " Sending goal to execute tree: %s" , target_tree.c_str ());
31+ RCLCPP_INFO (this ->get_logger (), " Sending goal to execute tree: %s" , target_tree.c_str ());
4332
44- auto send_goal_options = rclcpp_action::Client<ExecuteTree>::SendGoalOptions ();
45-
46- send_goal_options.goal_response_callback =
47- [this ](GoalHandleExecuteTree::SharedPtr goal_handle) {
48- if (!goal_handle)
49- {
50- RCLCPP_ERROR (this ->get_logger (), " Goal was rejected by the server" );
51- }
52- else
53- {
54- RCLCPP_INFO (this ->get_logger (), " Goal accepted by the server, waiting for result" );
55- }
56- };
33+ auto send_goal_options = rclcpp_action::Client<ExecuteTree>::SendGoalOptions ();
5734
58- send_goal_options.feedback_callback =
59- [this ](GoalHandleExecuteTree::SharedPtr, const std::shared_ptr<const ExecuteTree::Feedback> feedback) {
60- RCLCPP_INFO (this ->get_logger (), " Feedback received: %s" , feedback->message .c_str ());
61- };
35+ send_goal_options.goal_response_callback =
36+ [this ](GoalHandleExecuteTree::SharedPtr goal_handle)
37+ {
38+ if (!goal_handle)
39+ {
40+ RCLCPP_ERROR (this ->get_logger (), " Goal was rejected by the server" );
41+ }
42+ else
43+ {
44+ RCLCPP_INFO (this ->get_logger (), " Goal accepted by the server, waiting for result" );
45+ }
46+ };
6247
63- send_goal_options.result_callback =
64- [this ](const GoalHandleExecuteTree::WrappedResult &result) {
65- switch (result.code )
66- {
67- case rclcpp_action::ResultCode::SUCCEEDED:
68- RCLCPP_INFO (this ->get_logger (), " Result received: Status=%d, Message=%s" ,
69- result.result ->node_status , result.result ->return_message .c_str ());
70- break ;
71- case rclcpp_action::ResultCode::ABORTED:
72- RCLCPP_ERROR (this ->get_logger (), " Goal was aborted" );
73- break ;
74- case rclcpp_action::ResultCode::CANCELED:
75- RCLCPP_WARN (this ->get_logger (), " Goal was canceled" );
76- break ;
77- default :
78- RCLCPP_ERROR (this ->get_logger (), " Unknown result code" );
79- break ;
80- }
81- rclcpp::shutdown ();
82- };
83-
84- action_client_->async_send_goal (goal_msg, send_goal_options);
85- }
86- };
48+ send_goal_options.feedback_callback =
49+ [this ](GoalHandleExecuteTree::SharedPtr,
50+ const std::shared_ptr<const ExecuteTree::Feedback> feedback)
51+ {
52+ RCLCPP_INFO (this ->get_logger (), " Feedback received: %s" , feedback->message .c_str ());
53+ };
8754
88- int main (int argc, char **argv)
89- {
90- rclcpp::init (argc, argv);
91-
92- if (argc < 2 ) {
93- RCLCPP_ERROR (rclcpp::get_logger (" tree_execution_client" ), " Usage: ros2 run package_name node_name <target_tree_name>" );
94- return 1 ;
95- }
96-
97- std::string target_tree = argv[1 ];
98- auto node = std::make_shared<TreeExecutionClient>(target_tree);
99- rclcpp::spin (node);
100- rclcpp::shutdown ();
101- return 0 ;
102- }
55+ send_goal_options.result_callback =
56+ [this ](const GoalHandleExecuteTree::WrappedResult &result)
57+ {
58+ switch (result.code )
59+ {
60+ case rclcpp_action::ResultCode::SUCCEEDED:
61+ RCLCPP_INFO (this ->get_logger (), " Result received: Status=%d, Message=%s" ,
62+ result.result ->node_status , result.result ->return_message .c_str ());
63+ break ;
64+ case rclcpp_action::ResultCode::ABORTED:
65+ RCLCPP_ERROR (this ->get_logger (), " Goal was aborted" );
66+ break ;
67+ case rclcpp_action::ResultCode::CANCELED:
68+ RCLCPP_WARN (this ->get_logger (), " Goal was canceled" );
69+ break ;
70+ default :
71+ RCLCPP_ERROR (this ->get_logger (), " Unknown result code" );
72+ break ;
73+ }
74+ rclcpp::shutdown ();
75+ };
76+
77+ action_client_->async_send_goal (goal_msg, send_goal_options);
78+ }
0 commit comments