Skip to content

Commit 2a110ba

Browse files
AlexeyMerzlyakovAndrew Lycas
authored andcommitted
Fix mask coordinates calculation in worldToMask (ros-navigation#3418)
1 parent a6ed732 commit 2a110ba

File tree

3 files changed

+117
-7
lines changed

3 files changed

+117
-7
lines changed

nav2_costmap_2d/plugins/costmap_filters/costmap_filter.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,18 +187,18 @@ bool CostmapFilter::worldToMask(
187187
nav_msgs::msg::OccupancyGrid::ConstSharedPtr filter_mask,
188188
double wx, double wy, unsigned int & mx, unsigned int & my) const
189189
{
190-
double origin_x = filter_mask->info.origin.position.x;
191-
double origin_y = filter_mask->info.origin.position.y;
192-
double resolution = filter_mask->info.resolution;
193-
unsigned int size_x = filter_mask->info.width;
194-
unsigned int size_y = filter_mask->info.height;
190+
const double origin_x = filter_mask->info.origin.position.x;
191+
const double origin_y = filter_mask->info.origin.position.y;
192+
const double resolution = filter_mask->info.resolution;
193+
const unsigned int size_x = filter_mask->info.width;
194+
const unsigned int size_y = filter_mask->info.height;
195195

196196
if (wx < origin_x || wy < origin_y) {
197197
return false;
198198
}
199199

200-
mx = std::round((wx - origin_x) / resolution);
201-
my = std::round((wy - origin_y) / resolution);
200+
mx = static_cast<unsigned int>((wx - origin_x) / resolution);
201+
my = static_cast<unsigned int>((wy - origin_y) / resolution);
202202
if (mx >= size_x || my >= size_y) {
203203
return false;
204204
}

nav2_costmap_2d/test/unit/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ target_link_libraries(declare_parameter_test
1818
nav2_costmap_2d_core
1919
)
2020

21+
ament_add_gtest(costmap_filter_test costmap_filter_test.cpp)
22+
target_link_libraries(costmap_filter_test
23+
nav2_costmap_2d_core
24+
)
25+
2126
ament_add_gtest(keepout_filter_test keepout_filter_test.cpp)
2227
target_link_libraries(keepout_filter_test
2328
nav2_costmap_2d_core
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
// Copyright (c) 2023 Samsung R&D Institute Russia
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+
17+
#include <string>
18+
#include <memory>
19+
20+
#include "rclcpp/rclcpp.hpp"
21+
#include "nav2_util/occ_grid_values.hpp"
22+
#include "nav_msgs/msg/occupancy_grid.hpp"
23+
#include "geometry_msgs/msg/pose2_d.hpp"
24+
#include "nav2_costmap_2d/costmap_2d.hpp"
25+
#include "nav2_costmap_2d/costmap_filters/costmap_filter.hpp"
26+
27+
class CostmapFilterWrapper : public nav2_costmap_2d::CostmapFilter
28+
{
29+
public:
30+
CostmapFilterWrapper() {}
31+
32+
bool worldToMask(
33+
nav_msgs::msg::OccupancyGrid::ConstSharedPtr filter_mask,
34+
double wx, double wy, unsigned int & mx, unsigned int & my) const
35+
{
36+
return nav2_costmap_2d::CostmapFilter::worldToMask(filter_mask, wx, wy, mx, my);
37+
}
38+
39+
// API coverage
40+
void initializeFilter(const std::string &) {}
41+
void process(
42+
nav2_costmap_2d::Costmap2D &, int, int, int, int, const geometry_msgs::msg::Pose2D &)
43+
{}
44+
void resetFilter() {}
45+
};
46+
47+
TEST(CostmapFilter, testWorldToMask)
48+
{
49+
// Create occupancy grid for test as follows:
50+
//
51+
// ^
52+
// | (6,6)
53+
// | *-----*
54+
// | |/////| <- mask
55+
// | |/////|
56+
// | *-----*
57+
// | (3,3)
58+
// *---------------->
59+
// (0,0)
60+
61+
const unsigned int width = 3;
62+
const unsigned int height = 3;
63+
64+
auto mask = std::make_shared<nav_msgs::msg::OccupancyGrid>();
65+
mask->header.frame_id = "map";
66+
mask->info.resolution = 1.0;
67+
mask->info.width = width;
68+
mask->info.height = height;
69+
mask->info.origin.position.x = 3.0;
70+
mask->info.origin.position.y = 3.0;
71+
72+
mask->data.resize(width * height, nav2_util::OCC_GRID_OCCUPIED);
73+
74+
CostmapFilterWrapper cf;
75+
unsigned int mx, my;
76+
// Point inside mask
77+
ASSERT_TRUE(cf.worldToMask(mask, 4.0, 5.0, mx, my));
78+
ASSERT_EQ(mx, 1);
79+
ASSERT_EQ(my, 2);
80+
// Corner cases
81+
ASSERT_TRUE(cf.worldToMask(mask, 3.0, 3.0, mx, my));
82+
ASSERT_EQ(mx, 0);
83+
ASSERT_EQ(my, 0);
84+
ASSERT_TRUE(cf.worldToMask(mask, 5.9, 5.9, mx, my));
85+
ASSERT_EQ(mx, 2);
86+
ASSERT_EQ(my, 2);
87+
// Point outside mask
88+
ASSERT_FALSE(cf.worldToMask(mask, 2.9, 2.9, mx, my));
89+
ASSERT_FALSE(cf.worldToMask(mask, 6.0, 6.0, mx, my));
90+
}
91+
92+
int main(int argc, char ** argv)
93+
{
94+
// Initialize the system
95+
testing::InitGoogleTest(&argc, argv);
96+
rclcpp::init(argc, argv);
97+
98+
// Actual testing
99+
bool test_result = RUN_ALL_TESTS();
100+
101+
// Shutdown
102+
rclcpp::shutdown();
103+
104+
return test_result;
105+
}

0 commit comments

Comments
 (0)