26 #include "wait_behavior_tester.hpp"
27 #include "nav2_ros_common/tf2_factories.hpp"
29 using namespace std::chrono_literals;
30 using namespace std::chrono;
32 namespace nav2_system_tests
35 WaitBehaviorTester::WaitBehaviorTester()
37 initial_pose_received_(false)
39 node_ = rclcpp::Node::make_shared(
41 rclcpp::NodeOptions().parameter_overrides(
42 {rclcpp::Parameter(
"use_sim_time",
true)}));
44 tf_buffer_ = nav2::create_transform_buffer(node_);
45 tf_listener_ = nav2::create_transform_listener(*tf_buffer_);
47 client_ptr_ = rclcpp_action::create_client<Wait>(
48 node_->get_node_base_interface(),
49 node_->get_node_graph_interface(),
50 node_->get_node_logging_interface(),
51 node_->get_node_waitables_interface(),
55 node_->create_publisher<geometry_msgs::msg::PoseWithCovarianceStamped>(
"initialpose", 10);
57 subscription_ = node_->create_subscription<geometry_msgs::msg::PoseWithCovarianceStamped>(
58 "amcl_pose", rclcpp::QoS(rclcpp::KeepLast(1)).transient_local().reliable(),
59 std::bind(&WaitBehaviorTester::amclPoseCallback,
this, std::placeholders::_1));
62 WaitBehaviorTester::~WaitBehaviorTester()
69 void WaitBehaviorTester::activate()
72 throw std::runtime_error(
"Trying to activate while already active");
75 rclcpp::executors::SingleThreadedExecutor executor;
76 executor.add_node(node_);
77 while (!initial_pose_received_) {
78 RCLCPP_WARN(node_->get_logger(),
"Initial pose not received");
80 std::this_thread::sleep_for(100ms);
85 std::this_thread::sleep_for(10s);
88 RCLCPP_ERROR(node_->get_logger(),
"Action client not initialized");
93 if (!client_ptr_->wait_for_action_server(10s)) {
94 RCLCPP_ERROR(node_->get_logger(),
"Action server not available after waiting");
99 RCLCPP_INFO(this->node_->get_logger(),
"Wait action server is ready");
103 void WaitBehaviorTester::deactivate()
106 throw std::runtime_error(
"Trying to deactivate while already inactive");
111 bool WaitBehaviorTester::behaviorTest(
112 const float wait_time)
115 RCLCPP_ERROR(node_->get_logger(),
"Not activated");
120 std::this_thread::sleep_for(5s);
122 auto start_time = node_->now();
123 auto goal_msg = Wait::Goal();
124 goal_msg.time = rclcpp::Duration(wait_time, 0.0);
126 RCLCPP_INFO(this->node_->get_logger(),
"Sending goal");
128 auto goal_handle_future = client_ptr_->async_send_goal(goal_msg);
130 if (rclcpp::spin_until_future_complete(node_, goal_handle_future) !=
131 rclcpp::FutureReturnCode::SUCCESS)
133 RCLCPP_ERROR(node_->get_logger(),
"send goal call failed :(");
137 rclcpp_action::ClientGoalHandle<Wait>::SharedPtr goal_handle = goal_handle_future.get();
139 RCLCPP_ERROR(node_->get_logger(),
"Goal was rejected by server");
144 auto result_future = client_ptr_->async_get_result(goal_handle);
146 RCLCPP_INFO(node_->get_logger(),
"Waiting for result");
147 if (rclcpp::spin_until_future_complete(node_, result_future) !=
148 rclcpp::FutureReturnCode::SUCCESS)
150 RCLCPP_ERROR(node_->get_logger(),
"get result call failed :(");
154 rclcpp_action::ClientGoalHandle<Wait>::WrappedResult wrapped_result = result_future.get();
156 switch (wrapped_result.code) {
157 case rclcpp_action::ResultCode::SUCCEEDED:
break;
158 case rclcpp_action::ResultCode::ABORTED: RCLCPP_ERROR(
162 case rclcpp_action::ResultCode::CANCELED: RCLCPP_ERROR(
164 "Goal was canceled");
166 default: RCLCPP_ERROR(node_->get_logger(),
"Unknown result code");
170 RCLCPP_INFO(node_->get_logger(),
"result received");
172 if ((node_->now() - start_time).seconds() <
static_cast<double>(wait_time)) {
179 bool WaitBehaviorTester::behaviorTestCancel(
180 const float wait_time)
183 RCLCPP_ERROR(node_->get_logger(),
"Not activated");
188 std::this_thread::sleep_for(5s);
190 auto start_time = node_->now();
191 auto goal_msg = Wait::Goal();
192 goal_msg.time = rclcpp::Duration(wait_time, 0.0);
194 RCLCPP_INFO(this->node_->get_logger(),
"Sending goal");
196 auto goal_handle_future = client_ptr_->async_send_goal(goal_msg);
198 if (rclcpp::spin_until_future_complete(node_, goal_handle_future) !=
199 rclcpp::FutureReturnCode::SUCCESS)
201 RCLCPP_ERROR(node_->get_logger(),
"send goal call failed :(");
205 rclcpp_action::ClientGoalHandle<Wait>::SharedPtr goal_handle = goal_handle_future.get();
207 RCLCPP_ERROR(node_->get_logger(),
"Goal was rejected by server");
212 auto result_future = client_ptr_->async_cancel_all_goals();
214 RCLCPP_INFO(node_->get_logger(),
"Waiting for cancellation");
215 if (rclcpp::spin_until_future_complete(node_, result_future) !=
216 rclcpp::FutureReturnCode::SUCCESS)
218 RCLCPP_ERROR(node_->get_logger(),
"get cancel result call failed :(");
222 auto status = goal_handle_future.get()->get_status();
225 case rclcpp_action::GoalStatus::STATUS_SUCCEEDED: RCLCPP_ERROR(
229 case rclcpp_action::GoalStatus::STATUS_ABORTED: RCLCPP_ERROR(
233 case rclcpp_action::GoalStatus::STATUS_CANCELED: RCLCPP_INFO(
235 "Goal was canceled");
237 case rclcpp_action::GoalStatus::STATUS_CANCELING: RCLCPP_INFO(
239 "Goal is cancelling");
241 case rclcpp_action::GoalStatus::STATUS_EXECUTING: RCLCPP_ERROR(
243 "Goal is executing");
245 case rclcpp_action::GoalStatus::STATUS_ACCEPTED: RCLCPP_ERROR(
247 "Goal is processing");
249 default: RCLCPP_ERROR(node_->get_logger(),
"Unknown result code");
256 void WaitBehaviorTester::sendInitialPose()
258 geometry_msgs::msg::PoseWithCovarianceStamped pose;
259 pose.header.frame_id =
"map";
260 pose.header.stamp = rclcpp::Time();
261 pose.pose.pose.position.x = -2.0;
262 pose.pose.pose.position.y = -0.5;
263 pose.pose.pose.position.z = 0.0;
264 pose.pose.pose.orientation.x = 0.0;
265 pose.pose.pose.orientation.y = 0.0;
266 pose.pose.pose.orientation.z = 0.0;
267 pose.pose.pose.orientation.w = 1.0;
268 for (
int i = 0; i < 35; i++) {
269 pose.pose.covariance[i] = 0.0;
271 pose.pose.covariance[0] = 0.08;
272 pose.pose.covariance[7] = 0.08;
273 pose.pose.covariance[35] = 0.05;
275 publisher_->publish(pose);
276 RCLCPP_INFO(node_->get_logger(),
"Sent initial pose");
279 void WaitBehaviorTester::amclPoseCallback(
280 const geometry_msgs::msg::PoseWithCovarianceStamped::ConstSharedPtr)
282 initial_pose_received_ =
true;