Skip to content

Commit b1f7afb

Browse files
committed
Fix map-center indexing and add regression tests
1 parent 20a8a26 commit b1f7afb

File tree

3 files changed

+54
-7
lines changed

3 files changed

+54
-7
lines changed

elevation_mapping_cupy/script/elevation_mapping_cupy/elevation_mapping.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -330,12 +330,13 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori
330330
points = points_all[:, :3]
331331
# additional_fusion = self.get_fusion_of_pcl(channels)
332332
with self.map_lock:
333-
self.shift_translation_to_map_center(t)
333+
t = t.copy()
334+
t[2] -= self.center[2]
334335
self.error_counting_kernel(
335336
self.elevation_map,
336337
points,
337-
cp.array([0.0], dtype=self.data_type),
338-
cp.array([0.0], dtype=self.data_type),
338+
self.center[:1],
339+
self.center[1:2],
339340
R,
340341
t,
341342
self.new_map,
@@ -356,8 +357,8 @@ def update_map_with_kernel(self, points_all, channels, R, t, position_noise, ori
356357
if np.abs(self.mean_error) < self.param.max_drift:
357358
self.elevation_map[0] += self.mean_error * self.param.drift_compensation_alpha
358359
self.add_points_kernel(
359-
cp.array([0.0], dtype=self.data_type),
360-
cp.array([0.0], dtype=self.data_type),
360+
self.center[:1],
361+
self.center[1:2],
361362
R,
362363
t,
363364
self.normal_map,

elevation_mapping_cupy/script/elevation_mapping_cupy/kernels/custom_kernels.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ def map_utils(
2424
return max(min(x, max_x), min_x);
2525
}
2626
__device__ int get_x_idx(float16 x, float16 center) {
27-
int i = (x - center) / ${resolution} + 0.5 * ${width};
27+
float fi = (x - center) / ${resolution} + 0.5 * (${width} - 1);
28+
int i = (int)floorf(fi + 0.5f);
2829
return i;
2930
}
3031
__device__ int get_y_idx(float16 y, float16 center) {
31-
int i = (y - center) / ${resolution} + 0.5 * ${height};
32+
float fi = (y - center) / ${resolution} + 0.5 * (${height} - 1);
33+
int i = (int)floorf(fi + 0.5f);
3234
return i;
3335
}
3436
__device__ bool is_inside(int idx) {
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import cupy as cp
2+
3+
from elevation_mapping_cupy.kernels.custom_kernels import map_utils
4+
5+
6+
def _probe_get_idx_kernel(axis: str, width: int, height: int, resolution: float):
7+
if axis not in ("x", "y"):
8+
raise ValueError(f"Unsupported axis '{axis}'. Expected 'x' or 'y'.")
9+
op = "out[i] = get_x_idx(coords[i], center[0]);" if axis == "x" else "out[i] = get_y_idx(coords[i], center[0]);"
10+
return cp.ElementwiseKernel(
11+
in_params="raw U coords, raw U center",
12+
out_params="raw int32 out",
13+
preamble=map_utils(
14+
resolution=resolution,
15+
width=width,
16+
height=height,
17+
sensor_noise_factor=0.0,
18+
min_valid_distance=0.0,
19+
max_height_range=1000.0,
20+
ramped_height_range_a=0.0,
21+
ramped_height_range_b=0.0,
22+
ramped_height_range_c=1000.0,
23+
),
24+
operation=op,
25+
name=f"probe_get_{axis}_idx_kernel",
26+
)
27+
28+
29+
def test_get_x_idx_rounds_left_of_boundary_before_clamp():
30+
kernel = _probe_get_idx_kernel(axis="x", width=200, height=200, resolution=1.0)
31+
coords = cp.asarray([-100.2], dtype=cp.float32)
32+
center = cp.asarray([0.0], dtype=cp.float32)
33+
out = cp.zeros((1,), dtype=cp.int32)
34+
kernel(coords, center, out, size=1)
35+
assert int(out[0].item()) == -1
36+
37+
38+
def test_get_y_idx_at_center_matches_middle_cell():
39+
kernel = _probe_get_idx_kernel(axis="y", width=200, height=200, resolution=1.0)
40+
coords = cp.asarray([0.0], dtype=cp.float32)
41+
center = cp.asarray([0.0], dtype=cp.float32)
42+
out = cp.zeros((1,), dtype=cp.int32)
43+
kernel(coords, center, out, size=1)
44+
assert int(out[0].item()) == 100

0 commit comments

Comments
 (0)