forked from BehaviorTree/BehaviorTree.ROS2
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsleep_server.cpp
More file actions
100 lines (83 loc) · 3.06 KB
/
sleep_server.cpp
File metadata and controls
100 lines (83 loc) · 3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <functional>
#include <memory>
#include <thread>
#include "rclcpp/rclcpp.hpp"
#include "rclcpp_action/rclcpp_action.hpp"
#include "btcpp_ros2_interfaces/action/sleep.hpp"
#include "behaviortree_ros2/bt_action_node.hpp"
class SleepActionServer : public rclcpp::Node
{
public:
using Sleep = btcpp_ros2_interfaces::action::Sleep;
using GoalHandleSleep = rclcpp_action::ServerGoalHandle<Sleep>;
explicit SleepActionServer(const rclcpp::NodeOptions& options = rclcpp::NodeOptions())
: Node("sleep_action_server", options)
{
using namespace std::placeholders;
this->action_server_ = rclcpp_action::create_server<Sleep>(
this, "sleep_service", std::bind(&SleepActionServer::handle_goal, this, _1, _2),
std::bind(&SleepActionServer::handle_cancel, this, _1),
std::bind(&SleepActionServer::handle_accepted, this, _1));
}
private:
rclcpp_action::Server<Sleep>::SharedPtr action_server_;
rclcpp_action::GoalResponse handle_goal(const rclcpp_action::GoalUUID&,
std::shared_ptr<const Sleep::Goal> goal)
{
RCLCPP_INFO(this->get_logger(), "Received goal request with sleep time %d",
goal->msec_timeout);
return rclcpp_action::GoalResponse::ACCEPT_AND_EXECUTE;
}
rclcpp_action::CancelResponse
handle_cancel(const std::shared_ptr<GoalHandleSleep> goal_handle)
{
RCLCPP_INFO(this->get_logger(), "Received request to cancel goal");
(void)goal_handle;
return rclcpp_action::CancelResponse::ACCEPT;
}
void handle_accepted(const std::shared_ptr<GoalHandleSleep> goal_handle)
{
using namespace std::placeholders;
// this needs to return quickly to avoid blocking the executor, so spin up a new thread
std::thread{ std::bind(&SleepActionServer::execute, this, _1), goal_handle }.detach();
}
void execute(const std::shared_ptr<GoalHandleSleep> goal_handle)
{
RCLCPP_INFO(this->get_logger(), "Executing goal");
rclcpp::Rate loop_rate(5);
const auto goal = goal_handle->get_goal();
auto feedback = std::make_shared<Sleep::Feedback>();
auto result = std::make_shared<Sleep::Result>();
rclcpp::Time deadline = get_clock()->now() + rclcpp::Duration::from_seconds(
double(goal->msec_timeout) / 1000);
int cycle = 0;
while(get_clock()->now() < deadline)
{
if(goal_handle->is_canceling())
{
result->done = false;
goal_handle->canceled(result);
RCLCPP_INFO(this->get_logger(), "Goal canceled");
return;
}
feedback->cycle = cycle++;
goal_handle->publish_feedback(feedback);
RCLCPP_INFO(this->get_logger(), "Publish feedback");
loop_rate.sleep();
}
// Check if goal is done
if(rclcpp::ok())
{
result->done = true;
goal_handle->succeed(result);
RCLCPP_INFO(this->get_logger(), "Goal succeeded");
}
}
}; // class SleepActionServer
int main(int argc, char** argv)
{
rclcpp::init(argc, argv);
auto node = std::make_shared<SleepActionServer>();
rclcpp::spin(node);
return 0;
}