26 #include "wait_behavior_tester.hpp"
28 using namespace std::chrono_literals;
29 using namespace std::chrono;
31 namespace nav2_system_tests
34 WaitBehaviorTester::WaitBehaviorTester()
36 initial_pose_received_(false)
38 node_ = rclcpp::Node::make_shared(
"wait_behavior_test");
40 tf_buffer_ = std::make_shared<tf2_ros::Buffer>(node_->get_clock());
41 tf_listener_ = std::make_shared<tf2_ros::TransformListener>(*tf_buffer_);
43 client_ptr_ = rclcpp_action::create_client<Wait>(
44 node_->get_node_base_interface(),
45 node_->get_node_graph_interface(),
46 node_->get_node_logging_interface(),
47 node_->get_node_waitables_interface(),
51 node_->create_publisher<geometry_msgs::msg::PoseWithCovarianceStamped>(
"initialpose", 10);
53 subscription_ = node_->create_subscription<geometry_msgs::msg::PoseWithCovarianceStamped>(
54 "amcl_pose", rclcpp::QoS(rclcpp::KeepLast(1)).transient_local().reliable(),
55 std::bind(&WaitBehaviorTester::amclPoseCallback,
this, std::placeholders::_1));
58 WaitBehaviorTester::~WaitBehaviorTester()
65 void WaitBehaviorTester::activate()
68 throw std::runtime_error(
"Trying to activate while already active");
72 while (!initial_pose_received_) {
73 RCLCPP_WARN(node_->get_logger(),
"Initial pose not received");
75 std::this_thread::sleep_for(100ms);
76 rclcpp::spin_some(node_);
80 std::this_thread::sleep_for(10s);
83 RCLCPP_ERROR(node_->get_logger(),
"Action client not initialized");
88 if (!client_ptr_->wait_for_action_server(10s)) {
89 RCLCPP_ERROR(node_->get_logger(),
"Action server not available after waiting");
94 RCLCPP_INFO(this->node_->get_logger(),
"Wait action server is ready");
98 void WaitBehaviorTester::deactivate()
101 throw std::runtime_error(
"Trying to deactivate while already inactive");
106 bool WaitBehaviorTester::behaviorTest(
107 const float wait_time)
110 RCLCPP_ERROR(node_->get_logger(),
"Not activated");
115 std::this_thread::sleep_for(5s);
117 auto start_time = node_->now();
118 auto goal_msg = Wait::Goal();
119 goal_msg.time = rclcpp::Duration(wait_time, 0.0);
121 RCLCPP_INFO(this->node_->get_logger(),
"Sending goal");
123 auto goal_handle_future = client_ptr_->async_send_goal(goal_msg);
125 if (rclcpp::spin_until_future_complete(node_, goal_handle_future) !=
126 rclcpp::FutureReturnCode::SUCCESS)
128 RCLCPP_ERROR(node_->get_logger(),
"send goal call failed :(");
132 rclcpp_action::ClientGoalHandle<Wait>::SharedPtr goal_handle = goal_handle_future.get();
134 RCLCPP_ERROR(node_->get_logger(),
"Goal was rejected by server");
139 auto result_future = client_ptr_->async_get_result(goal_handle);
141 RCLCPP_INFO(node_->get_logger(),
"Waiting for result");
142 if (rclcpp::spin_until_future_complete(node_, result_future) !=
143 rclcpp::FutureReturnCode::SUCCESS)
145 RCLCPP_ERROR(node_->get_logger(),
"get result call failed :(");
149 rclcpp_action::ClientGoalHandle<Wait>::WrappedResult wrapped_result = result_future.get();
151 switch (wrapped_result.code) {
152 case rclcpp_action::ResultCode::SUCCEEDED:
break;
153 case rclcpp_action::ResultCode::ABORTED: RCLCPP_ERROR(
157 case rclcpp_action::ResultCode::CANCELED: RCLCPP_ERROR(
159 "Goal was canceled");
161 default: RCLCPP_ERROR(node_->get_logger(),
"Unknown result code");
165 RCLCPP_INFO(node_->get_logger(),
"result received");
167 if ((node_->now() - start_time).seconds() <
static_cast<double>(wait_time)) {
174 bool WaitBehaviorTester::behaviorTestCancel(
175 const float wait_time)
178 RCLCPP_ERROR(node_->get_logger(),
"Not activated");
183 std::this_thread::sleep_for(5s);
185 auto start_time = node_->now();
186 auto goal_msg = Wait::Goal();
187 goal_msg.time = rclcpp::Duration(wait_time, 0.0);
189 RCLCPP_INFO(this->node_->get_logger(),
"Sending goal");
191 auto goal_handle_future = client_ptr_->async_send_goal(goal_msg);
193 if (rclcpp::spin_until_future_complete(node_, goal_handle_future) !=
194 rclcpp::FutureReturnCode::SUCCESS)
196 RCLCPP_ERROR(node_->get_logger(),
"send goal call failed :(");
200 rclcpp_action::ClientGoalHandle<Wait>::SharedPtr goal_handle = goal_handle_future.get();
202 RCLCPP_ERROR(node_->get_logger(),
"Goal was rejected by server");
207 auto result_future = client_ptr_->async_cancel_all_goals();
209 RCLCPP_INFO(node_->get_logger(),
"Waiting for cancellation");
210 if (rclcpp::spin_until_future_complete(node_, result_future) !=
211 rclcpp::FutureReturnCode::SUCCESS)
213 RCLCPP_ERROR(node_->get_logger(),
"get cancel result call failed :(");
217 auto status = goal_handle_future.get()->get_status();
220 case rclcpp_action::GoalStatus::STATUS_SUCCEEDED: RCLCPP_ERROR(
224 case rclcpp_action::GoalStatus::STATUS_ABORTED: RCLCPP_ERROR(
228 case rclcpp_action::GoalStatus::STATUS_CANCELED: RCLCPP_INFO(
230 "Goal was canceled");
232 case rclcpp_action::GoalStatus::STATUS_CANCELING: RCLCPP_INFO(
234 "Goal is cancelling");
236 case rclcpp_action::GoalStatus::STATUS_EXECUTING: RCLCPP_ERROR(
238 "Goal is executing");
240 case rclcpp_action::GoalStatus::STATUS_ACCEPTED: RCLCPP_ERROR(
242 "Goal is processing");
244 default: RCLCPP_ERROR(node_->get_logger(),
"Unknown result code");
251 void WaitBehaviorTester::sendInitialPose()
253 geometry_msgs::msg::PoseWithCovarianceStamped pose;
254 pose.header.frame_id =
"map";
255 pose.header.stamp = rclcpp::Time();
256 pose.pose.pose.position.x = -2.0;
257 pose.pose.pose.position.y = -0.5;
258 pose.pose.pose.position.z = 0.0;
259 pose.pose.pose.orientation.x = 0.0;
260 pose.pose.pose.orientation.y = 0.0;
261 pose.pose.pose.orientation.z = 0.0;
262 pose.pose.pose.orientation.w = 1.0;
263 for (
int i = 0; i < 35; i++) {
264 pose.pose.covariance[i] = 0.0;
266 pose.pose.covariance[0] = 0.08;
267 pose.pose.covariance[7] = 0.08;
268 pose.pose.covariance[35] = 0.05;
270 publisher_->publish(pose);
271 RCLCPP_INFO(node_->get_logger(),
"Sent initial pose");
274 void WaitBehaviorTester::amclPoseCallback(
275 const geometry_msgs::msg::PoseWithCovarianceStamped::SharedPtr)
277 initial_pose_received_ =
true;