vkgs-sim / tests /test_sensors_cpp.py
kimjunhan's picture
Add files using upload-large-folder tool
4c75661 verified
Raw History Blame Contribute Delete
3.41 kB
"""src/vkgs/src/sensors.hpp (๋ ˆ์ด์บ์ŠคํŠธ ๋ผ์ด๋‹คยท๋ ˆ์ด๋”) ๋ฅผ g++ ๋กœ ์ปดํŒŒ์ผํ•ด ์‹œํ—˜ํ•œ๋‹ค. ์ฐฝ์„ ๋„์šฐ์ง€ ์•Š๋Š”๋‹ค.
๋ณต์…€ ์›”๋“œ๋Š” nusim.sim.voxels ๋กœ ๋งŒ๋“ ๋‹ค โ€” ํŒŒ์ผ ํ˜•์‹์„ PythonยทC++ ์–‘์ชฝ์ด ๊ฐ™๊ฒŒ ์ฝ๋Š”์ง€๋„ ๊ฐ™์ด ๋ณธ๋‹ค."""
import os
import shutil
import subprocess
from pathlib import Path
import numpy as np
import pytest
from nusim.sim.voxels import read_voxels, write_grid
ROOT = Path(__file__).resolve().parents[1]
CXX = os.environ.get("CXX") or "g++"
def _world(path: Path):
g = np.mgrid[-30:30:0.1, -30:30:0.1].reshape(2, -1).T
ground = np.c_[g, np.full(len(g), 0.1)] # ์ง€๋ฉด ์นธ z 0 ~ 0.2
yz = np.mgrid[-30:30:0.1, 0:6:0.1].reshape(2, -1).T
wall = np.c_[np.full(len(yz), 20.1), yz] # x = 20 ~ 20.2
pts = np.vstack([ground, ground, wall, wall]) # ์นธ๋งˆ๋‹ค 2์  ์ด์ƒ
return write_grid(path, pts, np.array([-30.0, -30.0, -2.0]), np.array([30.0, 30.0, 10.0]))
def test_voxels_roundtrip(tmp_path):
_world(tmp_path / "w.vox")
occ, lo, res = read_voxels(tmp_path / "w.vox")
assert not occ[int((5 - lo[0]) / res), int((0 - lo[1]) / res), int((0.1 - lo[2]) / res)] # ์ง€๋ฉด์€ ๋†’์ด ์ง€๋„๊ฐ€ ๋งก๋Š”๋‹ค (๋ณต์…€ ์•„๋‹˜)
assert occ[int((20.1 - lo[0]) / res), int((0 - lo[1]) / res), int((3 - lo[2]) / res)] # ๋ฒฝ
assert not occ[int((5 - lo[0]) / res), int((0 - lo[1]) / res), int((2 - lo[2]) / res)] # ๋นˆ ๊ณต๊ฐ„
@pytest.mark.skipif(shutil.which(CXX) is None, reason="g++ ์—†์Œ")
def test_sensors(tmp_path):
_world(tmp_path / "w.vox")
exe = tmp_path / "t"
subprocess.run([CXX, "-std=c++20", "-O2", "-pthread", "-I", str(ROOT / "src/vkgs/src"),
str(ROOT / "tests/cpp/test_sensors.cpp"), "-o", str(exe)], check=True)
r = subprocess.run([str(exe), str(tmp_path / "w.vox")], capture_output=True, text=True)
assert r.returncode == 0, r.stdout + r.stderr
@pytest.mark.skipif(not (ROOT / "build" / "vkgs_voxcarve").exists(), reason="build/vkgs_voxcarve ์—†์Œ (cmake --build build)")
def test_free_space_carving(tmp_path):
"""๋นˆ ๊ณต๊ฐ„ ๊นŽ๊ธฐ: ํ•œ sweep ์—๋งŒ ์ฐํžŒ '์ง€๋‚˜๊ฐ„ ์ฐจ ์กฐ๊ฐ' ์€ ๋‹ค๋ฅธ sweep ์˜ ๋น”์ด ๊ทธ ์ž๋ฆฌ๋ฅผ ์ง€๋‚˜๊ฐ€๋ฏ€๋กœ ์ง€์›Œ์ง€๊ณ ,
๋งค sweep ์ฐํžˆ๋Š” ๋ฒฝ์€ ๋‚จ๋Š”๋‹ค (nusim.sim.voxels.carve, src/vkgs/src/voxcarve.cpp)."""
rng = np.random.default_rng(0)
org, ends, sweep = [], [], []
for s in range(20): # ์ž์ฐจ๊ฐ€ x 0 โ†’ 19 m ๋กœ ๊ฐ€๋ฉฐ 20 sweep
o = np.array([float(s), 0.0, 1.8])
org.append(o)
# ๋ฒฝ (x = 30, ๋†’์ด 0.5~3 m): ๋งค sweep
wall = np.c_[np.full(400, 30.1), rng.uniform(-3, 3, 400), rng.uniform(0.5, 3, 400)]
pts = [wall]
if s == 3: # ์ง€๋‚˜๊ฐ„ ์ฐจ ์กฐ๊ฐ (x 15, y 0, ๋†’์ด 0.5 m) โ€” ํ•œ sweep ์—๋งŒ
pts.append(np.c_[rng.normal(15, 0.03, 50), rng.normal(0, 0.03, 50), rng.normal(0.5, 0.03, 50)])
p = np.vstack(pts)
ends.append(p)
sweep.append(np.full(len(p), s, np.int32))
pts = np.vstack(ends)
lo, hi = np.array([-5.0, -10.0, -2.0]), np.array([40.0, 10.0, 8.0])
write_grid(tmp_path / "w.vox", pts, lo, hi, rays=(np.array(org), np.concatenate(sweep)))
occ, lo2, res = read_voxels(tmp_path / "w.vox")
at = lambda x, y, z: occ[int((x - lo2[0]) / res), int((y - lo2[1]) / res), int((z - lo2[2]) / res)]
assert not at(15.0, 0.0, 0.5) # ๊นŽ์˜€๋‹ค
assert at(30.1, 0.0, 1.5) # ๋ฒฝ์€ ๋‚จ๋Š”๋‹ค