Skip to content

Commit ea67710

Browse files
committed
[Test sprint] push nav2_map_server over 90% (#1922)
* adding CLI test * adding tests for more lines to map_server * fix last test * adding out of bounds and higher bounds checks * adding planner tests for plugins working * add cleanup * working * ping
1 parent 6c5ca28 commit ea67710

File tree

8 files changed

+152
-43
lines changed

8 files changed

+152
-43
lines changed

nav2_controller/src/nav2_controller.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,6 @@ ControllerServer::ControllerServer()
6363
ControllerServer::~ControllerServer()
6464
{
6565
RCLCPP_INFO(get_logger(), "Destroying");
66-
controllers_.clear();
67-
costmap_thread_.reset();
6866
}
6967

7068
nav2_util::CallbackReturn
@@ -404,6 +402,8 @@ void ControllerServer::publishZeroVelocity()
404402
velocity.twist.linear.x = 0;
405403
velocity.twist.linear.y = 0;
406404
velocity.twist.linear.z = 0;
405+
velocity.header.frame_id = costmap_ros_->getBaseFrameID();
406+
velocity.header.stamp = now();
407407
publishVelocity(velocity);
408408
}
409409

nav2_map_server/test/component/test_map_server_node.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class MapServerTestFixture : public ::testing::Test
5858
{
5959
lifecycle_client_->change_state(Transition::TRANSITION_DEACTIVATE);
6060
lifecycle_client_->change_state(Transition::TRANSITION_CLEANUP);
61+
lifecycle_client_->change_state(Transition::TRANSITION_UNCONFIGURED_SHUTDOWN);
6162
}
6263

6364
template<class T>

nav2_map_server/test/map_saver_cli/test_map_saver_cli.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ TEST(MapSaverCLI, CLITest)
4747
msg->info.origin.position.y = 0.0;
4848
msg->info.origin.orientation.w = 1.0;
4949
msg->data.resize(9);
50+
msg->data[0] = 0;
51+
msg->data[2] = 100;
52+
msg->data[1] = 101;
53+
msg->data[3] = 50;
5054

5155
RCLCPP_INFO(node->get_logger(), "Publishing occupancy grid...");
5256

@@ -105,24 +109,38 @@ TEST(MapSaverCLI, CLITest)
105109
return_code = system(command.c_str());
106110
EXPECT_EQ(return_code, 0);
107111

112+
rclcpp::Rate(0.5).sleep();
113+
108114
RCLCPP_INFO(node->get_logger(), "Testing invalid mode...");
109115
command =
110116
std::string(
111117
"ros2 run nav2_map_server map_saver_cli --mode fake_mode");
112118
return_code = system(command.c_str());
113119
EXPECT_EQ(return_code, 0);
114120

121+
rclcpp::Rate(0.5).sleep();
122+
115123
RCLCPP_INFO(node->get_logger(), "Testing missing argument...");
116124
command =
117125
std::string(
118126
"ros2 run nav2_map_server map_saver_cli --mode");
119127
return_code = system(command.c_str());
120128
EXPECT_EQ(return_code, 65280);
121129

130+
rclcpp::Rate(0.5).sleep();
131+
122132
RCLCPP_INFO(node->get_logger(), "Testing wrong argument...");
123133
command =
124134
std::string(
125135
"ros2 run nav2_map_server map_saver_cli --free 0 0");
126136
return_code = system(command.c_str());
127137
EXPECT_EQ(return_code, 65280);
138+
139+
rclcpp::Rate(0.5).sleep();
140+
141+
command =
142+
std::string(
143+
"ros2 run nav2_map_server map_saver_cli --ros-args -r __node:=map_saver_test_node");
144+
return_code = system(command.c_str());
145+
EXPECT_EQ(return_code, 0);
128146
}

