Skip to content

Commit c7fd163

Browse files
j3soonisaaclab-bot[bot]
authored andcommitted
Fix star terrain crash on NumPy 2 (#6910)
# Description `star_terrain` computed the bar lengths with `np.math.cos` and `np.math.sin`. `np.math` was an alias for the standard library `math` module; it was deprecated in NumPy 1.25 and removed in NumPy 2.0. Since Isaac Lab 3.0 ships NumPy 2, any terrain configuration containing the star sub-terrain raised `AttributeError: module 'numpy' has no attribute 'math'`, making `MeshStarTerrainCfg` unusable. Use the standard library `math` module instead. The alias was the same module object, so the generated geometry is unchanged. The regression went unnoticed because `ROUGH_TERRAINS_CFG`, the only config covered by the terrain generator tests, has no star sub-terrain. Add a test that generates a star-only terrain, with a bar count that exercises all three branches of the bar-length computation. > Note: The testcase is written by Claude. I've confirmed the code fix myself. Fixes #6909 <!-- As a practice, it is recommended to open an issue to have discussions on the proposed pull request. This makes it easier for the community to keep track of what is being developed or added, and if a given feature is demanded by more than one party. --> ## Type of change <!-- As you go through the list, delete the ones that are not applicable. --> - Bug fix (non-breaking change which fixes an issue) ## Release backport - [x] <!-- backport-active-release --> Backport this pull request to the active release branch after it merges into `develop` ## Checklist - [x] I have read and understood the [contribution guidelines](https://isaac-sim.github.io/IsaacLab/main/source/refs/contributing.html) - [ ] I have run the [`pre-commit` checks](https://pre-commit.com/) with `./isaaclab.sh --format` - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [x] I have added tests that prove my fix is effective or that my feature works - [x] I have added a changelog fragment under `source/<pkg>/changelog.d/` for every touched package (do **not** edit `CHANGELOG.rst` or bump `extension.toml` — CI handles that) - [ ] I have added my name to the `CONTRIBUTORS.md` or my name already exists there <!-- As you go through the checklist above, you can mark something as done by putting an x character in it For example, - [x] I have done this task - [ ] I have not done this task --> Co-authored-by: ooctipus <zhengyuz@nvidia.com> (cherry picked from commit b44ea65)
1 parent 6cfcb1d commit c7fd163

3 files changed

Lines changed: 47 additions & 4 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Fixed
2+
^^^^^
3+
4+
* Fixed :func:`~isaaclab.terrains.trimesh.mesh_terrains.star_terrain` failing with
5+
``AttributeError: module 'numpy' has no attribute 'math'``. The function used the ``np.math``
6+
alias, which was removed in NumPy 2.0, and now uses the standard library ``math`` module instead.

source/isaaclab/isaaclab/terrains/trimesh/mesh_terrains.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from __future__ import annotations
99

10+
import math
1011
from typing import TYPE_CHECKING
1112

1213
import numpy as np
@@ -694,11 +695,11 @@ def star_terrain(
694695
# length changes since the bar is connected to a square border
695696
bar_length = cfg.size[0]
696697
if yaw < 0.25 * np.pi:
697-
bar_length /= np.math.cos(yaw)
698+
bar_length /= math.cos(yaw)
698699
elif yaw < 0.75 * np.pi:
699-
bar_length /= np.math.sin(yaw)
700+
bar_length /= math.sin(yaw)
700701
else:
701-
bar_length /= np.math.cos(np.pi - yaw)
702+
bar_length /= math.cos(np.pi - yaw)
702703
# compute the transform of the bar
703704
transform[0:3, 0:3] = tf.Rotation.from_euler("z", yaw).as_matrix()
704705
# add the bar to the mesh

source/isaaclab/test/terrains/test_terrain_generator.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import pytest
1111
import torch
1212

13-
from isaaclab.terrains import FlatPatchSamplingCfg, TerrainGenerator, TerrainGeneratorCfg
13+
from isaaclab.terrains import FlatPatchSamplingCfg, MeshStarTerrainCfg, TerrainGenerator, TerrainGeneratorCfg
1414
from isaaclab.terrains.config.rough import ROUGH_TERRAINS_CFG
1515
from isaaclab.utils.seed import configure_seed
1616

@@ -49,6 +49,42 @@ def test_generation(output_dir):
4949
assert actualSize[1] == pytest.approx(expectedSizeY)
5050

5151

52+
def test_generation_star_terrain():
53+
"""Generates a star sub-terrain and tests that the resulting mesh has the expected size.
54+
55+
The star sub-terrain is not part of :obj:`ROUGH_TERRAINS_CFG`, so it needs its own coverage.
56+
"""
57+
# create terrain generator with only the star sub-terrain
58+
cfg = TerrainGeneratorCfg(
59+
seed=0,
60+
size=(8.0, 8.0),
61+
num_rows=1,
62+
num_cols=1,
63+
use_cache=False,
64+
sub_terrains={
65+
# the number of bars is chosen so that all the branches of the bar-length computation are covered
66+
"star": MeshStarTerrainCfg(
67+
proportion=1.0,
68+
platform_width=1.5,
69+
num_bars=5,
70+
bar_width_range=(0.5, 1.0),
71+
bar_height_range=(0.05, 0.2),
72+
)
73+
},
74+
)
75+
terrain_generator = TerrainGenerator(cfg=cfg)
76+
77+
# get size from mesh bounds
78+
bounds = terrain_generator.terrain_mesh.bounds
79+
actual_size = abs(bounds[1] - bounds[0])
80+
81+
# check if the size is as expected
82+
assert actual_size[0] == pytest.approx(cfg.size[0] * cfg.num_rows + 2 * cfg.border_width)
83+
assert actual_size[1] == pytest.approx(cfg.size[1] * cfg.num_cols + 2 * cfg.border_width)
84+
# check the sub-terrain origin is at the center of the terrain
85+
assert terrain_generator.terrain_origins.shape == (cfg.num_rows, cfg.num_cols, 3)
86+
87+
5288
@pytest.mark.parametrize("use_global_seed", [True, False])
5389
@pytest.mark.parametrize("seed", [20, 40, 80])
5490
def test_generation_reproducibility(use_global_seed, seed):

0 commit comments

Comments
 (0)