Files
ExperionCrawler/docs/안전피드램프-검증시나리오매트릭스.md

127 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# WP1 — 안전 피드램프 Advisory 검증 시나리오 매트릭스
> 작성 2026-06-01. 대상: `plans/안전피드램프-advisory-작업지시서.md` WP3(`FeedRampCalculator`/`/api/ff/ramp-advisor`).
> 역할 3종: ① WP3 구현 spec ② WP3 단위테스트 정의 ③ 라이브 sim(WP0 override) 검증 스크립트.
> 컬럼: C-6111. 모든 기대 수치는 §0 config로 직접 계산(재현 가능).
---
## 0. 기준 상수 (C-6111, ff_stream_config) + 공통식
| key | role | K | θ_up(s) | τ(s) | sp_max | rate_up(kg/hr·min) |
|---|---|---|---|---|---|---|
| P | Commanded | 0.95 | 60 | 900 | 2000 | 30 |
| R | Commanded | 0.80 | 0 | 0 | 2000 | 30 |
| D | LevelDriven | 0.02 | | | 1000 | 0 |
| B | LevelDriven | 0.03 | | | 500 | 0 |
ProductKey=P. 피드=ficq-6101.
```
valveSlew = min_i(rate_up_i/K_i) = min(30/0.95, 30/0.8) = 31.58 kg/hr·min (P)
dynamic = ΔI × 60 / (K_P×(τ_P+θ_P)) = ΔI × 60/912 = ΔI × 0.06579
ΔI=50 → 3.29 ΔI=600 → 39.47
R_feed = min(valveSlew, dynamic, [energyLoop])
valveCeiling = min_i(sp_max_i/K_i) = min(2105.3, 2500, 50000, 16666.7) = 2105.3 (P)
floodCeiling = Fcur × (floodLimit/ΔPnow)^(1/n) ΔPnow = pi-6111b pica-6111
ceiling = min(valveCeiling, floodCeiling[, steamCeiling])
rampTimeMin= (clampedTarget currentFeed) / R_feed
steamTo = fiq6115Cur × (clampedTarget/currentFeed) + sensibleGain × clampedTarget × (feedTempRef ti6103Now)
```
## 0.1 공통 baseline 주입값 (anchor, 평형)
| 태그 | 값 | 비고 |
|---|---|---|
| ficq-6101.pv (feed) | 900 | currentFeed |
| ficq-6118.pv (P) | 855 | ≈0.95×900 |
| ficq-6113.pv (R) | 720 | ≈0.8×900 |
| ficq-6114.pv (D) | 18 | ≈0.02×900 |
| ficq-6116.pv (B) | 27 | ≈0.03×900 |
| ficq-6115.pv (스팀) | 300 | fiq6115Cur |
| ti-6103.pv | 150 | = feedTempRef(앵커) |
| pica-6111.pv | 40 | 탑정 진공압(mmHg) |
| pi-6111b.pv | 80 | 탑저 진공압 → ΔPnow=40 |
허용오차: 비율·flow ±2%, 시간 ±2%, binding 라벨은 정확일치.
---
## 1. 시나리오 매트릭스 (S0~S7)
| ID | 목적 | 주입/파라미터(anchor에서 변경분) | 기대 출력 | 합격기준 | 검증경로 |
|---|---|---|---|---|---|
| **S0** | baseline 평형 | targetFeed=**900**, ΔI=50 | clampedTarget=900, rampTimeMin≈0, ceiling=2105.3(**P**), steamTo=300(무변화), warnings≠∅ | rampTime≈0, ceiling 2105±2% binding=P, steam 300±2% | 단위+sim |
| **S1** | 피드 증량(동특성 binding) | targetFeed=**1100**, ΔI=50, feedTempRef=150, sensibleGain=0.001 | R_feed=**3.29**(binding=**dynamic**), clampedTarget=1100, rampTimeMin=**60.8**, steamTo=**366.7**, ceiling=2105.3(P) | rampRate 3.29±2% binding=dynamic, time 60.8±2%, steam 366.7±2% | 단위+sim |
| **S2** | 밸브 슬루 binding | targetFeed=1100, **ΔI=600** | dynamic=39.5 > valveSlew=31.58 → R_feed=**31.58**(binding=**valveSlew@P**), rampTimeMin=**6.33** | rampRate 31.58±2% binding=valveSlew@P, time 6.33±2% | 단위+sim |
| **S3** | ceiling 초과(밸브포화) | targetFeed=**2200**, ΔI=50 | clampedTarget=**2105.3**(binding=**P sp_max**), R_feed=3.29, rampTimeMin=**366.4** | clampedTarget 2105±2%, ceiling.binding="P sp_max", targetFeed 원값 2200 표기 | 단위+sim |
| **S4** | flooding ceiling | pi-6111b=**120**(ΔPnow=80), **floodLimit=100, n=1.8**, targetFeed=1100, ΔI=50 | floodCeiling=900×(100/80)^(1/1.8)=**1018.5**, ceiling=min(2105,1018.5)=**1018.5**(binding=**flooding**), clampedTarget=1018.5, rampTimeMin=**36.1** | ceiling 1018.5±2% binding=flooding, clampedTarget 클램프 | 단위+sim |
| **S5** | TI-6103 하강(현열 FF) | feed=900 고정, **ti-6103=140**, targetFeed=900, sensibleGain=0.001, feedTempRef=150 | steamTo=300×1 + 0.001×900×(150140)=**309.0**(+9), rampTimeMin≈0 | steamTo 309±2%(피드 무변에도 steam↑), 현열항 부호 양수 | 단위+sim |
| **S6** | stale/HOLD | feed 태그 Good=false(단위) / 운전원 frozen(>stale_sec=120s) | **HOLD** 반환 + warning="feed-bad/stale", 권장 미산정 | HOLD 상태·warning stale, 수치 미반환 | 단위(Good=false), 운전원 frozen |
| **S7** | 과추출 감지(현행엔진) | B=**150**(vs 27), P=855, D=18 → D+P+B=1023 > feed → vloss≈**120** | (FeedRampCalculator 아님) `/api/ff/advisory` **massBalanceState="물질수지 불일치(계측 점검)"** (\|vloss\|>3%·ff 조건이 먼저 걸림; 작은 음수만 "음의 손실") | mbState≠"정상" | **엔진**(/api/ff/advisory). override 엔진확장(2026-06-01) 후 **자율검증 가능**(라이브 120.27 확인) |
---
## 2. Worked 계산 (재현)
```
S1: dynamic=50×0.06579=3.29 valveSlew=31.58 → R_feed=3.29(dynamic)
clampedTarget=min(1100,2105.3)=1100 rampTime=(1100900)/3.29=60.8 min
steam=300×(1100/900)+0.001×1100×(150150)=366.7+0=366.7
S2: dynamic=600×0.06579=39.47 valveSlew=31.58 → R_feed=31.58(valveSlew@P)
rampTime=(1100900)/31.58=6.33 min
S3: clampedTarget=min(2200,2105.3)=2105.3(P sp_max)
rampTime=(2105.3900)/3.29=366.4 min
S4: ΔPnow=12040=80 floodCeiling=900×(100/80)^(1/1.8)
(100/80)=1.25 1.25^0.5556=1.1317 → 1018.5
ceiling=min(2105.3,1018.5)=1018.5(flooding) clampedTarget=1018.5
rampTime=(1018.5900)/3.29=36.0 min
S5: steam=300×(900/900)+0.001×900×(150140)=300+9.0=309.0 (피드 무변, 현열만)
S7: vloss=feed(D+P+B)=900(18+855+150)=123 (|123|>3%·900=27) → "음의 손실(스팬 오류 의심)"
```
---
## 3. 라이브 sim 검증 (WP0 override 경로)
공통 anchor 주입(S1 예):
```
curl -s -XPOST :5000/api/ff/sim/override -H 'Content-Type: application/json' -d '{
"enabled":true,
"values":{"ficq-6101.pv":900,"ficq-6118.pv":855,"ficq-6113.pv":720,
"ficq-6114.pv":18,"ficq-6116.pv":27,"ficq-6115.pv":300,
"ti-6103.pv":150,"pica-6111.pv":40,"pi-6111b.pv":80}}'
curl -s ':5000/api/ff/ramp-advisor?columnId=1&targetFeed=1100&deltaIAllow=50&feedTempRef=150&sensibleGain=0.001'
# 기대: rampRate.value≈3.29 binding=dynamic, rampTimeMin≈60.8, steam.fiq6115To≈366.7, ceiling.value≈2105 binding=P
curl -s -XDELETE :5000/api/ff/sim/override
```
- S2: 같은 anchor + `deltaIAllow=600`
- S3: `targetFeed=2200`
- S4: override에 `pi-6111b.pv=120` + query `floodLimit=100&n=1.8`
- S5: override에 `ti-6103.pv=140` + query `targetFeed=900&sensibleGain=0.001&feedTempRef=150`
- S7: override에 `ficq-6116.pv=150``GET /api/ff/advisory`의 massBalanceState 확인(ramp-advisor 아님)
## 4. 단위테스트 매핑 (WP3-F)
| 시나리오 | 테스트 | 비고 |
|---|---|---|
| S0~S5 | `FeedRampCalculatorTests` (합성 ColumnConfig+PvSnapshot 직접 구성) | S5는 sensibleGain·feedTempRef 명시 전달 |
| S6 | 동상 단위테스트, `pv.Feed.Good=false` → HOLD 검증 | |
| S7 | **제외** — mbState는 `FeedforwardEngine` 산출. WP2 또는 Engine 통합테스트 | 작업지시서 §256 |
## 5. 합격 종합
- S0~S5 단위테스트 전건 통과(허용오차 내), binding 라벨 정확.
- 라이브 sim S1~S5가 단위테스트 기대치와 일치(override↔계산 동일 입력).
- S6 HOLD, S7 mbState≠정상.
- 모든 미산정(energyLoop·flooding 근거 부재 등) warnings 노출.
## 6. 참조
- `plans/안전피드램프-advisory-작업지시서.md` (WP0~WP3)
- `docs/안전피드램프-한계치-브레인스토밍.md` §3(공식)·§7(스팀)·§9(압력)