nav2_navfn_planner/src/navfn_planner.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,9 @@ NavfnPlanner::makePlan(
152152
// clear the plan, just in case
153153
plan.poses.clear();
154154

155+
plan.header.stamp = node_->now();
156+
plan.header.frame_id = global_frame_;
157+
155158
// TODO(orduno): add checks for start and goal reference frame -- should be in global frame
156159

157160
double wx = start.position.x;
@@ -327,9 +330,6 @@ NavfnPlanner::getPlanFromPotential(
327330
float * y = planner_->getPathY();
328331
int len = planner_->getPathLen();
329332

330-
plan.header.stamp = node_->now();
331-
plan.header.frame_id = global_frame_;
332-
333333
for (int i = len - 1; i >= 0; --i) {
334334
// convert the plan to world coordinates
335335
double world_x, world_y;

nav2_planner/include/nav2_planner/planner_server.hpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ class PlannerServer : public nav2_util::LifecycleNode
5858

5959
using PlannerMap = std::unordered_map<std::string, nav2_core::GlobalPlanner::Ptr>;
6060

61+
/**
62+
* @brief Method to get plan from the desired plugin
63+
* @param start starting pose
64+
* @param goal goal request
65+
* @return Path
66+
*/
67+
nav_msgs::msg::Path getPlan(
68+
const geometry_msgs::msg::PoseStamped & start,
69+
const geometry_msgs::msg::PoseStamped & goal,
70+
const std::string & planner_id);
71+
6172
protected:
6273
/**
6374
* @brief Configure member variables and initializes planner
@@ -90,7 +101,8 @@ class PlannerServer : public nav2_util::LifecycleNode
90101
*/
91102
nav2_util::CallbackReturn on_shutdown(const rclcpp_lifecycle::State & state) override;
92103

93-
using ActionServer = nav2_util::SimpleActionServer<nav2_msgs::action::ComputePathToPose>;
104+
using ActionT = nav2_msgs::action::ComputePathToPose;
105+
using ActionServer = nav2_util::SimpleActionServer<ActionT>;
94106

95107
// Our action server implements the ComputePathToPose action
96108
std::unique_ptr<ActionServer> action_server_;
@@ -129,9 +141,6 @@ class PlannerServer : public nav2_util::LifecycleNode
129141

130142
// Publishers for the path
131143
rclcpp_lifecycle::LifecyclePublisher<nav_msgs::msg::Path>::SharedPtr plan_publisher_;
132-
133-
// Whether we've published the single planner warning yet
134-
bool single_planner_warning_given_{false};
135144
};
136145

137146
} // namespace nav2_planner

nav2_planner/src/planner_server.cpp

Lines changed: 41 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -120,12 +120,11 @@ PlannerServer::on_configure(const rclcpp_lifecycle::State & state)
120120
if (expected_planner_frequency > 0) {
121121
max_planner_duration_ = 1 / expected_planner_frequency;
122122
} else {
123-
max_planner_duration_ = 0.0;
124-
125123
RCLCPP_WARN(
126124
get_logger(),
127-
"The expected planner frequency parameter is %.4f Hz. The value has to be greater"
128-
" than 0.0 to turn on displaying warning messages", expected_planner_frequency);
125+
"The expected planner frequency parameter is %.4f Hz. The value should to be greater"
126+
" than 0.0 to turn on duration overrrun warning messages", expected_planner_frequency);
127+
max_planner_duration_ = 0.0;
129128
}
130129

131130
// Initialize pubs & subs
@@ -230,7 +229,6 @@ PlannerServer::computePlan()
230229

231230
geometry_msgs::msg::PoseStamped start;
232231
if (!costmap_ros_->getRobotPose(start)) {
233-
RCLCPP_ERROR(this->get_logger(), "Could not get robot pose");
234232
action_server_->terminate_current();
235233
return;
236234
}
@@ -240,30 +238,7 @@ PlannerServer::computePlan()
240238
goal = action_server_->accept_pending_goal();
241239
}
242240

243-
RCLCPP_DEBUG(
244-
get_logger(), "Attempting to a find path from (%.2f, %.2f) to "
245-
"(%.2f, %.2f).", start.pose.position.x, start.pose.position.y,
246-
goal->pose.pose.position.x, goal->pose.pose.position.y);
247-
248-
if (planners_.find(goal->planner_id) != planners_.end()) {
249-
result->path = planners_[goal->planner_id]->createPlan(start, goal->pose);
250-
} else {
251-
if (planners_.size() == 1 && goal->planner_id.empty()) {
252-
if (!single_planner_warning_given_) {
253-
single_planner_warning_given_ = true;
254-
RCLCPP_WARN(
255-
get_logger(), "No planners specified in action call. "
256-
"Server will use only plugin %s in server."
257-
" This warning will appear once.", planner_ids_concat_.c_str());
258-
}
259-
result->path = planners_[planners_.begin()->first]->createPlan(start, goal->pose);
260-
} else {
261-
RCLCPP_ERROR(
262-
get_logger(), "planner %s is not a valid planner. "
263-
"Planner names are: %s", goal->planner_id.c_str(),
264-
planner_ids_concat_.c_str());
265-
}
266-
}
241+
result->path = getPlan(start, goal->pose, goal->planner_id);
267242

268243
if (result->path.poses.size() == 0) {
269244
RCLCPP_WARN(
@@ -281,7 +256,6 @@ PlannerServer::computePlan()
281256
goal->pose.pose.position.y);
282257

283258
// Publish the plan for visualization purposes
284-
RCLCPP_DEBUG(get_logger(), "Publishing the valid path");
285259
publishPlan(result->path);
286260

287261
auto cycle_duration = steady_clock_.now() - start_time;
@@ -295,8 +269,6 @@ PlannerServer::computePlan()
295269
}
296270

