Replies: 1 comment
-
|
Thank you for posting this. Here is a summary that may help, though still under review. I'll move this post to our Discussions section for follow up. The uneven distribution and obstacle-overlap both come from how flat patches are computed on height fields, not from your sub-terrain layout. Flat patch sampling is local and constrained by the HF resolution and height thresholds, so you can easily over-sample “good” areas and still get points whose radius overlaps obstacles even if the center is nominally flat.12 Why distribution looks clusteredFlat patches are found by scanning the height field grid and checking local height differences within the patch radius; all valid “patch centers” are then subsampled to meet
If you want spatially more uniform coverage, you need an extra sampling layer on top of
For example, after getting # valid_positions: [num_rows, num_cols, num_patches, 3]
flat_points = self.valid_positions.reshape(-1, 3)
# optional: restrict to the actual useful area (remove borders, etc.)
mask = (
(flat_points[:, 0] > -35.0) & (flat_points[:, 0] < 35.0) &
(flat_points[:, 1] > -35.0) & (flat_points[:, 1] < 35.0)
)
flat_points = flat_points[mask]
# simple stratified re-sampling example
num_bins = 20
x_bins = torch.linspace(flat_points[:, 0].min(), flat_points[:, 0].max(), num_bins + 1)
y_bins = torch.linspace(flat_points[:, 1].min(), flat_points[:, 1].max(), num_bins + 1)
indices = []
for i in range(num_bins):
for j in range(num_bins):
in_cell = (
(flat_points[:, 0] >= x_bins[i]) & (flat_points[:, 0] < x_bins[i+1]) &
(flat_points[:, 1] >= y_bins[j]) & (flat_points[:, 1] < y_bins[j+1])
).nonzero(as_tuple=True)[^0]
if len(in_cell) > 0:
idx = in_cell[torch.randint(len(in_cell), (1,))]
indices.append(idx)
uniform_points = flat_points[torch.stack(indices)]Then sample robot spawn locations from Why points appear “inside” obstaclesA few details of the HF obstacles setup are important here.21
To ensure robots do not spawn on obstacles, you need either geometric or semantic filtering:
If your ground is at or near 0 and obstacles at 10, use flat_patch_sampling={
"target": FlatPatchSamplingCfg(
num_patches=20000,
patch_radius=0.8,
max_height_diff=0.0,
z_range=(-0.2, 0.5), # adapt to your ground noise
)
}The
If the obstacle field only occupies part of the map, you can also add FlatPatchSamplingCfg(
num_patches=20000,
patch_radius=0.8,
max_height_diff=0.0,
x_range=(-35.0, 35.0),
y_range=(-35.0, 35.0),
z_range=(-0.2, 0.5),
)
If you know the obstacle geometry (e.g., you also have the HF or obstacle masks), compute the shortest distance from each candidate patch center to obstacle cells and discard any below a margin: # flat_points: [N, 3]
# obs_mask: [Hx, Hy] boolean mask where True = obstacle cell
# obs_points: coordinates of obstacle cells
# then:
dists = torch.cdist(flat_points[:, :2], obs_points[:, :2])
min_dists, _ = dists.min(dim=1)
safe_mask = min_dists >= (patch_radius + safety_margin)
safe_points = flat_points[safe_mask]This guarantees that your robots will not overlap obstacles even if the HF flatness checker allows some centers near edges. Footnotes |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
I am using flat_patch_sampling to collect obstacle-free points as initial positions for my robots. However, when visualizing these points in yellow, I found that their distribution across the map is extremely uneven—some areas contain a large number of points, while others have very few. This uneven distribution undermines my goal of having robots spawn randomly and uniformly across the terrain. Since I am using only a single sub-terrain, I am not sure what is causing the issue. Below is the code I used to generate the terrain:
And I also set patch_radius = 0.8, but some sampled points still appear inside obstacles. From the visualization, you can clearly see yellow points located on top of obstacles. I tried adjusting this value to 0.9, 1.0, and so on, but none of these settings solved the issue. Unfortunately, I am unable to inspect the internal implementation of the flat_patch_sampling function to understand how its sampling logic works. This problem has been troubling me for quite a while. Any help or insight would be greatly appreciated!
Beta Was this translation helpful? Give feedback.
All reactions