Skip to content

Commit 449f1f4

Browse files
authored
Merge pull request #3 from leggedrobotics/noetic
Noetic
2 parents 1f10668 + a1b98e6 commit 449f1f4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1584
-225
lines changed

README.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ Features:
1515
* **Visualizations:** The *grid_map_rviz_plugin* renders grid maps as 3d surface plots (height maps) in [RViz]. Additionally, the *grid_map_visualization* package helps to visualize grid maps as point clouds, occupancy grids, grid cells etc.
1616
* **Filters:** The *grid_map_filters* provides are range of filters to process grid maps as a sequence of filters. Parsing of mathematical expressions allows to flexibly setup powerful computations such as thresholding, normal vectors, smoothening, variance, inpainting, and matrix kernel convolutions.
1717

18-
The grid map package has been tested with [ROS] Indigo, Jade (under Ubuntu 14.04), Kinetic (under Ubuntu 16.04), and Melodic (under Ubuntu 18.04). This is research code, expect that it changes often and any fitness for a particular purpose is disclaimed.
18+
This is research code, expect that it changes often and any fitness for a particular purpose is disclaimed.
1919

2020
The source code is released under a [BSD 3-Clause license](LICENSE).
2121

2222
**Author: Péter Fankhauser<br />
2323
Affiliation: [ANYbotics](https://www.anybotics.com/)<br />
2424
Maintainer: Péter Fankhauser, pfankhauser@anybotics.com<br />**
25-
With contributions by: Tanja Baumann, Jeff Delmerico, Remo Diethelm, Perry Franklin, Dominic Jud, Ralph Kaestner, Philipp Krüsi, Alex Millane, Daniel Stonier, Elena Stumm, Martin Wermelinger, Christos Zalidis, Edo Jelavic, Ruben Grandia, Simone Arreghini
25+
With contributions by: Tanja Baumann, Jeff Delmerico, Remo Diethelm, Perry Franklin, Dominic Jud, Ralph Kaestner, Philipp Krüsi, Alex Millane, Daniel Stonier, Elena Stumm, Martin Wermelinger, Christos Zalidis, Edo Jelavic, Ruben Grandia, Simone Arreghini, Magnus Gärtner
2626

2727
This projected was initially developed at ETH Zurich (Autonomous Systems Lab & Robotic Systems Lab).
2828

@@ -152,6 +152,10 @@ The *grid_map_demos* package contains several demonstration nodes. Use this code
152152
roslaunch grid_map_demos image_to_gridmap_demo.launch
153153

154154
![Image to grid map demo result](grid_map_demos/doc/image_to_grid_map_demo_result.png)
155+
156+
* *[grid_map_to_image_demo](grid_map_demos/src/GridmapToImageDemo.cpp)* demonstrates how to save a grid map layer to an image. Start the demonstration with
157+
158+
rosrun grid_map_demos grid_map_to_image_demo _grid_map_topic:=/grid_map _file:=/home/$USER/Desktop/grid_map_image.png
155159

156160
* *[opencv_demo](grid_map_demos/src/opencv_demo_node.cpp)* demonstrates map manipulations with help of [OpenCV] functions. Start the demonstration with
157161

@@ -391,7 +395,20 @@ Several basic filters are provided in the *grid_map_filters* package:
391395
input_layer: input
392396
output_layer: output
393397
radius: 0.06 # in m.
398+
* **`gridMapFilters/MedianFillFilter`**
399+
400+
Compute for each _NaN_ cell of a layer the median (of finites) inside a patch with radius.
401+
Optionally, apply median calculations for values that are already finite, the patch radius for these points is given by existing_value_radius.
394402

403+
name: median
404+
type: gridMapFilters/MedianFillFilter
405+
params:
406+
input_layer: input
407+
output_layer: output
408+
fill_hole_radius: 0.11 # in m.
409+
filter_existing_values: false # Default is false. If enabled it also does a median computation for existing values.
410+
existing_value_radius: 0.2 # in m. Note that this option only has an effect if filter_existing_values is set true.
411+
395412
* **`gridMapFilters/NormalVectorsFilter`**
396413

397414
Compute the normal vectors of a layer in a map.

grid_map_core/src/GridMapMath.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,22 @@ void wrapIndexToRange(Index& index, const Size& bufferSize)
219219

220220
void wrapIndexToRange(int& index, int bufferSize)
221221
{
222-
index = index % bufferSize;
223-
if (index < 0) {
224-
index += bufferSize;
222+
// Try shortcuts before resorting to the expensive modulo operation.
223+
if (index < bufferSize){
224+
if(index >= 0){ // within the wanted range
225+
return;
226+
} else if(index >= -bufferSize){ // Index is below range, but not more than one span of the range.
227+
index +=bufferSize;
228+
return;
229+
}else{ // Index is largely below range.
230+
index = index % bufferSize;
231+
index += bufferSize;
232+
}
233+
}else if(index < bufferSize*2){ // Index is above range, but not more than one span of the range.
234+
index -= bufferSize;
235+
return;
236+
} else{ // Index is largely above range.
237+
index = index % bufferSize;
225238
}
226239
}
227240

grid_map_core/test/SubmapIteratorTest.cpp

Lines changed: 107 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
* Institute: ETH Zurich, ANYbotics
77
*/
88

9-
#include "grid_map_core/iterators/SubmapIterator.hpp"
109
#include "grid_map_core/GridMap.hpp"
10+
#include "grid_map_core/iterators/SubmapIterator.hpp"
1111

1212
// Eigen
1313
#include <Eigen/Core>
@@ -25,8 +25,7 @@ using namespace std;
2525
using namespace Eigen;
2626
using namespace grid_map;
2727

28-
TEST(SubmapIterator, Simple)
29-
{
28+
TEST(SubmapIterator, Simple) {
3029
Eigen::Array2i submapTopLeftIndex(3, 1);
3130
Eigen::Array2i submapBufferSize(3, 2);
3231
Eigen::Array2i index;
@@ -35,7 +34,7 @@ TEST(SubmapIterator, Simple)
3534
vector<string> types;
3635
types.push_back("type");
3736
GridMap map(types);
38-
map.setGeometry(Array2d(8.1, 5.1), 1.0, Vector2d(0.0, 0.0)); // bufferSize(8, 5)
37+
map.setGeometry(Array2d(8.1, 5.1), 1.0, Vector2d(0.0, 0.0)); // bufferSize(8, 5)
3938

4039
SubmapIterator iterator(map, submapTopLeftIndex, submapBufferSize);
4140

@@ -88,8 +87,7 @@ TEST(SubmapIterator, Simple)
8887
EXPECT_EQ(1, iterator.getSubmapIndex()(1));
8988
}
9089

91-
TEST(SubmapIterator, CircularBuffer)
92-
{
90+
TEST(SubmapIterator, CircularBuffer) {
9391
Eigen::Array2i submapTopLeftIndex(6, 3);
9492
Eigen::Array2i submapBufferSize(2, 4);
9593
Eigen::Array2i index;
@@ -98,8 +96,8 @@ TEST(SubmapIterator, CircularBuffer)
9896
vector<string> types;
9997
types.push_back("type");
10098
GridMap map(types);
101-
map.setGeometry(Length(8.1, 5.1), 1.0, Position(0.0, 0.0)); // bufferSize(8, 5)
102-
map.move(Position(-3.0, -2.0)); // bufferStartIndex(3, 2)
99+
map.setGeometry(Length(8.1, 5.1), 1.0, Position(0.0, 0.0)); // bufferSize(8, 5)
100+
map.move(Position(-3.0, -2.0)); // bufferStartIndex(3, 2)
103101

104102
SubmapIterator iterator(map, submapTopLeftIndex, submapBufferSize);
105103

@@ -165,3 +163,104 @@ TEST(SubmapIterator, CircularBuffer)
165163
EXPECT_EQ(1, iterator.getSubmapIndex()(0));
166164
EXPECT_EQ(3, iterator.getSubmapIndex()(1));
167165
}
166+
167+
/**
168+
* The submap should contain the same elements as before even after moving the underlying map.
169+
*
170+
* +----------------------------+
171+
* | |
172+
* | |
173+
* +----------------------------+ | |
174+
* |0 0 0 0 0 0 0 0 0 0| | 0 0 0 0 0 0 0 0|
175+
* | +----+ | | +----+ |
176+
* Submap |1 1 |1 1| 1 1 1 1 1 1| | 1 1 |1 1| 1 1 1 1|
177+
* +------> | | | | | | |
178+
* |2 2 |2 2| 2 2 2 2 2 2| | 2 2 |2 2| 2 2 2 2|
179+
* | +----+ | | +----+ |
180+
* |3 3 3 3 3 3 3 3 3 3| Move | 3 3 3 3 3 3 3 3|
181+
* | | | |
182+
* |4 4 4 4 4 4 4 4 4 4| +---------> | 4 4 4 4 4 4 4 4|
183+
* | | | |
184+
* |5 5 5 5 5 5 5 5 5 5| | 5 5 5 5 5 5 5 5|
185+
* | | | |
186+
* |6 6 6 6 6 6 6 6 6 6| | 6 6 6 6 6 6 6 6|
187+
* | | | |
188+
* |7 7 7 7 7 7 7 7 7 7| | 7 7 7 7 7 7 7 7|
189+
* | | +----------------------------+
190+
* |8 8 8 8 8 8 8 8 8 8|
191+
* | |
192+
* |9 9 9 9 9 9 9 9 9 9|
193+
* +----------------------------+
194+
*/
195+
TEST(SubmapIterator, InterleavedExecutionWithMove) {
196+
grid_map::Index submapTopLeftIndex(3, 1);
197+
grid_map::Size submapSize(2, 2);
198+
199+
GridMap map({"layer"});
200+
201+
map.setGeometry(Length(10, 10), 1.0, Position(0.0, 0.0)); // bufferSize(8, 5)
202+
203+
auto& layer = map.get("layer");
204+
205+
// Initialize the layer as sketched.
206+
for (size_t colIndex = 0; colIndex < layer.cols(); colIndex++) {
207+
layer.col(colIndex).setConstant(colIndex);
208+
}
209+
210+
std::cout << "(4,7) contains " << map.at("layer", {4, 7}) << std::endl;
211+
// Instantiate the submap iterator as sketched.
212+
SubmapIterator iterator(map, submapTopLeftIndex, submapSize);
213+
214+
// check that the submap iterator returns {1,1,2,2}
215+
auto checkCorrectValues = [](std::array<double, 4> given) {
216+
int countOnes = 0, countTwos = 0;
217+
for (auto& value : given) {
218+
if (std::abs(value - 1.0) < 1e-6) {
219+
countOnes++;
220+
} else if (std::abs(value - 2.0) < 1e-6) {
221+
countTwos++;
222+
} else {
223+
FAIL() << "Submap iterator returned unexpected value.";
224+
}
225+
}
226+
EXPECT_EQ(countOnes, 2);
227+
EXPECT_EQ(countTwos, 2);
228+
};
229+
230+
std::array<double, 4> returnedSequence;
231+
returnedSequence.fill(0);
232+
233+
for (size_t submapIndex = 0; submapIndex < 4; submapIndex++) {
234+
returnedSequence.at(submapIndex) = map.at("layer", *iterator);
235+
++iterator;
236+
}
237+
238+
checkCorrectValues(returnedSequence);
239+
240+
// Reset the iterator and now check that it still returns the same sequence when we move the map interleaved with iterating.
241+
iterator = SubmapIterator(map, submapTopLeftIndex, submapSize);
242+
returnedSequence.fill(0);
243+
for (size_t submapIndex = 0; submapIndex < 4; submapIndex++) {
244+
if (submapIndex == 2) {
245+
// Now move the map as depicted.
246+
map.move(Position(2.0, 2.0));
247+
}
248+
returnedSequence.at(submapIndex) = map.at("layer", *iterator);
249+
++iterator;
250+
}
251+
checkCorrectValues(returnedSequence);
252+
253+
// TODO (mwulf, mgaertner): This behavior is not yet implemented:
254+
//
255+
// // Reset the iterator and now check that the iterator throws? if the submap moved out of range.
256+
// iterator = SubmapIterator(map, submapTopLeftIndex, submapSize);
257+
//
258+
// EXPECT_ANY_THROW(for (size_t submapIndex = 0; submapIndex < 4; submapIndex++) {
259+
// if (submapIndex == 2) {
260+
// // Now move the map so that the submap gets out of range.
261+
// map.move(Position(20.0, 20.0));
262+
// }
263+
// returnedSequence.at(submapIndex) = map.at("layer", *iterator);
264+
// ++iterator;
265+
// });
266+
}

grid_map_cv/CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
22
Changelog for package grid_map_cv
33
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
1.6.3 (2020-09-30)
5+
------------------
6+
* Added getTransformedMap.
47

58
1.6.2 (2019-10-14)
69
------------------

grid_map_cv/include/grid_map_cv/GridMapCvProcessing.hpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* GridMapCvProcessing.hpp
33
*
44
* Created on: Apr 15, 2016
5-
* Author: Péter Fankhauser
5+
* Author: Péter Fankhauser, Magnus Gärtner
66
* Institute: ETH Zurich, ANYbotics
77
*/
88

@@ -18,8 +18,7 @@ namespace grid_map {
1818
/*!
1919
* Processing of grid maps with OpenCV methods.
2020
*/
21-
class GridMapCvProcessing
22-
{
21+
class GridMapCvProcessing {
2322
public:
2423
/*!
2524
* Default constructor.
@@ -39,11 +38,28 @@ class GridMapCvProcessing
3938
* @param[in](optional) interpolationAlgorithm the interpolation method.
4039
* @return true if successful, false otherwise.
4140
*/
42-
static bool changeResolution(const GridMap& gridMapSource,
43-
GridMap& gridMapResult,
44-
const double resolution,
41+
static bool changeResolution(const GridMap& gridMapSource, GridMap& gridMapResult, const double resolution,
4542
const int interpolationAlgorithm = cv::INTER_CUBIC);
4643

44+
/*!
45+
* Apply isometric transformation (rotation + offset) to grid map and returns the transformed map.
46+
* Note: The returned map may not have the same length since it's geometric description contains
47+
* the original map.
48+
* Also note that the map treats the height layer differently from other layers. I.e, the translation in z-direction is applied only to
49+
* the height layer. For layers other than the height layer that contain geometric information this function might compute unexpected
50+
* results. E.g transforming the layers normals_x/y/z will only represent the same values at the transformed location but will not
51+
* transform the normal vectors into the new coordinate system.
52+
*
53+
* @param[consume] gridMapSource The map to transform.
54+
* @param[in] transform the requested transformation to apply.
55+
* @param[in] heightLayerName the height layer of the map.
56+
* @param[in] newFrameId frame index of the new map.
57+
* @return transformed map.
58+
* @throw std::out_of_range if no map layer with name `heightLayerName` is present.
59+
* @throw std::invalid_argument if the transform is not approximately z-aligned.
60+
*/
61+
static GridMap getTransformedMap(GridMap&& gridMapSource, const Eigen::Isometry3d& transform, const std::string& heightLayerName,
62+
const std::string& newFrameId);
4763
};
4864

49-
} /* namespace */
65+
} // namespace grid_map

grid_map_cv/package.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
<?xml version="1.0"?>
22
<package format="2">
33
<name>grid_map_cv</name>
4-
<version>1.6.2</version>
4+
<version>1.6.3</version>
55
<description>Conversions between grid maps and OpenCV images.</description>
66
<maintainer email="mwulf@anybotics.com">Maximilian Wulf</maintainer>
77
<maintainer email="ynava@anybotics.com">Yoshua Nava</maintainer>
88
<license>BSD</license>
99
<url type="website">http://github.com/anybotics/grid_map</url>
1010
<url type="bugtracker">http://github.com/anybotics/grid_map/issues</url>
1111
<author email="pfankhauser@anybotics.com">Péter Fankhauser</author>
12+
<author email="mgaertner@anybotics.com">Magnus Gärtner</author>
1213
<buildtool_depend>catkin</buildtool_depend>
1314
<depend>grid_map_core</depend>
1415
<depend>cv_bridge</depend>

0 commit comments

Comments
 (0)