Skip to content

Commit 51c379a

Browse files
Jaeyoung-LimRyanf55
authored andcommitted
Incrementally loading terrain from VRT server (#63)
* Add vrt parsing node * Load position and extent from VRT server * Add terrain loader node * Use gdal transforms * Remove geoconversion library * Update readme
1 parent 0778982 commit 51c379a

File tree

7 files changed

+432
-0
lines changed

7 files changed

+432
-0
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,12 @@ source install/setup.bash
7272
ros2 launch grid_map_geo load_tif_launch.xml
7373
```
7474

75+
76+
## Loading teerrain from a VRT server
77+
78+
One can load a DEM from a terrain server directly.
79+
```
80+
roslaunch grid_map_geo run_terrain_loader.launch
81+
```
82+
83+
![terrain-loader](https://github.com/ethz-asl/grid_map_geo/assets/5248102/e93b2c86-c26a-477c-8704-dc0233b7ef2e)

grid_map_geo/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ target_link_libraries(test_tif_loader PUBLIC
5959
${PROJECT_NAME}
6060
)
6161

62+
add_executable(terrain_loader
63+
src/terrain_loader.cpp
64+
)
65+
66+
target_link_libraries(terrain_loader PUBLIC
67+
${PROJECT_NAME}
68+
)
69+
6270
# Fix for yaml_cpp not resolving correctly on macOS
6371
# https://github.com/ethz-asl/grid_map_geo/pull/59#discussion_r1474669370
6472
if (APPLE)

grid_map_geo/include/grid_map_geo/grid_map_geo.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,8 @@ class GridMapGeo {
117117
*/
118118
bool initializeFromGeotiff(const std::string& path);
119119

120+
bool initializeFromVrt(const std::string& path, const Eigen::Vector2d& map_center, Eigen::Vector2d& extent);
121+
120122
/**
121123
* @brief Load a color layer from a geotiff file (orthomosaic)
122124
*
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<launch>
2+
<arg name="visualization" default="true"/>
3+
<arg name="location" default="hinwil"/>
4+
5+
<node pkg="grid_map_geo" type="terrain_loader" name="terrain_loader" output="screen">
6+
<!-- <param name="terrain_path" value="$(find terrain_models)/models/$(arg location).tif"/> -->
7+
<param name="terrain_path" value="/vsizip/vsicurl/https://terrain.ardupilot.org/SRTM1/ap_srtm1.zip/ap_srtm1.vrt"/>
8+
</node>
9+
10+
<group if="$(arg visualization)">
11+
<node type="rviz" name="rviz" pkg="rviz" args="-d $(find grid_map_geo)/launch/terrain_loader.rviz" output="screen"/>
12+
</group>
13+
</launch>
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
Panels:
2+
- Class: rviz/Displays
3+
Help Height: 78
4+
Name: Displays
5+
Property Tree Widget:
6+
Expanded:
7+
- /Global Options1
8+
- /Grid1
9+
- /GridMap1
10+
Splitter Ratio: 0.5
11+
Tree Height: 850
12+
- Class: rviz/Selection
13+
Name: Selection
14+
- Class: rviz/Tool Properties
15+
Expanded:
16+
- /2D Pose Estimate1
17+
- /2D Nav Goal1
18+
- /Publish Point1
19+
Name: Tool Properties
20+
Splitter Ratio: 0.5886790156364441
21+
- Class: rviz/Views
22+
Expanded:
23+
- /Current View1
24+
Name: Views
25+
Splitter Ratio: 0.5
26+
- Class: rviz/Time
27+
Name: Time
28+
SyncMode: 0
29+
SyncSource: ""
30+
- Class: rviz_plugin_tutorials/Teleop
31+
Name: Teleop
32+
Topic: ""
33+
- Class: mav_planning_rviz/PlanningPanel
34+
Name: PlanningPanel
35+
namespace: ""
36+
odometry_topic: ""
37+
planner_name: sertig
38+
planning_budget: 4
39+
Preferences:
40+
PromptSaveOnExit: true
41+
Toolbars:
42+
toolButtonStyle: 2
43+
Visualization Manager:
44+
Class: ""
45+
Displays:
46+
- Alpha: 0.5
47+
Cell Size: 1000
48+
Class: rviz/Grid
49+
Color: 160; 160; 164
50+
Enabled: true
51+
Line Style:
52+
Line Width: 0.029999999329447746
53+
Value: Lines
54+
Name: Grid
55+
Normal Cell Count: 0
56+
Offset:
57+
X: 0
58+
Y: 0
59+
Z: 0
60+
Plane: XY
61+
Plane Cell Count: 10
62+
Reference Frame: map
63+
Value: true
64+
- Alpha: 0.25
65+
Autocompute Intensity Bounds: false
66+
Class: grid_map_rviz_plugin/GridMap
67+
Color: 200; 200; 200
68+
Color Layer: elevation
69+
Color Transformer: IntensityLayer
70+
Enabled: true
71+
Height Layer: elevation
72+
Height Transformer: Layer
73+
History Length: 5
74+
Invert Rainbow: false
75+
Max Color: 255; 255; 255
76+
Max Intensity: 2200
77+
Min Color: 0; 0; 0
78+
Min Intensity: 1400
79+
Name: GridMap
80+
Show Grid Lines: false
81+
Topic: /grid_map
82+
Unreliable: false
83+
Use Rainbow: true
84+
Value: true
85+
Enabled: true
86+
Global Options:
87+
Background Color: 255; 255; 255
88+
Default Light: true
89+
Fixed Frame: map
90+
Frame Rate: 30
91+
Name: root
92+
Tools:
93+
- Class: rviz/Interact
94+
Hide Inactive Objects: true
95+
- Class: rviz/MoveCamera
96+
- Class: rviz/Select
97+
- Class: rviz/FocusCamera
98+
- Class: rviz/Measure
99+
- Class: rviz/SetInitialPose
100+
Theta std deviation: 0.2617993950843811
101+
Topic: /initialpose
102+
X std deviation: 0.5
103+
Y std deviation: 0.5
104+
- Class: rviz/SetGoal
105+
Topic: /move_base_simple/goal
106+
- Class: rviz/PublishPoint
107+
Single click: true
108+
Topic: /clicked_point
109+
Value: true
110+
Views:
111+
Current:
112+
Class: rviz/Orbit
113+
Distance: 30173.89453125
114+
Enable Stereo Rendering:
115+
Stereo Eye Separation: 0.05999999865889549
116+
Stereo Focal Distance: 1
117+
Swap Stereo Eyes: false
118+
Value: false
119+
Field of View: 0.7853981852531433
120+
Focal Point:
121+
X: 5063.75927734375
122+
Y: 2195.057373046875
123+
Z: 3253.49755859375
124+
Focal Shape Fixed Size: true
125+
Focal Shape Size: 0.05000000074505806
126+
Invert Z Axis: false
127+
Name: Current View
128+
Near Clip Distance: 0.009999999776482582
129+
Pitch: 0.639797031879425
130+
Target Frame: map
131+
Yaw: 5.113188743591309
132+
Saved: ~
133+
Window Geometry:
134+
Displays:
135+
collapsed: false
136+
Height: 1136
137+
Hide Left Dock: false
138+
Hide Right Dock: true
139+
PlanningPanel:
140+
collapsed: false
141+
QMainWindow State: 000000ff00000000fd000000040000000000000247000003dbfc020000000bfb0000001200530065006c0065006300740069006f006e00000001e10000009b0000005c00fffffffb0000001e0054006f006f006c002000500072006f007000650072007400690065007302000001ed000001df00000185000000a3fb000000120056006900650077007300200054006f006f02000001df000002110000018500000122fb000000200054006f006f006c002000500072006f0070006500720074006900650073003203000002880000011d000002210000017afb000000100044006900730070006c006100790073010000007a000003db000000c700fffffffb0000001a0050006c0061006e006e0069006e006700500061006e0065006c0000000255000000ef0000006e00fffffffb0000002000730065006c0065006300740069006f006e00200062007500660066006500720200000138000000aa0000023a00000294fb00000014005700690064006500530074006500720065006f02000000e6000000d2000003ee0000030bfb0000000c004b0069006e0065006300740200000186000001060000030c00000261fb0000000a0049006d006100670065010000020c000001b10000000000000000fb0000000c00540065006c0065006f00700000000368000000b20000004500ffffff000000010000010f000002cafc0200000003fb0000001e0054006f006f006c002000500072006f00700065007200740069006500730100000041000000780000000000000000fb0000000a00560069006500770073000000007a000002ca000000a000fffffffb0000001200530065006c0065006300740069006f006e010000025a000000b20000000000000000000000020000073800000039fc0100000002fb0000000800540069006d00650100000000000007380000030700fffffffb0000000a00560069006500770073030000004e00000080000002e10000019700000003000007800000014efc0100000001fb0000000800540069006d00650100000000000004500000000000000000000004eb000003db00000004000000040000000800000008fc0000000100000002000000010000000a0054006f006f006c00730100000000ffffffff0000000000000000
142+
Selection:
143+
collapsed: false
144+
Teleop:
145+
collapsed: false
146+
Time:
147+
collapsed: false
148+
Tool Properties:
149+
collapsed: false
150+
Views:
151+
collapsed: true
152+
Width: 1848
153+
X: 72
154+
Y: 27

grid_map_geo/src/grid_map_geo.cpp

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,102 @@ bool GridMapGeo::initializeFromGeotiff(const std::string &path) {
144144
return true;
145145
}
146146

147+
bool GridMapGeo::initializeFromVrt(const std::string &path, const Eigen::Vector2d &map_center,
148+
Eigen::Vector2d &extent) {
149+
GDALAllRegister();
150+
GDALDataset *dataset = (GDALDataset *)GDALOpen(path.c_str(), GA_ReadOnly);
151+
if (!dataset) {
152+
std::cout << "Failed to open" << std::endl;
153+
return false;
154+
}
155+
std::cout << std::endl << "Loading GeoTIFF file for gridmap" << std::endl;
156+
157+
double originX, originY, pixelSizeX, pixelSizeY;
158+
double geoTransform[6];
159+
if (dataset->GetGeoTransform(geoTransform) == CE_None) {
160+
originX = geoTransform[0];
161+
originY = geoTransform[3];
162+
pixelSizeX = geoTransform[1];
163+
pixelSizeY = geoTransform[5];
164+
} else {
165+
std::cout << "Failed read geotransform" << std::endl;
166+
return false;
167+
}
168+
169+
const char *pszProjection = dataset->GetProjectionRef();
170+
std::cout << std::endl << "Wkt ProjectionRef: " << pszProjection << std::endl;
171+
172+
const OGRSpatialReference *spatial_ref = dataset->GetSpatialRef();
173+
std::string name_coordinate = spatial_ref->GetAttrValue("geogcs");
174+
std::string epsg_code = spatial_ref->GetAttrValue("AUTHORITY", 1);
175+
// Get image metadata
176+
unsigned width = dataset->GetRasterXSize();
177+
unsigned height = dataset->GetRasterYSize();
178+
double resolution = pixelSizeX;
179+
std::cout << "Width: " << width << " Height: " << height << " Resolution: " << resolution << std::endl;
180+
181+
// pixelSizeY is negative because the origin of the image is the north-east corner and positive
182+
// Y pixel coordinates go towards the south
183+
int grid_width = extent(0) / std::abs(resolution);
184+
int grid_height = extent(1) / std::abs(resolution);
185+
const double lengthX = resolution * grid_width;
186+
const double lengthY = resolution * grid_height;
187+
grid_map::Length length(lengthX, lengthY);
188+
std::cout << "length: " << length.transpose() << std::endl;
189+
190+
maporigin_.espg = static_cast<ESPG>(std::stoi(epsg_code));
191+
maporigin_.position = map_center.head(2);
192+
193+
Eigen::Vector2d position{Eigen::Vector2d::Zero()};
194+
195+
grid_map_.setGeometry(length, resolution, position);
196+
std::cout << "position: " << position.transpose() << std::endl;
197+
/// TODO: Use TF for geocoordinates
198+
grid_map_.setFrameId(frame_id_);
199+
grid_map_.add("elevation");
200+
GDALRasterBand *elevationBand = dataset->GetRasterBand(1);
201+
202+
Eigen::Vector2d center_px((map_center(1) - geoTransform[0]) / geoTransform[1],
203+
(map_center(0) - geoTransform[3]) / geoTransform[5]);
204+
205+
const auto raster_io_x_offset = center_px.x() - grid_width / 2;
206+
const auto raster_io_y_offset = center_px.y() - grid_height / 2;
207+
std::cout << "center_px: " << center_px.transpose() << std::endl;
208+
209+
std::vector<float> data(grid_width * grid_height, 0.0f);
210+
const auto raster_err = elevationBand->RasterIO(GF_Read, raster_io_x_offset, raster_io_y_offset, grid_width,
211+
grid_height, &data[0], grid_width, grid_height, GDT_Float32, 0, 0);
212+
if (raster_err != CPLE_None) {
213+
std::cout << "Error loading raster" << std::endl;
214+
return false;
215+
}
216+
grid_map::Matrix &layer_elevation = grid_map_["elevation"];
217+
for (grid_map::GridMapIterator iterator(grid_map_); !iterator.isPastEnd(); ++iterator) {
218+
const grid_map::Index gridMapIndex = *iterator;
219+
// TODO: This may be wrong if the pixelSizeY > 0
220+
int x = grid_width - 1 - gridMapIndex(0);
221+
int y = gridMapIndex(1);
222+
223+
layer_elevation(x, y) = data[gridMapIndex(0) + grid_width * gridMapIndex(1)];
224+
}
225+
226+
static tf2_ros::StaticTransformBroadcaster static_broadcaster;
227+
geometry_msgs::TransformStamped static_transformStamped;
228+
229+
static_transformStamped.header.stamp = ros::Time::now();
230+
static_transformStamped.header.frame_id = name_coordinate;
231+
static_transformStamped.child_frame_id = frame_id_;
232+
static_transformStamped.transform.translation.x = map_center(0);
233+
static_transformStamped.transform.translation.y = map_center(1);
234+
static_transformStamped.transform.translation.z = 0.0;
235+
static_transformStamped.transform.rotation.x = 0.0;
236+
static_transformStamped.transform.rotation.y = 0.0;
237+
static_transformStamped.transform.rotation.z = 0.0;
238+
static_transformStamped.transform.rotation.w = 1.0;
239+
static_broadcaster.sendTransform(static_transformStamped);
240+
return true;
241+
}
242+
147243
bool GridMapGeo::addColorFromGeotiff(const std::string &path) {
148244
GDALAllRegister();
149245
const auto dataset = GDALDatasetUniquePtr(GDALDataset::FromHandle(GDALOpen(path.c_str(), GA_ReadOnly)));

0 commit comments

Comments
 (0)