diff --git a/tutorials.md.in b/tutorials.md.in index 3f6a1c0b31..9cf55bdfbd 100644 --- a/tutorials.md.in +++ b/tutorials.md.in @@ -89,6 +89,7 @@ If you are an absolute beginner, start with the Tutorials section. * \subpage collada_world_exporter "Collada World Exporter": Export an entire world to a single Collada mesh. * \subpage meshtofuel "Importing a Mesh to Fuel": Build a model directory around a mesh so it can be added to the Gazebo Fuel app. * \subpage pointcloud "Converting a Point Cloud to a 3D Model": Turn point cloud data into 3D models for use in simulations. +* \subpage heightmap_dem "Terrain simulation": Load image heightmaps and Digital Elevation Models (DEM) ### Blender help diff --git a/tutorials/digital_elevation_models.md b/tutorials/digital_elevation_models.md new file mode 100644 index 0000000000..692bb495a0 --- /dev/null +++ b/tutorials/digital_elevation_models.md @@ -0,0 +1,192 @@ +\page heightmap_dem Load image heightmaps and Digital Elevation Models (DEM) + +# Overview + +## What are heightmaps and why are they useful for simulation? + +Simply put, a heightmap is common term used in computer graphics to refer to a 2D image where the value of each pixel or cell corresponds to the elevation or height of that specific point in the real world. + +![Visual example of grid of elevations](files/digital_elevation_models/ex_of_grid_of_elevations.png) + +Image reference: https://www.futurelearn.com/info/courses/advanced-archaeological-remote-sensing/0/steps/356833 + +They are useful for simulation because they offer a simple way to provide realistic digital representation of the terrain. +For fields like robotics, accurate topography can be beneficial for develop algorithms and/or models for autonomous navigation, motion planning, task planning, and control because they can provide cost effective, rapid development cycles. +Engineers can develop and test algorithms in these environments before physical deployment. + +In this tutorial we'll dive deeper into what makes heightmaps, where to get them, and how to process them to use for simulation in Gazebo. + +## Gazebo's supported heightmap types + +Gazebo supports creating a terrain from image heightmaps, meshes, and Digital Elevation Models (DEMs). +While this tutorial will be focusing more in depth with DEMs, we will provide a quick overview of the other formats available to try out. + +### Image heightmaps + +Image heightmaps use a 2D grayscale image, where each pixel corresponds to the elevation at that point. Black (or `0`) represents the lowest point and while (or `255`) represents the highest. +This is a simple and efficient way to store elevation data because it can use less memory compared to meshes and DEMs. + +The following example will look at the [demo created for Gazebo Fortress](https://app.gazebosim.org/OpenRobotics/fuel/models/Fortress%20heightmap). Below shows the black and white image is what gets referenced in SDF and fed into Gazebo (download the model from the previous link and look at the `model.sdf` file). + +![Example of image heightmap](files/digital_elevation_models/fortress_heightmap.png) + +What ends up getting rendered in Gazebo is shown below: + +![Image heightmap in Gazebo](files/digital_elevation_models/fortress_heightmap_in_gazebo.jpg) + +![Another image heightmap in Gazebo](files/digital_elevation_models/fortress_heightmap_in_gazebo2.jpg) + +### Meshes + +Another format used for realistic topography are meshes, which are 3D polygonal models. +The supported file formats for meshes in Gazebo include DAE, GLTF, OBJ, and STL, and more. These models are best suited for worlds with tunnels, caves, or overhangs. + +Examples: + +\image html files/digital_elevation_models/mesh_tunnel_entrance.png width=80% + +\image html files/digital_elevation_models/mesh_cave.png width=80% + +Meshes were the format used for the [DARPA Subterranean Challenge (SubT) simulation](https://github.com/osrf/subt/wiki) +and most were created from point cloud converted data (check out this [tutorial on how to convert point cloud data to a 3D mesh model for Gazebo](http://gazebosim.org/api/sim/10/pointcloud.html)). +These heightmap meshes can be found [here on Fuel](https://app.gazebosim.org/OpenRobotics/fuel/collections/SubT%20Tech%20Repo). + +### Digital Elevation Models + +A Digital Elevation Model (DEM) is a 3D representation of a terrain's surface that does not include any objects like buildings or vegetation. +DEMs are frequently created by using a combination of sensors, such as satellites, LIDAR, radar, or cameras. +The terrain elevations for ground positions are sampled at regularly-spaced horizontal intervals. + +\image html files/digital_elevation_models/dem_monterey_bay.png width=80% + + +# Walkthrough with DEMs for Gazebo + +There are two main types of DEM formats, a vector-based Triangular Irregular Network (TIN) or a grid of elevations (raster). +In Gazebo, raster based formats (more specifically GeoTiff or `.tif` files) are the most tested formats but in theory Gazebo should be able to run any [GDAL](https://gdal.org/en/stable/index.html) default supported format +(since GDAL is the backend library that Gazebo uses to read DEM files). +Let's look at an example of getting DEMs from publicly available data and using some common open source tools to process them for Gazebo. + +## Obtaining data + +Many resources for publicly available data exist and include: + +* [OpenTopography](https://portal.opentopography.org/datasets) +* [earthexplorer.usgs.gov](http://earthexplorer.usgs.gov) +* [NASA's EarthData](https://www.earthdata.nasa.gov/topics/land-surface/digital-elevation-terrain-model-dem/data-access-tools) +* [General Bathymetric Chart of the Oceans (GEBCO) data](https://www.gebco.net/) +* [Other planetary DEMs (e.g., Moon or Mars)](https://astrogeology.usgs.gov/search?target=&system=&p=1&accscope=&searchBar=) + +For our example, we will use [OpenTopography](https://portal.opentopography.org/datasets), +* Create an account if not done so already +* Look for your area of interest, in this example, in the "Search by keyword" textbox enter `half dome` +* In the results section, under "High Resolution Topography" click "Get Raster Data" +* In the following page, + + * In the map, click the blue "Select a Region" button in the top left corner of the map to select the region to extract the DEM from + \image html files/digital_elevation_models/open_topography_region_selection.png width=80% + + * The data output format should be GeoTiff and Digital Terrain Model (DTM) should be checked for Layer types + * Click Submit + +* Once the data has finished processing, download the bundled results and unzip the file + +## Processing data + +Common open source tools for geospatial data include: + +* [Geospatial Data Abstraction Library (GDAL)](https://gdal.org/en/stable/): is a library and command line toolkit for reading and maipulating DEMs. +This is the library that is used in Gazebo for reading DEMs and will be installed on your system if Gazebo is installed. +* [QGIS](https://qgis.org/): a GUI for viewing, analyzing, editing, and publishing DEMs and relies on GDAL. + +Using [QGIS](https://qgis.org/), + +* (optional) When working with earth DEMs, it can be helpful to add a map layer (as the base layer) to verify the imported DEM is in the correct projection. + + * In the top toolbar, go to Layer > Add Layer > Add XYZ Layer... + * In the dropdown menu under "XYZ Connections", select 'Google Satellite' or 'OpenStreetMap' > Click 'Add' > then 'Close' + +* In the top toolbar, go to Layer > Add Layer > Add Raster Layer... +* Select the file that we downloaded and unzipped (from the instructions above) > Click 'Add' > then 'Close' +* Check the Coordinate Reference System button at the bottom right to make sure it is set to 'EPSG:4326'. If not click on it and search for 'EPSG:4326', choose 'WGS 84 - SPSG:4326' and click 'OK' +* Enter the lat/lon coordinates retrieved from USGS earlier in the "Coordinate" textbox at the bottom (i.e., `37.7444, -119.5341`) > hit the Enter key (this will move the viewpoint to the desired location) +* In the bottom bar, update "Scale" to `1:50000` + + * If the optional step was followed, QGIS should look something like the image below, otherwise only the DEM will be displayed + +\image html files/digital_elevation_models/qgis_satellite_and_dem.png width=80% + + +* If the Processing Toolbox panel isn't open, click the gear icon in the top toolbar + + * Search for "Clip raster by extent" and double click to open the dialog + * Input layer: should be the imported GeoTiff + * Clipping extent: click the down arrow and select "Draw on Map Canvas" to select your desired region + + \image html files/digital_elevation_models/qgis_draw_on_map_canvas.png width=80% + + * Clipped (extent): Click the button with the "..." dots > Save to File ... > select the desired save location and give the file a name + * Click the "Run" button, this will add a new layer to the layers panel (on the left) + +## SDF setup + +Now let's set up the SDF model, in a terminal run: `gdalinfo -stats ` + +Look for the output: `Size is ` + +This is the `x` and `y` values that need to be entered in the `` tag. To calculate z, subtract the `Minimum` from the `Maximum` elevation (i.e., `z = Maximum - Minimum`). + +Optionally, to move the model down to Gazebo's camera default viewpoint, update the `z` of the `` tag to be the negative of the `Maximum` elevation (i.e., `0 0 -Maximum`). Note when using seabed data (e.g., GEBCO), negate the `Minimum` instead. + +The model should look similar to the following: + +```xml + + true + + + + + half_dome.tif + + 3793 3563 1481.398 + 0 0 -2694.987 + + + + + + + + textures/rocks_diffuse.png + textures/rocks_normal.png + 250 + + + 2 + 5 + + + 4 + 5 + + half_dome.tif + + 3793 3563 1481.398 + 0 0 -2694.987 + + + + + +``` + +To launch the completed demo yourself, [download the files here](files/digital_elevation_models/half_dome_example/) then run: + +```bash +cd /path/to/half_dome_example/ + +gz sim -v 4 half_dome.sdf +``` + +\image html files/digital_elevation_models/gazebo_half_dome.png width=80% diff --git a/tutorials/files/digital_elevation_models/dem_monterey_bay.png b/tutorials/files/digital_elevation_models/dem_monterey_bay.png new file mode 100644 index 0000000000..fef40b9177 Binary files /dev/null and b/tutorials/files/digital_elevation_models/dem_monterey_bay.png differ diff --git a/tutorials/files/digital_elevation_models/ex_of_grid_of_elevations.png b/tutorials/files/digital_elevation_models/ex_of_grid_of_elevations.png new file mode 100644 index 0000000000..03d8f92240 Binary files /dev/null and b/tutorials/files/digital_elevation_models/ex_of_grid_of_elevations.png differ diff --git a/tutorials/files/digital_elevation_models/fortress_heightmap.png b/tutorials/files/digital_elevation_models/fortress_heightmap.png new file mode 100644 index 0000000000..f4281d8644 Binary files /dev/null and b/tutorials/files/digital_elevation_models/fortress_heightmap.png differ diff --git a/tutorials/files/digital_elevation_models/fortress_heightmap_in_gazebo.jpg b/tutorials/files/digital_elevation_models/fortress_heightmap_in_gazebo.jpg new file mode 100644 index 0000000000..80305251e0 Binary files /dev/null and b/tutorials/files/digital_elevation_models/fortress_heightmap_in_gazebo.jpg differ diff --git a/tutorials/files/digital_elevation_models/fortress_heightmap_in_gazebo2.jpg b/tutorials/files/digital_elevation_models/fortress_heightmap_in_gazebo2.jpg new file mode 100644 index 0000000000..9a8593c605 Binary files /dev/null and b/tutorials/files/digital_elevation_models/fortress_heightmap_in_gazebo2.jpg differ diff --git a/tutorials/files/digital_elevation_models/gazebo_half_dome.png b/tutorials/files/digital_elevation_models/gazebo_half_dome.png new file mode 100644 index 0000000000..a1e06d16b8 Binary files /dev/null and b/tutorials/files/digital_elevation_models/gazebo_half_dome.png differ diff --git a/tutorials/files/digital_elevation_models/half_dome_example/half_dome.sdf b/tutorials/files/digital_elevation_models/half_dome_example/half_dome.sdf new file mode 100644 index 0000000000..2ddf7a56cb --- /dev/null +++ b/tutorials/files/digital_elevation_models/half_dome_example/half_dome.sdf @@ -0,0 +1,332 @@ + + + + 0 0 -9.8 + + + + bullet + + + + + + + + + + + + + + + 3D View + false + docked + + + ogre2 + scene + 0.4 0.4 0.4 + 0.8 0.8 0.8 + -6 0 6 0 0.5 0 + + 0.25 + 25000 + + + + + + + floating + 5 + 5 + false + + + + + false + 5 + 5 + floating + false + + + + + false + 5 + 5 + floating + false + + + + + false + 5 + 5 + floating + false + + + + + false + 5 + 5 + floating + false + + + + + + + + + false + 5 + 5 + floating + false + + + + + false + 5 + 5 + floating + false + + + + + + + + + + false + 5 + 5 + floating + false + + + + + + + World control + false + false + 72 + 1 + + floating + + + + + + + true + true + true + true + + + + + + + World stats + false + false + 110 + 290 + 1 + + floating + + + + + + + true + true + true + true + + + + + + false + 0 + 0 + 250 + 50 + floating + false + #666666 + + + + + + + false + 250 + 0 + 150 + 50 + floating + false + #666666 + + + + + + + false + 0 + 50 + 250 + 50 + floating + false + #777777 + + + + + + + false + 250 + 50 + 50 + 50 + floating + false + #777777 + + + + + + + false + 300 + 50 + 50 + 50 + floating + false + #777777 + + + + true + false + 4000000 + + + + + + + docked_collapsed + + + + + + + docked_collapsed + + + + + + + docked_collapsed + + + + + + + true + 0 0 10 0 0 0 + 1 1 1 1 + 0.5 0.5 0.5 1 + + 1000 + 0.9 + 0.01 + 0.001 + + -0.5 0.1 -0.9 + + + + true + + + + + half_dome.tif + + 3793 3563 1481.398 + + 0 0 -2694.987 + + + + + + + + textures/rocks_diffuse.png + textures/rocks_normal.png + 250 + + + 2 + 5 + + + 4 + 5 + + half_dome.tif + + 3793 3563 1481.398 + + 0 0 -2694.987 + + + + + + + + diff --git a/tutorials/files/digital_elevation_models/half_dome_example/half_dome.tif b/tutorials/files/digital_elevation_models/half_dome_example/half_dome.tif new file mode 100644 index 0000000000..12cc46cfe5 Binary files /dev/null and b/tutorials/files/digital_elevation_models/half_dome_example/half_dome.tif differ diff --git a/tutorials/files/digital_elevation_models/half_dome_example/textures/rocks_diffuse.png b/tutorials/files/digital_elevation_models/half_dome_example/textures/rocks_diffuse.png new file mode 100644 index 0000000000..3e8e2e6d08 Binary files /dev/null and b/tutorials/files/digital_elevation_models/half_dome_example/textures/rocks_diffuse.png differ diff --git a/tutorials/files/digital_elevation_models/half_dome_example/textures/rocks_normal.png b/tutorials/files/digital_elevation_models/half_dome_example/textures/rocks_normal.png new file mode 100644 index 0000000000..35dd4405bd Binary files /dev/null and b/tutorials/files/digital_elevation_models/half_dome_example/textures/rocks_normal.png differ diff --git a/tutorials/files/digital_elevation_models/mesh_cave.png b/tutorials/files/digital_elevation_models/mesh_cave.png new file mode 100644 index 0000000000..d9c90955cd Binary files /dev/null and b/tutorials/files/digital_elevation_models/mesh_cave.png differ diff --git a/tutorials/files/digital_elevation_models/mesh_tunnel_entrance.png b/tutorials/files/digital_elevation_models/mesh_tunnel_entrance.png new file mode 100644 index 0000000000..95bdb54efc Binary files /dev/null and b/tutorials/files/digital_elevation_models/mesh_tunnel_entrance.png differ diff --git a/tutorials/files/digital_elevation_models/open_topography_region_selection.png b/tutorials/files/digital_elevation_models/open_topography_region_selection.png new file mode 100644 index 0000000000..b4a7c7213a Binary files /dev/null and b/tutorials/files/digital_elevation_models/open_topography_region_selection.png differ diff --git a/tutorials/files/digital_elevation_models/qgis_draw_on_map_canvas.png b/tutorials/files/digital_elevation_models/qgis_draw_on_map_canvas.png new file mode 100644 index 0000000000..5768b6f5f8 Binary files /dev/null and b/tutorials/files/digital_elevation_models/qgis_draw_on_map_canvas.png differ diff --git a/tutorials/files/digital_elevation_models/qgis_satellite_and_dem.png b/tutorials/files/digital_elevation_models/qgis_satellite_and_dem.png new file mode 100644 index 0000000000..4eda4ee280 Binary files /dev/null and b/tutorials/files/digital_elevation_models/qgis_satellite_and_dem.png differ