Skip to content

🐛 Gazebo Harmonic doesn't load external DEM/TIF files (e.g., NOAA/GEBCO bathymetry) #589

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
smtbhd32 opened this issue Apr 18, 2025 · 5 comments
Labels
bug Something isn't working

Comments

@smtbhd32
Copy link

🐛 Gazebo Harmonic doesn't load external DEM/TIF files (e.g., NOAA/GEBCO bathymetry)

Environment

  • OS Version: Ubuntu 22.04
  • ROS Version: ROS 2 Humble
  • Gazebo Version: Harmonic (installed via binary packages)

Description

  • Expected behavior:
    Gazebo should be able to load any valid .tif/GeoTIFF file as a <heightmap> surface, even if the data comes from external sources like NOAA or GEBCO (bathymetry datasets).

  • Actual behavior:
    Gazebo only successfully loads the example .tif files provided in tutorials (like volcano.tif).
    When trying to load a DEM from NOAA or GEBCO (which use EPSG:4326 WGS84 projection), no errors are shown in console, but the heightmap simply does not appear in the simulation.

Steps to reproduce

  1. Download bathymetry data (e.g., GEBCO 2023 dataset) as .tif (EPSG:4326).
  2. Create a Gazebo world using this .tif file as <heightmap>.
  3. Launch the world with gz sim your_world.sdf.
  4. Notice that no terrain is rendered. (But no clear error message is shown.)

Output

  • No error messages in terminal.
  • Nothing rendered in place of the heightmap.
  • Compared file properties:
    • Working file (volcano.tif):
      • CRS: EPSG:26710 (UTM Zone 10N)
      • Data type: float32
      • Well-defined pixel size and transform.
    • Non-working file (gebco.tif):
      • CRS: EPSG:4326 (WGS84)
      • Data type: int16
      • Pixel transform matrix almost zero.

✅ Driver matches (GTiff), but other properties differ (CRS, pixel size, data type).


Additional Notes

  • Possibly Gazebo expects heightmaps to be in a local projected coordinate system (like UTM) and float32 format.
  • Better documentation or internal CRS support would help users simulate real-world terrains like oceans and seabeds.
  • At minimum, Gazebo should log a warning or clear error if the DEM file cannot be interpreted properly.
@smtbhd32 smtbhd32 added the bug Something isn't working label Apr 18, 2025
@smtbhd32
Copy link
Author

@jennuine Pls check on it

@jennuine
Copy link
Contributor

Hi @smtbhd32 it's been awhile so I'll do my best to remember. If you are using bathymetry data, this data is below sea level so most likely the DEM is being loaded in Gazebo but the visual is outside of the viewport of the camera. Take a look at our example from GEBCO of Monterey Bay (model and world). If you download the model and look at the model.sdf's <pos> offset, we needed to move the model up the z axis to get the model to be visible within the camera viewport, which points to 0,0,0. If I remember correctly, I determined this by looking at the min elevation of the DEM (which was -6220) and used that value as the offset (+6220).

If you have Gazebo installed from source, you can use our gz-rendering example (which is outside of the full simulation stack) to try loading your DEM and modifying the position in these sections here. Then when you have the correct position figured out you can update the <pos> in your SDF. The instructions to build and run the gz-rendering example are listed here: gazebosim/gz-rendering#560

If this doesn't work for you, I can't promise I'll be able to look at this anytime soon but if you provide a link to the model you're trying to load either I or maybe someone in the community can take a look.

As for the documentation, we welcome PRs and would be happy to review it 😄

@smtbhd32
Copy link
Author

Thanks @jennuine ! 😄 I got it working by editing the <pose> tag as you mentioned.

I also noticed you had already mentioned this in the documentation at Gazebo DEM Tutorial:

"The <heightmap><size> element in the code above tells Gazebo whether to load the DEM with the original dimensions (when <size> is not present) or to scale it (when <size> is present). In case you prefer to scale the DEM, the <size> element tells Gazebo the size in meters that the terrain will have in the simulation. If you want to maintain the correct aspect ratio, be sure to properly calculate its size in all three dimensions. In our example, the DEM will be scaled to a square of 150 x 150 meters and a height of 50 meters. The minimum elevation for this particular DEM file is 685 meters, so in the <pose> element, we translate the entire DEM in negative z direction so that it sits at z=0 in the world."

While reading it earlier, I didn't realize how important the <pose> adjustment was for the model to actually appear in the simulation. I wasn't aware of Gazebo's camera viewport behavior either — I’ll definitely read more about it. 📖

Additionally, I got to know about the elevation details of my bathymetry DEM using the command gdalinfo -stats bathymetry.tif, which helped me determine the required z-offset. Really useful!

I have one more question: after loading the bathymetry model, I noticed that I am getting spikes or strange artifacts in the terrain. Could you please suggest some steps or best practices to avoid this? 🙏

Also, do I need to use any additional tags in the SDF like <terrain_paging> for better handling of large DEMs? Currently, I am following the setup from the volcano.world example.

I'm attaching screenshots showing the issue I'm facing along with the .tif file I am using for better context.

Thanks again for your help and for pointing me in the right direction — this feature saved me a lot of work (otherwise I was about to start writing a full converter from .tif to model.sdf)! 🚀

Image
Image

@jennuine
Copy link
Contributor

after loading the bathymetry model, I noticed that I am getting spikes or strange artifacts in the terrain.

Most likely the DEM model has holes or NODATA values. You can try using gdal or other tools like QGIS to fill in the NODATA values. There are ways to smooth the results as well.

do I need to use any additional tags in the SDF like <terrain_paging> for better handling of large DEMs?

Gazebo Harmonic uses <use_terrain_paging> and this would only help with rendering I believe. You can try setting it and seeing what your results are. You may need to delete the cached version of the model before re-launching Gazebo. It lives somewhere in your ~/.gz/ directory. See http://sdformat.org/spec?ver=1.12&elem=geometry#geometry_heightmap for the supported SDF tags. Outside of Gazebo, you can try using GDAL or QGIS to reduce the size of the DEM. From what I remember, it's all a little trial and error to see what works for your needs and your system.

FYI, The links you've pointed to and the <terrain_paging> tag uses Gazebo-classic, the content regarding DEMs outside Gazebo should be roughly the same.

@smtbhd32
Copy link
Author

Thanks @jennuine ! I tried filling the NODATA values using gdal_fillnodata.py like this:

gdal_fillnodata.py input.tif output_filled.tif

But the spikes are still there. I think it may be due to cliffs in the data, as we can see similar formations in the images. It seems like the area has actual cliffs in the bathymetry data itself. I’ll go ahead and close the issue now. Thanks a lot for your help!

@github-project-automation github-project-automation bot moved this from Inbox to Done in Core development Apr 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
Status: Done
Development

No branches or pull requests

2 participants