- P&ID: 연결 분석 API, Prefix 규칙 관리, 카테고리 분류, DXF 그래프 빌드 - LLM: 대화 요약, tool card 영구 보존, 시계열 차트(uPlot), 에이전트 모드 - KB: 청크 미리보기, Field Instrument Inference, 인증/Qdrant 클라이언트 - MCP: 서버 기능 확장, 파이프라인 수정, timeout 개선 - Frontend: P&ID UI, LLM UI, KB UI, OPC UA Write 탭 추가 - 설정: AGENTS.md, plant_context, README, opencode.json 업데이트 - 정리: 진단 체크리스트 문서 삭제
12 KiB
12 KiB
P&ID 흐름 추적 · From/To 추출 알고리즘 사양서
출처: P10-EQP-BLOCK.dxf 협업 역설계로 검증된 규칙 통합 (2026-05-18). 참조 자산:
mcp-server/legend_symbols.json(심볼 시그니처),mcp-server/block_template_library.json(블록 템플릿),mcp-server/legend_probe.py(프로브). 관련 메모리: feedback-trace-reporting-granularity, reference-lineno-leader-rule, project-legend-symbol-catalog.
0. 목적과 핵심 전제 (지배 규칙)
- 목적: 도면에서 유체 흐름을 추적해 랜드마크 간 From/To 연결그래프와 라인번호·출처를 추출.
- 답변 단위: "FCV-10101 어디야?" → "라인 P-10149-40A-F1A-n (출처 T-10100) 상, P-10101 흡입헤더·토출·F-10102A/B 거쳐 FIT-10101 하류". 수동밸브/체크/호스/레듀서 등 commodity는 절대 열거 안 함.
- 정밀 카운트 아님: 견적용 개수 검출이 목적이 아니라 연결·위상 파악이 목적.
노드 분류
| 분류 | 예 | 처리 |
|---|---|---|
| 랜드마크 노드 | 설비(P-,T-,E-,C-,D-,F-,SC-…), 컨트롤밸브/태그계기(FCV-,FIT-,LIC-…), 모터 | From/To 그래프의 정점 |
| 투명 통과 (commodity) | 수동 볼/체크/글로브밸브, 레듀서, 플렉시블호스, 스트레이너, 플랜지 | 흐름 안 끊기게 브리지만, 노드 아님, 출력에 미열거 |
| 연결 매체 | 배관(pipings) | 엣지. line_number·출처 보유 |
1. 입력 자산
- 설비 블록: 태그명 INSERT (이름=태그). 위치 =
virtual_entities()월드 bbox (insert (0,0)+내부절대좌표 / 또는 실좌표 — 변환이 흡수). - 심볼 템플릿 라이브러리: 명명 블록 정의의 정규화 시그니처(상대좌표·길이·각도·토폴로지, 원/호/SOLID 수). 회전·미러 불변 종류식별 + 월드기하 방향산출 2계층.
- raw 지오메트리: modelspace LINE/LWPOLYLINE/ARC/CIRCLE/SOLID/HATCH — 실제 그려진 배관·commodity 심볼.
- OFFPAGE_CONNECTOR: 방향성 블록(LINE 5~6) + 본체 bbox 내부 TEXT 2개(출처설비/서비스, 라인번호/연속키).
- 라인번호 TEXT + 지시선: 직접배치 또는 leader(SOLID/선-구성 chevron 화살촉 + stem).
2. 알고리즘 단계
Phase 1 — 랜드마크 노드 추출
- 모든 INSERT 순회. 이름이 태그패턴(
^[A-Z0-9]{1,4}-?\d{3,5}또는 명시 설비명)이면 설비 노드: tag, world bbox 중심, 카테고리(prefix 규칙). - 태그계기/컨트롤밸브: 심볼(글로브밸브 등) + 인접 태그TEXT(FCV-/FIT-…) → 태그계기 노드. 태그=인접 라벨, 위치=심볼 월드좌표.
-SAME/중복 복제 = 동일 노드로 병합(같은 물리설비).
Phase 2 — 배관망 + commodity 투명 브리지
- raw LINE/LWPOLYLINE → 끝점 그래프(좌표 양자화). 세그먼트 = 잠재 배관.
- commodity 심볼 인식 → 투명 통과:
- 소형 빈 CIRCLE r≈0.28~0.46 (+ bowtie 바/대각) = 볼밸브 → pass-through. (r 필터 하한 0.28 필수; faceted·무원 변형은 클러스터 패턴으로)
- SOLID 삼각형 + 단일사선 = 체크밸브(방향성) → pass-through
- 닫힌 LWPOLY 채움 = 글로브 / ARC 돔+stem = 컨트롤·다이어프램 (단 태그 있으면 랜드마크, 없으면 commodity)
- 레듀서/플렉시블호스/스트레이너/플랜지 = pass-through
- 회전·미러는
virtual_entities()월드기하로 흡수. 블록명은 힌트, 방향근거 금지.
- gap-통과 브리지: 배관 끊김 → 진행 흐름벡터 방향(콘)으로 lookahead, gap에 commodity 심볼 있으면 그 너머 공선 세그먼트로 연결 계속.
Phase 3 — 위상 인식 (흐름방향·분기·합류·루프)
- 흐름방향 = 의미적: 발원지(OFFPAGE/탱크/펌프)에서 누적 흐름벡터. DXF 선 정점순서 무시, 역행 금지, 방문엣지 가드(진동 방지).
- FLOW_DIRECTION 화살표: 만나면 그 위치 흐름방향을 월드기하 apex→tail 벡터로 확정(이름 아님). 의미적 추정보다 우선.
- 엘보: 직각 굽힘은 끝점공유로 따라감(수평→수직 등).
- TEE = 분기/합류: 한 점에 3선 이상. 분기 시 본류+지선 분할.
- 재순환(킥백) 루프: 한 지선이 이미 방문한 흡입측으로 복귀 = 정상 사이클. 무한루프 아님 →
recirculation엣지로 표기, 그 지선 종료. - 헤더/매니폴드: 수평선에 수직 분기 다수 → 합류 매니폴드. 좌단 블라인드플랜지=막힘(흐름 반대편).
- 병렬 트레인: 동일 x/y의 평행 분기→합류 (예 F-10102A/B 수직병렬).
- OFFPAGE 짝: 본체 내부 라인번호/연속키 TEXT 추출. 동일 연속키 가진 커넥터끼리 페어 → 라인 점프(시트/위치). 방향 = 커넥터 월드기하.
Phase 4 — 라인번호 ↔ 배관 귀속
- 케이스 A 직접배치: 텍스트가 배관 복도 근접(수평배관 위 평행, 또는 수직배관 옆 span중간 가로배치). 박스 내 최근접 세그먼트.
- 케이스 B 지시선: 화살촉(SOLID 또는 1.0바+0.66대각 선-구성 chevron) → tip 좌표가 닿는 배관 = 대상. tip↔배관 매칭 허용오차 극소(sub-0.5u, ≈0) — 밀집부 오매칭 방지. stem(LINE/LWPOLY/SPLINE/LEADER 무관) → landing → 텍스트 역추적도 성립.
- 모호 분해: 근접 평행 수직 2개 등 기하로 불가 시 → 흐름-토폴로지 컨텍스트(어느 배관이 추적경로/설비에 실제 연결)로 결정.
Phase 5 — 랜드마크 From/To 환원
- 투명 commodity 체인 붕괴(collapse): 랜드마크→(commodity*)→랜드마크 를 랜드마크↔랜드마크 단일 엣지로.
- 엣지 =
from_tag(상류 랜드마크),to_tag(하류 랜드마크). From/To에 배관번호 안 넣음. - 상/하류 = 흐름방향으로 결정. 미결정 시 무방향(from/to 임의·플래그).
- 배관번호·출처 = pipings 레코드/엣지 속성(권위). 랜드마크 위치질의는 랜드마크→인접배관→line_number+OFFPAGE출처 조인 조립.
3. 출력 스키마 (pid_equipment 정합)
| 카테고리 | from_tag / to_tag | line_number |
|---|---|---|
| equipment / control_valve / motor / instrument | 인접 랜드마크 태그 ↔ 랜드마크 태그 | (옵션) 얹힌 라인 단일 참조, From/To 불포함 |
| pipings | 라인 양끝 랜드마크 / OFFPAGE 짝 | 그 배관 라인번호 (권위) |
recirculation/bypass엣지는 타입 플래그로 구분(정상 위상, 누락·추측 금지).- 재실행 결정성: 기존 From/To 초기화 후 재계산하되 수동 import 잠금(ConnectionLocked) 보존.
4. 핵심 불변식 (검증된 함정 회피)
- 흐름방향은 의미적(발원지 기준), 선 정점순서·블록명 불신. 방문엣지 가드 필수(self-oscillation 방지).
- 회전/미러 → 종류는 불변시그니처, 방향은
virtual_entities()월드기하. 동일형상 다른이름(FLOW_DIR 3종 등) 주의. - 볼밸브 r≈0.28
0.46 (소형 지배, 도면 다수). 펌프 케이싱 r≈23 (≥4.5 아님). - 재순환선 = 정상 사이클. 끊지 말고 루프로 표기.
- 화살촉 tip↔배관 = sub-0.5u 준-정확. 화살촉은 SOLID 또는 선-구성 chevron.
- From/To = 랜드마크↔랜드마크. 배관번호는 엣지/pipings 속성. commodity 미열거(답변 단위 전제).
5. 정직한 한계 / 미검증
- raw 패턴매칭은 퍼지: 재현율 100% 보장 못 함(회전·스케일·작도변형·배관병합).
- 밀집부(토출·HATCH다수)는 좁은 허용오차 없이는 오탐.
- 지시선 변형: SOLID·선-구성 chevron 검증됨. SPLINE 곡선 stem 미검증.
- 직접배치 평행수직 모호 → 토폴로지 컨텍스트 의존(자동화 시 흐름추적 선행 필요).
- OFFPAGE 짝 매칭은 연속키 텍스트 정확추출 전제(밀집·회전 텍스트 노이즈 가능).
6. 구현 상태 · 다음 세션 인계 (2026-05-18 2차 세션 종료 시점)
산출물 (확정·보존)
- 사양서:
mcp-server/pid_trace_algorithm.md(이 문서) - 구현체:
mcp-server/pid_tracer.py— Phase 1·1b·2·3·4·5 구현 (미드스트림 라우팅 미완) - 카탈로그:
mcp-server/legend_symbols.json,mcp-server/block_template_library.json,mcp-server/legend_probe.py - 출력:
mcp-server/storage/P10-EQP-BLOCK_connections.json(C# 소비 포맷 호환) - C# 소비경로:
AnalyzeConnectionsAsync이미<prefix>_connections.jsonedges 소비 (이전 세션 구현)
정답 레퍼런스 (협업 검증된 ground truth)
- P-10101 시스템 전체 위상 = 흡입 T-10100/T-10101 합류 + 킥백 재순환 루프 + 토출 → 병렬필터 F-10102A/B → MASS_FLOW_METER(FIT-10101) → FCV(+바이패스) → E-10103
- 주의: 핸드오프 기억상 "FCV-10101" 이나 도면 실제 인접 버블은 FCV-10116 (도면 권위)
현재 어디까지 (2026-05-18 2차 세션 (a) 보강)
현재 트레이서 실측 출력:
- 랜드마크 57, OFFPAGE 시드 1, 볼앵커 372, raw 14,764, 라인번호귀속 227
OFFPAGE T-10100시드: T-10100 노드만 (공급선 P-10101 미완주)P-10101 discharge시드: P-10101 → F-10102B → F-10102A → FIT-10101 (여기서 멈춤)
완료·검증:
- ✅ OFFPAGE 발원 소스 시드: OFFPAGE_CONNECTOR 4종 중 LEFT_TO_RIGHT 처리.
apex = 본체 주축 두 극단 중 '뾰족한'(정점 1개) 쪽, 방향 = 뒷변중점→apex (월드기하
권위). 본체 근접 TEXT 분류 → 출처태그
T-10100발원 노드 등록 + 라인번호P-10149-40A-F1A-n시드 부착. (공급선이 P-10101 까지 완주는 미달 — §아래) - ⬆️ 랜드마크 통과-후-재개:
resume_nozzle— 블록 실체범위(SOLID/원반경 포함world_extent) 밖, 안정적 시드 흐름축 투영 최대 미방문 노즐로 재개. 결과:P-10101 → F-10102B → F-10102A → FIT-10101(이전: F-10102A 에서 멈춤). - ⬆️ 명명 심볼 = 태그계기 합성: MASS_FLOW_METER/CONTROL_VALVE_GLOBE/
FLOW_METER_VARIABLE-AREA 를 commodity 에서 제외, 인접 함수코드+번호 버블 TEXT 로
태그 합성 (
FIT+10101→FIT-10101,FCV+10116→FCV-10116). 블록명은 종류 힌트, 태그는 인접 TEXT 권위. - ⬆️ 일반 전방 gap-브리지: commodity/작도 끊김을 흐름축 콘(dot>0.85+수직오프셋 최소)으로 점프, 착지점에서 정상 conn 재전진(역행 억제).
- ⬆️ 볼앵커 과포함 정밀화: r 0.28~0.46 + 동반 단선(≤2.6) ≥2 조건 → 560→372.
- 🧩 Phase 4·5 실코드화: 라인번호 귀속(SOLID tip sub-0.5u / 직접배치, 227건), 재순환 엣지·OFFPAGE 라인번호 엣지 속성.
남은 미완 (다음 세션 계속 (a)2/(a)3):
- 밀집 미드스트림 라우팅:
FIT-10101 → FCV-10116 → E-10103장거리 런이 계기 테이크오프·샘플 분기 fitting 기하에 갇힘. 계기-테이크오프 거부 + 헤더/TEE 추종 필요. - 공급선 P-10101 완주: OFFPAGE 시드가 흡입헤더까지 라우팅 미완(하향 드리프트).
- TEE 분기 본류/지선 분할·OFFPAGE 동일연속키 짝 매칭 = 미구현(골격).
(b) C# 연동·DB 반영 (착수 전):
- 트레이서 의미 엣지 산출 후
AnalyzeConnectionsAsync를 P10-EQP-BLOCK 출력 연결 - From/To = 랜드마크↔랜드마크만(배관번호 미내장, pipings/엣지 속성) — §3 스키마대로 DB 반영
- 수동 import 잠금(ConnectionLocked) 보존 회귀 확인
검증 진입점(SEEDS)·정답 위상은 pid_tracer.py 주석 및 본 문서 §2·메모리에 보존됨.