Commit e787e9bf authored by Kyle Morgenstein's avatar Kyle Morgenstein Committed by Mayank Mittal

Supports setting the ground plane color using the terrain importer (#1791)

The default plane configuration supports setting the plane color, but
this option is not currently exposed via the terrain importer. This PR
adds a ``color'' field to the terrain importer that is only used for
configuring a plane.

- New feature (non-breaking change which adds functionality)

<img width="912" alt="image"
src="https://github.com/user-attachments/assets/4e509270-a953-49e8-88e7-b67bc1a92d2c"
/>

<img width="909" alt="image"
src="https://github.com/user-attachments/assets/0aa77530-befe-4c30-991d-e668561b9793"
/>

Configuration:

```python
terrain = TerrainImporterCfg(
            prim_path="/World/ground",
            terrain_type="plane",
            terrain_generator=None,
            max_init_terrain_level=None,
            collision_group=-1,
            physics_material=sim_utils.RigidBodyMaterialCfg(
                friction_combine_mode="multiply",
                restitution_combine_mode="multiply",
                static_friction=1.0,
                dynamic_friction=1.0,
            ),
            color=(1.0, 0.0, 0.0), # Red
            debug_vis=False,
        )
```

- [ ] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [ ] I have made corresponding changes to the documentation
- [X] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [X] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------
Signed-off-by: 's avatarKyle Morgenstein <34984693+KyleM73@users.noreply.github.com>
Signed-off-by: 's avatarMayank Mittal <12863862+Mayankm96@users.noreply.github.com>
Co-authored-by: 's avatarMayank Mittal <12863862+Mayankm96@users.noreply.github.com>
parent ae6c5f6c
...@@ -10,6 +10,7 @@ import torch ...@@ -10,6 +10,7 @@ import torch
import trimesh import trimesh
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
import omni.log
import warp import warp
from pxr import UsdGeom from pxr import UsdGeom
...@@ -196,9 +197,21 @@ class TerrainImporter: ...@@ -196,9 +197,21 @@ class TerrainImporter:
# create a warp mesh # create a warp mesh
device = "cuda" if "cuda" in self.device else "cpu" device = "cuda" if "cuda" in self.device else "cpu"
self.warp_meshes[key] = convert_to_warp_mesh(mesh.vertices, mesh.faces, device=device) self.warp_meshes[key] = convert_to_warp_mesh(mesh.vertices, mesh.faces, device=device)
# obtain ground plane color from the configured visual material
color = (0.0, 0.0, 0.0)
if self.cfg.visual_material is not None:
material = self.cfg.visual_material.to_dict()
# defaults to the `GroundPlaneCfg` color if diffuse color attribute is not found
if "diffuse_color" in material:
color = material["diffuse_color"]
else:
omni.log.warn(
"Visual material specified for ground plane but no diffuse color found."
" Using default color: (0.0, 0.0, 0.0)"
)
# get the mesh # get the mesh
ground_plane_cfg = sim_utils.GroundPlaneCfg(physics_material=self.cfg.physics_material, size=size) ground_plane_cfg = sim_utils.GroundPlaneCfg(physics_material=self.cfg.physics_material, size=size, color=color)
ground_plane_cfg.func(self.cfg.prim_path, ground_plane_cfg) ground_plane_cfg.func(self.cfg.prim_path, ground_plane_cfg)
def import_mesh(self, key: str, mesh: trimesh.Trimesh): def import_mesh(self, key: str, mesh: trimesh.Trimesh):
......
...@@ -65,7 +65,7 @@ class TerrainImporterCfg: ...@@ -65,7 +65,7 @@ class TerrainImporterCfg:
"""The spacing between environment origins when defined in a grid. Defaults to None. """The spacing between environment origins when defined in a grid. Defaults to None.
Note: Note:
This parameter is used only when the ``terrain_type`` is ``"plane"`` or ``"usd"``. This parameter is used only when the ``terrain_type`` is "plane" or "usd".
""" """
visual_material: sim_utils.VisualMaterialCfg | None = sim_utils.PreviewSurfaceCfg( visual_material: sim_utils.VisualMaterialCfg | None = sim_utils.PreviewSurfaceCfg(
...@@ -73,10 +73,12 @@ class TerrainImporterCfg: ...@@ -73,10 +73,12 @@ class TerrainImporterCfg:
) )
"""The visual material of the terrain. Defaults to a dark gray color material. """The visual material of the terrain. Defaults to a dark gray color material.
The material is created at the path: ``{prim_path}/visualMaterial``. If `None`, then no material is created. This parameter is used for both the "generator" and "plane" terrains.
.. note:: - If the ``terrain_type`` is "generator", then the material is created at the path
This parameter is used only when the ``terrain_type`` is ``"generator"``. ``{prim_path}/visualMaterial`` and applied to all the sub-terrains.
- If the ``terrain_type`` is "plane", then the diffuse color of the material is set to
to the grid color of the imported ground plane.
""" """
physics_material: sim_utils.RigidBodyMaterialCfg = sim_utils.RigidBodyMaterialCfg() physics_material: sim_utils.RigidBodyMaterialCfg = sim_utils.RigidBodyMaterialCfg()
...@@ -85,7 +87,7 @@ class TerrainImporterCfg: ...@@ -85,7 +87,7 @@ class TerrainImporterCfg:
The material is created at the path: ``{prim_path}/physicsMaterial``. The material is created at the path: ``{prim_path}/physicsMaterial``.
.. note:: .. note::
This parameter is used only when the ``terrain_type`` is ``"generator"`` or ``"plane"``. This parameter is used only when the ``terrain_type`` is "generator" or "plane".
""" """
max_init_terrain_level: int | None = None max_init_terrain_level: int | None = None
......
...@@ -26,7 +26,7 @@ from isaacsim.core.prims import RigidPrim, SingleGeometryPrim, SingleRigidPrim ...@@ -26,7 +26,7 @@ from isaacsim.core.prims import RigidPrim, SingleGeometryPrim, SingleRigidPrim
from isaacsim.core.utils.extensions import enable_extension from isaacsim.core.utils.extensions import enable_extension
import isaaclab.terrains as terrain_gen import isaaclab.terrains as terrain_gen
from isaaclab.sim import SimulationContext, build_simulation_context from isaaclab.sim import PreviewSurfaceCfg, SimulationContext, build_simulation_context
from isaaclab.terrains import TerrainImporter, TerrainImporterCfg from isaaclab.terrains import TerrainImporter, TerrainImporterCfg
from isaaclab.terrains.config.rough import ROUGH_TERRAINS_CFG from isaaclab.terrains.config.rough import ROUGH_TERRAINS_CFG
from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR from isaaclab.utils.assets import ISAAC_NUCLEUS_DIR
...@@ -101,18 +101,22 @@ class TestTerrainImporter(unittest.TestCase): ...@@ -101,18 +101,22 @@ class TestTerrainImporter(unittest.TestCase):
def test_plane(self) -> None: def test_plane(self) -> None:
"""Generates a plane and tests that the resulting mesh has the correct size.""" """Generates a plane and tests that the resulting mesh has the correct size."""
for device in ("cuda:0", "cpu"): for device in ("cuda:0", "cpu"):
for use_custom_material in [True, False]:
with build_simulation_context(device=device, auto_add_lighting=True) as sim: with build_simulation_context(device=device, auto_add_lighting=True) as sim:
sim._app_control_on_stop_handle = None sim._app_control_on_stop_handle = None
expectedSizeX = 2.0e6 expectedSizeX = 2.0e6
expectedSizeY = 2.0e6 expectedSizeY = 2.0e6
# create custom material
visual_material = PreviewSurfaceCfg(diffuse_color=(1.0, 0.0, 0.0)) if use_custom_material else None
# Handler for terrains importing # Handler for terrains importing
terrain_importer_cfg = terrain_gen.TerrainImporterCfg( terrain_importer_cfg = terrain_gen.TerrainImporterCfg(
prim_path="/World/ground", prim_path="/World/ground",
terrain_type="plane", terrain_type="plane",
num_envs=1, num_envs=1,
env_spacing=1.0, env_spacing=1.0,
visual_material=visual_material,
) )
terrain_importer = TerrainImporter(terrain_importer_cfg) terrain_importer = TerrainImporter(terrain_importer_cfg)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment