Files
Aislo/resources/tester/test_78_recommend_mass.py
T
eomsangdonandClaude Opus 5.5 0deeb52e9a fix(B05): 노선 추천 균형 종단을 본 설계 횡단과 맞춤 — 곡선표 확폭 · 비탈 안 닫힘 넓힘 · 암반 경계 · 누가토량 ±500㎥(78)
- 확폭은 노선 곡선표로(후보 · 편집 띠 · [확인]) · 없으면 종전 실측 반경
- 반폭에서 비탈이 안 닫히면 지표면 끝까지 넓힌 샘플로 다시 셈(본 설계 extend_unclosed 와 같은 뜻)
- 암반 경계 기본 오프셋(본 설계 기본 설계와 같음)
- 균형 목표 = 누가토량 끝값(절토 다짐 − 성토) ±500㎥ · 고른 선은 보간 말고 바로 셈해 λ 를 더 좁힘
- 후보 줄 세우기는 보간값 그대로(빠름) · 화면에 낼 선만 바로 셈
- 추천 창 한 줄: 불균형 % → 누가토량 ±㎥

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019EMfGERKUg5nMMNQsyVZ2j
2026-10-07 23:08:43 +09:00

60 lines
2.4 KiB
Python

# -*- coding: utf-8 -*-
"""노선 추천 균형 종단 — 본 설계와 같은 횡단 · 누가토량 ±500㎥(PLAN 78).
랩탑 메인 노선 271: 추천은 곡선표 확폭 · 비탈 안 닫힘 넓힘을 빼 성토를 4,200㎥ 적게 봄.
"""
import numpy as np
from B05_Profile.B05_Profile_Engine_RouteInitial_Profile import (
CROSS_HALF_M,
_station_areas,
_widenings,
route_profile,
route_sections,
)
from B05_Profile.B05_Profile_Engine_RouteInitial_Search import Terrain
from config.config_system_design import curve_widening_m
def _steep() -> Terrain:
# 노선(y = 200) 왼쪽(+y)으로 70 % 내리막 — 성토 비탈(1:1.5)이 ±20 m 안에서 안 닫힘
x = np.arange(0.0, 202.0, 2.0)
y = np.arange(120.0, 282.0, 2.0)
xx, yy = np.meshgrid(x, y)
z = 100.0 - 0.7 * (yy - 200.0) + 0.02 * xx
return Terrain(x, y, z, np.ones(xx.shape, dtype=bool))
def test_곡선표가_있으면_그_반경으로_확폭():
xy = np.array([(0.0, 0.0), (40.0, 0.0), (80.0, 0.0)])
chain = np.array([0.0, 40.0, 80.0])
at = np.array([0.0, 20.0, 40.0, 60.0, 80.0])
table = [{"start": [30.0, 0.0], "apex": [40.0, 1.0], "end": [50.0, 0.0], "radius_m": 12.0}]
rows = _widenings(xy, chain, at, table)
assert rows[2]["curve_widening_m"] == curve_widening_m(12.0)
assert rows[2]["plan_radius_m"] == 12.0
# 곡선표 없으면 직선(반경 실측 없음) — 확폭 0
assert all(row["curve_widening_m"] == 0 for row in _widenings(xy, chain, at))
def test_비탈_안_닫히면_넓힌_샘플로_셈():
at, ground, sections, modes, curves = route_sections([(20.0, 200.0), (180.0, 200.0)], _steep())
i = len(at) // 2
samples = sections[i]
assert max(s["offset_m"] for s in samples) > CROSS_HALF_M # 반폭 밖까지 떠 둠
narrow = [s for s in samples if abs(s["offset_m"]) <= CROSS_HALF_M]
high = float(ground[i] + 3.0) # 쌓기 — 내리막 쪽 성토 비탈이 길어짐
_, _, wide_fill = _station_areas(samples, modes[i], high, curves[i])
_, _, narrow_fill = _station_areas(narrow, modes[i], high, curves[i])
assert wide_fill > narrow_fill + 1.0
def test_누가토량_끝값은_허용_안():
profile = route_profile(
[(20.0, 200.0), (180.0, 200.0)], _steep(), max_grade=0.14, design_speed=20
)
assert profile["exact"] is True
assert abs(profile["mass_end_m3"]) <= profile["mass_tolerance_m3"] == 500.0
assert profile["balanced"] is True