From b85add0a5159337ccd3006d83b51ee03edd95990 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sun, 1 Nov 2026 21:27:24 +0900 Subject: [PATCH] =?UTF-8?q?feat(640-3):=20=EC=99=B8=EA=B3=BD=20=ED=8B=88?= =?UTF-8?q?=20=EB=8B=AB=EA=B8=B0=203=20m=20=E2=80=94=20=EC=84=B1=EA=B8=B4?= =?UTF-8?q?=20=EC=88=B2=20=EB=9D=A0=EA=B9=8C=EC=A7=80=20=EC=8A=A4=EC=BA=94?= =?UTF-8?q?=20=EB=B2=94=EC=9C=84=20=EC=82=B4=EB=A6=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - SURFACE_FOOTPRINT_GAP_CLOSE_M 1.0 → 3.0 · 「가장 큰 덩이만」 그대로 - 설정 지문에 들어가 다음 짓기 때 모든 표현 · 등고선 · 유효 범위가 새 외곽으로 다시 지어짐(기존 확정 파일 · DB 는 그대로) - 지킴 시험 test_640_lidar_default 틈 닫기 Co-Authored-By: Claude Opus 5.5 --- config/config_system_terrain.py | 3 ++- resources/tester/test_640_lidar_default.py | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/config/config_system_terrain.py b/config/config_system_terrain.py index e28ab794b..7f2a8dfde 100644 --- a/config/config_system_terrain.py +++ b/config/config_system_terrain.py @@ -100,7 +100,8 @@ SURFACE_MODEL_SYNC_TIMEOUT_SECONDS = int(os.getenv("SURFACE_MODEL_SYNC_TIMEOUT_S # footprint(외곽) 산출 SURFACE_FOOTPRINT_RESOLUTION_M = float(os.getenv("SURFACE_FOOTPRINT_RESOLUTION_M", "1.0")) -SURFACE_FOOTPRINT_GAP_CLOSE_M = float(os.getenv("SURFACE_FOOTPRINT_GAP_CLOSE_M", "1.0")) +# 외곽 틈 닫기 3 m — DJI 지면점이 성긴 숲 띠까지 스캔 범위로 살림(요구 558). +SURFACE_FOOTPRINT_GAP_CLOSE_M = float(os.getenv("SURFACE_FOOTPRINT_GAP_CLOSE_M", "3.0")) SURFACE_BOUNDARY_INSET_M = float(os.getenv("SURFACE_BOUNDARY_INSET_M", "1.0")) SURFACE_KEEP_LARGEST_FOOTPRINT = ( os.getenv("SURFACE_KEEP_LARGEST_FOOTPRINT", "True").lower() == "true" diff --git a/resources/tester/test_640_lidar_default.py b/resources/tester/test_640_lidar_default.py index f92ee1b75..6c2a776ef 100644 --- a/resources/tester/test_640_lidar_default.py +++ b/resources/tester/test_640_lidar_default.py @@ -134,3 +134,22 @@ def test_설정_지문이_바뀌면_implicit_다시_지음(tmp_path: Path) -> No with np.load(tmp_path / "implicit_a.npz") as new: assert len(new["center_z"]) == 2_000 assert manifest["source_filters"]["a"]["methods"]["implicit"]["center_count"] == 2_000 + + +def test_외곽_틈_닫기_3m_는_성긴_띠를_살림() -> None: + points = _plane(60.0) + gap = (points[:, 0] > 28) & (points[:, 0] < 33) # 5 m 빈 띠 — 1 m 닫기면 두 덩이 + points = points[~gap] + + def area(close_m: float) -> float: + config = dict(cfg.build_surface_model_config(), footprint_gap_close_meters=close_m) + context = TerrainContext( + xyz=points, + mask=np.ones(len(points), bool), + bounds=np.array([points.min(axis=0), points.max(axis=0)]).T, + config=config, + ) + return context.footprint_metadata()["footprint_area_m2"] + + assert cfg.SURFACE_FOOTPRINT_GAP_CLOSE_M == 3.0 + assert area(3.0) > 1.8 * area(1.0) # 한 덩이(띠 포함) 대 큰 덩이 하나