297271
action_server_->succeeded_current(result);
298-
299-
return;
300272
} catch (std::exception & ex) {
301273
RCLCPP_WARN(
302274
get_logger(), "%s plugin failed to plan calculation to (%.2f, %.2f): \"%s\"",
@@ -305,15 +277,50 @@ PlannerServer::computePlan()
305277
// TODO(orduno): provide information about fail error to parent task,
306278
// for example: couldn't get costmap update
307279
action_server_->terminate_current();
308-
return;
309280
}
310281
}
311282

283+
nav_msgs::msg::Path
284+
PlannerServer::getPlan(
285+
const geometry_msgs::msg::PoseStamped & start,
286+
const geometry_msgs::msg::PoseStamped & goal,
287+
const std::string & planner_id)
288+
{
289+
RCLCPP_DEBUG(
290+
get_logger(), "Attempting to a find path from (%.2f, %.2f) to "
291+
"(%.2f, %.2f).", start.pose.position.x, start.pose.position.y,
292+
goal.pose.position.x, goal.pose.position.y);
293+
294+
if (planners_.find(planner_id) != planners_.end()) {
295+
return planners_[planner_id]->createPlan(start, goal);
296+
} else {
297+
if (planners_.size() == 1 && planner_id.empty()) {
298+
RCLCPP_WARN_ONCE(
299+
get_logger(), "No planners specified in action call. "
300+
"Server will use only plugin %s in server."
301+
" This warning will appear once.", planner_ids_concat_.c_str());
302+
return planners_[planners_.begin()->first]->createPlan(start, goal);
303+
} else {
304+
RCLCPP_ERROR(
305+
get_logger(), "planner %s is not a valid planner. "
306+
"Planner names are: %s", planner_id.c_str(),
307+
planner_ids_concat_.c_str());
308+
}
309+
}
310+
311+
return nav_msgs::msg::Path();
312+
}
313+
312314
void
313315
PlannerServer::publishPlan(const nav_msgs::msg::Path & path)
314316
{
315317
auto msg = std::make_unique<nav_msgs::msg::Path>(path);
316-
plan_publisher_->publish(std::move(msg));
318+
if (
319+
plan_publisher_->is_activated() &&
320+
this->count_subscribers(plan_publisher_->get_topic_name()) > 0)
321+
{
322+
plan_publisher_->publish(std::move(msg));
323+
}
317324
}
318325

319326
} // namespace nav2_planner

nav2_system_tests/src/planning/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,13 @@ ament_add_test(test_planner_random
4545
TEST_EXECUTABLE=$<TARGET_FILE:${test_planner_random_exec}>
4646
TEST_MAP=${PROJECT_SOURCE_DIR}/maps/map.pgm
4747
)
48+
49+
ament_add_gtest(test_planner_plugin_failures
50+
test_planner_plugins.cpp
51+
)
52+
53+
ament_target_dependencies(test_planner_plugin_failures rclcpp geometry_msgs nav2_msgs ${dependencies})
54+
55+
target_link_libraries(test_planner_plugin_failures
56+
stdc++fs
57+
)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright (c) 2020 Samsung Research
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License. Reserved.
14+
15+
#include <gtest/gtest.h>
16+
#include <memory>
17+
#include <vector>
18+
#include <string>
19+
20+
#include "rclcpp/rclcpp.hpp"
21+
#include "planner_tester.hpp"
22+
#include "nav2_util/lifecycle_utils.hpp"
23+
24+
using namespace std::chrono_literals;
25+
26+
using nav2_system_tests::PlannerTester;
27+
using nav2_util::TestCostmap;
28+
29+
using ComputePathToPoseCommand = geometry_msgs::msg::PoseStamped;
30+
using ComputePathToPoseResult = nav_msgs::msg::Path;
31+
32+
TEST(testPluginMap, Failures)
33+
{
34+
auto obj = std::make_shared<nav2_system_tests::NavFnPlannerTester>();
35+
rclcpp_lifecycle::State state;
36+
obj->onConfigure(state);
37+
38+
geometry_msgs::msg::PoseStamped start;
39+
geometry_msgs::msg::PoseStamped goal;
40+
std::string plugin_fake = "fake";
41+
std::string plugin_none = "";
42+
auto path = obj->getPlan(start, goal, plugin_none);
43+
EXPECT_EQ(path.header.frame_id, std::string("map"));
44+
45+
path = obj->getPlan(start, goal, plugin_fake);
46+
EXPECT_EQ(path.poses.size(), 0ul);
47+
48+
obj->onCleanup(state);
49+
}
50+
51+
int main(int argc, char ** argv)
52+
{
53+
::testing::InitGoogleTest(&argc, argv);
54+
55+
// initialize ROS
56+
rclcpp::init(argc, argv);
57+
58+
bool all_successful = RUN_ALL_TESTS();
59+
60+
// shutdown ROS
61+
rclcpp::shutdown();
62+
63+
return all_successful;
64+
}

0 commit comments

Comments
 (0)