Skip to content
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

NASA Challenge_[@martincerven]_[New Mars & Moon Gazebo sim high fidelity worlds] #70

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions heightmap_demo/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

FROM osrf/space-ros:latest

# Install Gazebo Harmonic:
# https://gazebosim.org/docs/harmonic/install_ubuntu/#binary-installation-on-ubuntu
RUN sudo apt-get update
RUN sudo apt-get install lsb-release gnupg
RUN sudo curl https://packages.osrfoundation.org/gazebo.gpg --output /usr/share/keyrings/pkgs-osrf-archive-keyring.gpg
RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/pkgs-osrf-archive-keyring.gpg] http://packages.osrfoundation.org/gazebo/ubuntu-stable $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/gazebo-stable.list > /dev/null
RUN sudo apt-get update

# Install required packages
RUN sudo apt-get update \
&& sudo apt-get install -y --no-install-recommends \
bash \
bash-completion \
build-essential \
cmake \
git \
python-is-python3 \
python3-pip \
gz-harmonic \
&& sudo apt-get autoremove -y

# Replace old entrypoint with an entrypoint that extends upon it
# This is necessary as Gazebo Harmonic has been installed as well as some new ROS packages.
# RUN sudo mv /ros_entrypoint.sh /old_entrypoint.sh
# COPY entrypoint.sh /ros_entrypoint.sh
# RUN sudo chmod +x /ros_entrypoint.sh

# Set up workspace
RUN mkdir -p /home/spaceros-user/heightmap_demo
WORKDIR /home/spaceros-user/heightmap_demo
# Copy over the files so that we can pre-build the package with colcon
COPY heightmap_demo /home/spaceros-user/heightmap_demo
# Source ROS environment and build the package
# RUN . /opt/ros/humble/setup.sh && . ${SPACEROS_DIR}/install/setup.sh && colcon build
61 changes: 61 additions & 0 deletions heightmap_demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Heightmap demo


This demo shows how to use custom DEM data from LRO & MRO to create performant terrain with Gazebo **heightmaps**.

It was made as part of **NASA Space ROS Sim Summer Sprint Challenge** by @martincerven



## Build container:

```
cd heightmap_demo
./build.sh
```

## Run container:

```
export GZ_SIM_RESOURCE_PATH=`pwd`/models:$GZ_SIM_RESOURCE_PATH

gz sim -v 4 "apollo_16.sdf"
```


# Workflow

