-
Notifications
You must be signed in to change notification settings - Fork 39
Environment Simulation
The software comes with a synthesized set of Gazebo worlds that the simulator can be run against:
- atacama_y1a.world: This world currently provides the best approximation to the landing site for for the europa mission. It is the only world that fully supports multi-material terrain.
- terminator.world: A world file with terrain and surface aspects that matches the Europa environment.
- terminator_workspace.world: Same environment as terminator.world but with a flat slightly tilted workspace.
- test_dem.world: Same environment as terminator.world but with a different landscape.
These example worlds are located within the ow_europa repository. Conveniently, a set of matching launch files are provided that launch the simulator along with the Europa Lander properly positioned:
- atacama_y1a.launch
- europa_terminator.launch
- europa_terminator_workspace.launch
- europa_test_dem.launch
The launch files are part of the ow_simulator/ow
package.
The lander is permanently fixed in each of these 4 worlds. The only way to adjust its position is at the start of the simulation. This can be done with the 6 pose arguments available for each of the 4 world launch files. init_x
, init_y
, and init_z
allow changing the default x, y, and z world position respectively. init_R
, init_P
, and init_Y
allow changing the default roll, pitch, and yaw relative to the world frame. Keep in mind that each world has its own set of default pose values. You can view these defaults in the launch file for each world.
OceanWATERS models the appearance of the celestial sphere. The apparent position of Jupiter, and the Sun as a function of time are represented in the environment, taking into account lightspeed delays.
To determine the location of celestial objects OceanWATERS utilizes the SPICE Toolkit, ephemerides and software developed by NASA JPL’s Navigation and Ancillary Information Facility (NAIF). For a given observer location and time, SPICE determines the position, velocity, and orientation of a given target body relative to the observer. These capabilities are also utilized for illumination and shadow modeling.
Support for determination of the positions of the sun and planetary bodies is implemented in the irg_planetary_ephemeris ROS node. A configuration file and ephemerides for the node can be found in the config and data sub-directories, respectively, of the ow_ephemeris package.
Gazebo is used to simulate illumination conditions in OceanWATERS. The simulation has three light sources:
- Direct light from the sun, implemented as a directional light and casting shadows with OGRE's implementation of Parallel Split Shadow Maps (PSSM).
- Indirect light from celestial bodies (such as Jupiter, Saturn, and stars) and sunlight reflected off terrain. Indirect light does not cast shadows as it is difficult to implement accurate shadows from area light sources with real-time graphics.
- Lander lights, implemented as typical OpenGL spotlights plus projected textures. The textures simulate the non-uniform nature of lensing on the lights. These lights do not cast shadows because, being close to the cameras, their shadows would have little impact on the final camera images. Since these lights are effectively point sources, quality shadows could be added.
We use physical units of lux, or luminous flux per unit area, as our light “intensity” values. To simulate light outside the visual spectrum, physical units of Watts per unit area would be more appropriate.
Direct illumination modeling is implemented in custom GLSL shader code. Because the sun is very far away it can be implemented as a directional light, which maps well to a single shader uniform variable called sunIntensity. The sunIntensity value is computed based on each mission site’s distance from the sun. Lander lights are modeled as “spotlights,” in computer graphics parlance. Lander lights are defined such that their cast light intensity at one meter is 1000 lux and attenuates with distance.
Sunlight reflected from large bodies, such as Jupiter and terrain at a mission site, and starlight, which is effectively emitted by the whole sky, is more difficult to simulate with real-time computer graphics than directional or point lights. Our solution is to render the environment into an irradiance environment map and use it as another light source. An irradiance environment map is essentially a blurred view of the environment stored in a cubemap. Retrieving a value from the cubemap using a surface normal provides all the light that would be scattered by that point on the surface if it were a perfect Lambertian reflector. This technique is limited in that it does not simulate specular reflections or shadows.
The point-of-view of our cubemap is just above the lander, near the lander camera. Since we have already chosen realistic light intensities and surface albedos, the values baked into this texture are an accurate representation of reflected light. We render everything in the scene except the sun and lander to create the irradiance environment map. The sun is a direct light source simulated separately, and the lander has large moving parts which would cause unrealistic changes in lighting when moved.
For the purpose of terrain interaction the terrain is always assumed to be a mostly solid material that can be processed into tailings by the grinder end-effector. When a grind is deep enough, terrain will be flattened and its appearance in that region will be altered to look like snow.
Figure 1. A segment of terrain that has been processed by the grinder and is now flat and snowy. Note that some surrounding terrain appears to be untouched; however, this is not the case. The change in terrain height must be enough for it to change appearance like this. Some terrain may be processed, but may not appear so.
The action of the grinder on the terrain is simulated by modifying the terrain's invisible collision model, which allows the scoop to pass through terrain only where the grinder has operated on. The action of the scoop on the terrain has a more visible effect as it modifies the terrain's visual model, digging a trench as it passes through.
The ability to simulate disparate materials in the surface and subsurface is available through the MaterialDistributionPlugin located in the ow_materials package. This plugin is capable of superimposing a 3D grid of voxels over the existing terrain model. Each voxel within the grid contains a blend of materials that are automatically synthesized from the terrain's albedo texture based on reference colors that can be selected by the user. Figure 2 shows how this material grid looks for atacama_y1a with 3 different materials represented.
Figure 2. Material grid generated for atacama_y1a. Blue represents water ice, green is salt, and red is Mg hydrates.
Materials are defined by the user as a yaml file that gets loaded as ROS
Parameters during simulation start-up. The default file is located at
ow_materials/config/materials.yaml
. To change available materials either this
file can be modified, or the file attribute of the load command can be changed
in ow/launch/common.launch
.
The following is a valid definition of a material taken from the
materials.yaml
file.
ICE:
density: 997 # kg/m^3
visualize_color: {r: 0, g: 0, b: 255}
Materials at present only vary by their density. This means there will be no difference in digging or grinder power consumption for operating on different materials; however, regolith particle weights will vary based on their composition.
The visualize_color
is to help view and differentiate materials in the Rviz
visualizations. When Rviz is launched, two material grid Display options
are available, but are initially unticked, they are: material_grid and
dug_points.
The material_grid visualization shows the entirety of the grid as many cubes.
The color of each cube is based on an interpolation between the
visualize_color
values of its constituent materials weighted by their relative
concentrations in that cube. So if your ice material is visualized by blue,
your salt material is visualized by green, and there is a voxel containing
about 50% ice and 50% salt, the cube representing that voxel in this
visualization will be colored teal. An example of the material_grid
visualization can be seen in Figure 2.
The dug_points visualization will display cubes, representing voxels, that
have been intersected by the path of scoop during a dig operation. Cubes will
disappear after 60 seconds of simulation time; however, pausing the simulation
will pause this countdown. The color of the cubes displayed in dug_points is
interpolated from the blended result of all of the voxel contents intersected
within that particular modification frame. So if the scoop passes through an
area of terrain with a high concentration of a material with a red
visualize_color
, you can expect the dug_points cubes to shift to red within
that area. Figure 3 shows an example of the visualization.
Figure 3. The dug_points display in Rviz following a TaskScoopLinear operation. The shape of this clustering of cubes will roughly match the shape of newly dug trench.
To generate a grid, materials defined in materials.yaml
must be mapped by name
to reference colors in a given world's model.sdf
file. Each voxel contains a
blend of the materials represented as fractions of the whole voxel volume. At
simulation start-up time, these concentrations are computed based on the
following.
- What materials are defined in
materials.yaml
, and - The closeness of a material's reference color to the pixel value directly above it in the terrain's albedo texture.
The material grid is served by the MaterialDistributionPlugin, which is a Gazebo
model plugin. For a world to have a material grid, it must contain a terrain
heightmap of relatively high resolution similar to atacama_y1a
. The <plugin>
element that defines the MaterialDistributionPlugin's parameters must appear
inside the <model>
element that defines the world's terrain. An example of the
MaterialDistributionPlugin being defined in atacama_y1a's model.sdf
file can
be seen in the following code block.
<plugin name="materials_distribution_plugin" filename="libMaterialDistributionPlugin.so">
<relative_to>base_link</relative_to>
<corner_a>1 -1 0.1</corner_a>
<corner_b>2.3 1 -0.37</corner_b>
<cell_side_length>0.0075</cell_side_length>
<materials>
<reference_color material="ICE"> 255 255 255 </reference_color>
<reference_color material="SALT"> 185 170 189 </reference_color>
<reference_color material="MG_HYDRATES"> 100 95 90 </reference_color>
</materials>
</plugin>
The optional relative_to parameter can be used to define the grid relative
to another model in the gazebo world. Since you typically want to define your
workspace relative to the lander, this will typically be base_link
. If this
parameter is not present, the material grid will be defined in the world frame.
Important Since the grid must be level relative to the heightmap, the model
frame must be level as well. If your grid is being defined relative to
base_link
for example, it's important not to give the robot a roll or pitch.
The vector values of corner_a and corner_b are opposite corner positions of a box that is aligned to the axes of whatever model frame the grid is defined in or the world frame. That axis-aligned box should intersect the terrain otherwise no voxel grid will generate. The cell_side_length defines the side length of a voxel cube, and is in meters. The reference_color entries inside the materials element define a color in or near a color in the terrain's albedo texture that should indicate a high concentration of the corresponding material. The reference_color value is an RGB-vector, whose values are float values are between 0 and 255 representing red, blue, and green levels in that order. For example, if you desire the reddish spots in the terrain to indicate a high concentration of sulfur, you could add the line.
<reference_color material="SULFUR"> 255 0 0 </reference_color>
Note that the material SULFUR
also needs to be defined in the
materials.yaml
file; otherwise, MaterialDistributionPlugin will throw an error
at simulation start-up. For a material grid to represent a distribution of
materials, a minimum of two reference_color values should be added under
materials. If only one reference_color value is added, the material grid
is ineffectual aside from enabling regolith collection that will only contain
that one type of material. Not all materials defined in materials.yaml
have to
be represented by a reference_color
, and those that are not represented will
simply not appear in the material grid that generates.
One way to specify reference colors for a new albedo texture for a world is to open the texture in your preferred image manipulation software, use the "eye-dropper" tool to select colors in the texture that you think would indicate a certain material, and use the RGB values sampled by the eye-dropper tool as the reference_color for that given material.
The material grid enables the testing of autonomy that seeks to identify
sampling sites by terrain color that can be viewed from images captured by the
lander. Autonomously selected sampling sites can then be operated on by the
grinder end-effector, and sampled by the scoop end-effector. This will result in
regolith particles collecting inside the scoop that are tagged with the material
concentrations at the site where they were sampled. To complete the sample loop,
sampled particles can be delivered into the lander's sample dock using the
TaskDeliverSample operation, and then ingested by the lander using the
DockIngestSample operation. About 3 seconds after the DockIngestSample
operation is called, and assuming sample successfully made it into the sample
dock, a message will be published on the ROS topic
/ground_truth/material_ingested
that communicates the concentration by volume
of each material contained by the ingested sample. An example of this message is
provided below, and can be seen by subscribing to the topic with
rostopic echo /ground_truth/material_ingested
.
header:
seq: 0
stamp:
secs: 1916525066
nsecs: 642499924
frame_id: ''
volume: 0.0012000000000000001
composition:
-
id: 1
name: "MG_HYDRATES"
proportion: 0.21510052680969238
-
id: 2
name: "SALT"
proportion: 0.4329657554626465
-
id: 0
name: "ICE"
proportion: 0.35193371772766113
NOTE This feature is only intended as ground truth for sampling autonomy, and does not attempt to simulate any experimental error or fault relevant to any kind of instrumentation required to determine material concentrations of a sample. The concentrations of each sample particle within the sample dock are simply added up and normalized to arrive at the result, and it should not be interpreted as instrunment data.
The values selected for atacama_y1a's material grid were optimized for performance on a moderately high-powered desktop/laptop work station.
Smaller voxels results in lower performance during dig operations. Specifically, the density of voxels in the grid scales cubic and inversely with cell_side_length. This means that relatively small decreases in this value can result in huge performance loss during dig operations.
On the other hand, the size of the box, determined by the values corner_a and corner_b, will primarily impact memory usage during runtime. It is therefore recommended to only define the material grid within the reachable workspace of the lander's robotic arm so as to minimize memory usage. This also applies to the depth of the workspace. Try to put the highest z-value just above the highest terrain feature, and the lowest z-value just below the deepest depth you wish to dig in a world.
You will know if your material grid is experience low performance if you repeatedly see messages of the following form
[ WARN]: Visual modification message was dropped! At least 12 message(s) may have been missed.
You can read more about why this message occurs in Caveats.
If multi-material terrain is simply not needed for your experiments, you can
turn off the grid without having to modify any SDF or launch files by setting
the launch argument sim_multimaterial
to false
. This argument is only
available in atacama_y1a since it is the only world that supports multi-material
terrain. Should you build your own world and launch file, you will have to
implement the flag yourself.
If mutli-material terrain is a desired feature, you can increase the value of cell_side_length. Thankfully very small increases in this value results in significant performance improvements, so it is recommended to change the value slowly and incrementally until you settle on a good balance between performance and grid resolution for your machine.