Digital elevation model (DEM) can be used in Gazebo as heightmaps. Example of such DEMs is data from [Lunar Reconaisance Orbiter's Apollo missions](https://wms.lroc.asu.edu/lroc/view_rdr/NAC_DTM_APOLLO16_4). DEM or DTM(Digital Terrain Model) is represented in float geotiff **.tiff** format.

Gazebo accepts data in **.png** format, therefore we need to do a few data processing steps.
First, we need to crop image to $(2^k,2^k)$ size, for example $(4096,4096)$.

For this we use free and open source tool [QGIS](https://qgis.org/).

We load downloaded geotiff and use **layer->clip by extent**.

Then we save squar tiff image.

Values of tiff images are **32-bit float** representing **elevation** and since Gazebo heightmap accepts png, we need to convert it, to **16-bit** unsigned integer.

```
gdal_translate -outsize 4096 4096 -ot UInt16 -scale <min> <max> 0 65535 <input>.tif <output>.tif
```

You can gen min,max of extent in QGIS or with following command:
```
gdalinfo <input>.tif | grep Min
```

`gdal_translate` can also output .png format, but for some reason only 8bit version works, while 16-bit is not recognized by Gazebo and throws [out of bound error](https://github.com/gazebosim/garden_demo/pull/22#issuecomment-2322324064). This is probably due to wrong .png chunk encodings.

We can circumvent this by importing .tif into FOSS image editor [Gimp](https://www.gimp.org/) which outputs correct .png file, by using **export->png->16bpc**.



## References

The idea for this demo comes from beautiful [Garden demo](https://github.com/gazebosim/garden_demo).
This demo descibes how the heightmap can be generated from publicly available data and using open source software.


23 changes: 23 additions & 0 deletions heightmap_demo/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash

ORG=openrobotics
IMAGE=heightmap_demo
TAG=latest

VCS_REF=""
VERSION=preview

# Exit script with failure if build fails
set -eo pipefail

echo ""
echo "##### Building Space ROS Demo Docker Image #####"
echo ""

docker build -t $ORG/$IMAGE:$TAG \
--build-arg VCS_REF="$VCS_REF" \
--build-arg VERSION="$VERSION" .

echo ""
echo "##### Done! #####"

6 changes: 6 additions & 0 deletions heightmap_demo/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash
set -e

# Setup the Demo environment
# source "${DEMO_DIR}/install/setup.bash"
exec "$@"
263 changes: 263 additions & 0 deletions heightmap_demo/heightmap_demo/apollo_16.sdf
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
<sdf version='1.10'>
<world name='world_demo'>
<gravity>0 0 -1.6200000000000001</gravity>
<gui fullscreen='false'>
<plugin name='3D View' filename='MinimalScene'>
<gz-gui>
<title>3D View</title>
<property type='bool' key='showTitleBar'>false</property>
<property type='string' key='state'>docked</property>
</gz-gui>
<engine>ogre2</engine>
<scene>scene</scene>
<ambient_light>0.0 0.0 0.0</ambient_light>
<background_color>0.0 0.0 0.0</background_color>
<camera_pose>-9.249 -3.787 -5.543 0 0 0 </camera_pose>
<camera_clip>
<near>0.25</near>
<far>1000000</far>
</camera_clip>
</plugin>
<plugin name='Entity context menu' filename='EntityContextMenuPlugin'>
<gz-gui>
<property key='state' type='string'>floating</property>
<property key='width' type='double'>5</property>
<property key='height' type='double'>5</property>
<property key='showTitleBar' type='bool'>false</property>
</gz-gui>
</plugin>
<plugin name='Scene Manager' filename='GzSceneManager'>
<gz-gui>
<property key='resizable' type='bool'>false</property>
<property key='width' type='double'>5</property>
<property key='height' type='double'>5</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
</gz-gui>
</plugin>
<plugin name='Interactive view control' filename='InteractiveViewControl'>
<gz-gui>
<property key='resizable' type='bool'>false</property>
<property key='width' type='double'>5</property>
<property key='height' type='double'>5</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
</gz-gui>
</plugin>
<plugin name='Camera Tracking' filename='CameraTracking'>
<gz-gui>
<property key='resizable' type='bool'>false</property>
<property key='width' type='double'>5</property>
<property key='height' type='double'>5</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
</gz-gui>
</plugin>
<plugin name='Marker manager' filename='MarkerManager'>
<gz-gui>
<property key='resizable' type='bool'>false</property>
<property key='width' type='double'>5</property>
<property key='height' type='double'>5</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
</gz-gui>
</plugin>
<plugin name='Select Entities' filename='SelectEntities'>
<gz-gui>
<anchors target='Select entities'>
<line own='right' target='right'/>
<line own='top' target='top'/>
</anchors>
<property key='resizable' type='bool'>false</property>
<property key='width' type='double'>5</property>
<property key='height' type='double'>5</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
</gz-gui>
</plugin>
<plugin name='Visualization Capabilities' filename='VisualizationCapabilities'>
<gz-gui>
<property key='resizable' type='bool'>false</property>
<property key='width' type='double'>5</property>
<property key='height' type='double'>5</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
</gz-gui>
</plugin>
<plugin name='Spawn Entities' filename='Spawn'>
<gz-gui>
<anchors target='Select entities'>
<line own='right' target='right'/>
<line own='top' target='top'/>
</anchors>
<property key='resizable' type='bool'>false</property>
<property key='width' type='double'>5</property>
<property key='height' type='double'>5</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
</gz-gui>
</plugin>
<plugin name='World control' filename='WorldControl'>
<gz-gui>
<title>World control</title>
<property type='bool' key='showTitleBar'>false</property>
<property type='bool' key='resizable'>false</property>
<property type='double' key='height'>72</property>
<property type='double' key='width'>121</property>
<property type='double' key='z'>1</property>
<property type='string' key='state'>floating</property>
<anchors target='3D View'>
<line own='left' target='left'/>
<line own='bottom' target='bottom'/>
</anchors>
</gz-gui>
<play_pause>true</play_pause>
<step>true</step>
<start_paused>true</start_paused>
<use_event>true</use_event>
</plugin>
<plugin name='World stats' filename='WorldStats'>
<gz-gui>
<title>World stats</title>
<property type='bool' key='showTitleBar'>false</property>
<property type='bool' key='resizable'>false</property>
<property type='double' key='height'>110</property>
<property type='double' key='width'>290</property>
<property type='double' key='z'>1</property>
<property type='string' key='state'>floating</property>
<anchors target='3D View'>
<line own='right' target='right'/>
<line own='bottom' target='bottom'/>
</anchors>
</gz-gui>
<sim_time>true</sim_time>
<real_time>true</real_time>
<real_time_factor>true</real_time_factor>
<iterations>true</iterations>
</plugin>
<plugin name='Shapes' filename='Shapes'>
<gz-gui>
<property key='resizable' type='bool'>false</property>
<property key='x' type='double'>0</property>
<property key='y' type='double'>0</property>
<property key='width' type='double'>250</property>
<property key='height' type='double'>50</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
<property key='cardBackground' type='string'>#666666</property>
</gz-gui>
</plugin>
<plugin name='Lights' filename='Lights'>
<gz-gui>
<property key='resizable' type='bool'>false</property>
<property key='x' type='double'>250</property>
<property key='y' type='double'>0</property>
<property key='width' type='double'>150</property>
<property key='height' type='double'>50</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
<property key='cardBackground' type='string'>#666666</property>
</gz-gui>
</plugin>
<plugin name='Transform control' filename='TransformControl'>
<gz-gui>
<property key='resizable' type='bool'>false</property>
<property key='x' type='double'>0</property>
<property key='y' type='double'>50</property>
<property key='width' type='double'>250</property>
<property key='height' type='double'>50</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
<property key='cardBackground' type='string'>#777777</property>
</gz-gui>
</plugin>
<plugin name='Screenshot' filename='Screenshot'>
<gz-gui>
<property key='resizable' type='bool'>false</property>
<property key='x' type='double'>250</property>
<property key='y' type='double'>50</property>
<property key='width' type='double'>50</property>
<property key='height' type='double'>50</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
<property key='cardBackground' type='string'>#777777</property>
</gz-gui>
</plugin>
<plugin name='VideoRecorder' filename='VideoRecorder'>
<gz-gui>
<property key='resizable' type='bool'>false</property>
<property key='x' type='double'>300</property>
<property key='y' type='double'>50</property>
<property key='width' type='double'>50</property>
<property key='height' type='double'>50</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
<property key='cardBackground' type='string'>#777777</property>
</gz-gui>
<record_video>
<use_sim_time>true</use_sim_time>
<lockstep>true</lockstep>
<bitrate>4000000</bitrate>
</record_video>
</plugin>
<plugin name='Key publisher' filename='KeyPublisher'>
<gz-gui>
<anchors target='3D View'>
<line own='right' target='right'/>
<line own='top' target='top'/>
</anchors>
<property key='resizable' type='bool'>false</property>
<property key='width' type='double'>5</property>
<property key='height' type='double'>5</property>
<property key='state' type='string'>floating</property>
<property key='showTitleBar' type='bool'>false</property>
</gz-gui>
</plugin>
</gui>
<magnetic_field>5.5644999999999998e-06 2.2875799999999999e-05 -4.2388400000000002e-05</magnetic_field>
<atmosphere type='adiabatic'/>
<physics type='ode'>
<max_step_size>0.001</max_step_size>
<real_time_factor>1</real_time_factor>
<real_time_update_rate>1000</real_time_update_rate>
</physics>

<scene>
<ambient>0.0 0.0 0.0 0.0</ambient>
<background>0.0 0.0 0.0 1.0</background>
<grid>false</grid>
</scene>

<include>
<uri>Moon model</uri>
<name>moon_model</name>
<pose>0 0 -400 0 0 0</pose>
</include>


<include>
<uri>Gazebo flag</uri>
<name>gazebo_flag</name>
<pose>0 0 -11.80316162109375 0 0 0</pose>
</include>
<light name='sun' type='directional'>
<pose>0 0 20 -1.3 1.1005873689362983e-17 0.5</pose>
<cast_shadows>true</cast_shadows>
<intensity>2</intensity>
<direction>0 0 -1</direction>
<diffuse>0.800000012 0.800000012 0.800000012 1</diffuse>
<specular>0.00999999978 0.00999999978 0.00999999978 1</specular>
<attenuation>
<range>10</range>
<linear>1</linear>
<constant>1</constant>
<quadratic>0</quadratic>
</attenuation>
<spot>
<inner_angle>0</inner_angle>
<outer_angle>0</outer_angle>
<falloff>0</falloff>
</spot>
</light>
</world>
</sdf>
Loading
Loading