docs: 운전원교육자료/브레인스토밍/knowledge 업데이트 + MCP config

This commit is contained in:
windpacer
2026-05-31 17:31:50 +09:00
parent 48a6b6be57
commit 671d4ee1e5
6 changed files with 976 additions and 1 deletions

View File

@@ -0,0 +1,344 @@
# 보조운전 (Operation Assistant) — 브레인스토밍
> 2026-05-30, C-6111 PGMEA 측류 추출식 증류탑 기준
## 1. 목표
LLM(MCP) + 실시간 DCS 데이터 + KB(SOP)를 결합하여 운전원의 startup / 생산 순도 확인 / 생산 모드 / shutdown 과정을 **단계별로 보조**하는 UI.
## 2. 핵심 설계 원칙
| 구분 | 처리 방식 | 예시 |
|:----|:---------|:-----|
| **DCS 계측 항목** | 시스템 자동 검증 (`find_tags`/`run_sql`/`query_events`) | Pump 상태, FICQ SP, XV open/close, 온도/압력 |
| **수동 항목** (hand valve, local gauge, visual) | LLM 지시 → **운전원이 "확인완료" 클릭** | "HV-6115 개방하세요" → 버튼 클릭 |
| **계산/분석 항목** | MCP tool + LLM 추론 | 물질수지 검증, 순도 확인, R/P 계산 |
## 3. 시스템 아키텍처
```
┌─────────────────────────────────────────────────────────────┐
│ 보조운전 UI (신규 pane ops.html + ops.js) │
│ ┌─ sub-tabs: [startup] [verify_purity] [production] [shutdown] │
│ └─ Step progress bar + 단계별 카드 + 확인 버튼 │
└──────────────────┬──────────────────────────────────────────┘
│ HTTP (JSON-RPC)
┌──────────────────▼──────────────────────────────────────────┐
│ C# Controller (/api/ops/*) │
│ - GET /api/ops/guide?unit=C-6111&mode=startup&step=1 │
│ - POST /api/ops/confirm { unit, mode, step, feedback } │
│ - GET /api/ops/state?unit=C-6111 │
└──────────────────┬──────────────────────────────────────────┘
│ IMcpService
┌──────────────────▼──────────────────────────────────────────┐
│ Python MCP Server (server.py) │
│ - execute_operation_guide(unit, mode, step, feedback) │
│ - KB 검색 (rag_query) + 실시간 데이터 검증 (find_tags) │
│ - 내부 state machine으로 현재 단계 추적 │
└──────────────────┬──────────────────────────────────────────┘
┌──────────────────▼──────────────────────────────────────────┐
│ Data Sources │
│ ├─ Qdrant (KB — SOP 문서) │
│ ├─ PostgreSQL (DCS 실시간/이력 데이터) │
│ └─ vLLM (Qwen3.6-35B-A3B-FP8) │
└─────────────────────────────────────────────────────────────┘
```
## 4. SOP 문서 구조 (KB ingest 용)
각 SOP는 JSON 구조의 step 배열로 청킹:
```json
{
"doc_id": "c-6111-startup-sop",
"title": "C-6111 Start-up 절차",
"unit": "C-6111",
"mode": "startup",
"steps": [
{
"step": 1,
"title": "전단계 안전 확인",
"actions": [
"비상정지 버튼(XV-6123, XV-6124) CLOSE 확인",
"컬럼 진공압 PI-6111 확인 (~50 torr)"
],
"verification_type": "operator",
"expected": null
},
{
"step": 2,
"title": "원료 라인 구성",
"actions": [
"HV-6101 개방 (feed line, 수동밸브)",
"HV-6115 개방 (reflux return, 수동밸브)",
"HV-6116 개방 (bottom line, 수동밸브)"
],
"verification_type": "operator",
"expected": null
},
{
"step": 3,
"title": "원료 공급 펌프 기동 및 유량 설정",
"actions": [
"P-6102 R-RUN 전환",
"FICQ-6101 SP=820 kg/hr 설정"
],
"verification_type": "system",
"expected": {
"p-6102.pv": "R-RUN",
"ficq-6101.pv": { "min": 800, "max": 840 }
}
},
{
"step": 4,
"title": "Reboiler 가온",
"actions": [
"TICA-6111A SP=81.5°C 설정",
"Reboiler 응축수 라인 확인"
],
"verification_type": "mixed",
"system_checks": [
{ "tag": "tica-6111a.pv", "min": 78, "max": 85 }
],
"operator_action": "Reboiler 응축수 드레인 밸브 개방 확인"
}
]
}
```
### 청킹 전략
- 문서 1개 = 1개 unit × 1개 mode (startup/shutdown/production)
- 각 step의 `verification_type`: `operator` | `system` | `mixed`
- `expected` 필드: 자동 검증할 태그명(key)과 기대값(value)
- KB collection: `plant_operation`
## 5. UI 구조 (보조운전 화면)
### 5.1 레이아웃
```
┌─────────────────────────────────────────────────┐
│ [pane-hdr] 보조운전 / C-6111 운전 보조 │
├─────────────────────────────────────────────────┤
│ [mode-tabs] │
│ ● START-UP ○ 순도 확인 ○ 생산모드 ○ SHUTDOWN │
├─────────────────────────────────────────────────┤
│ [step-progress] │
│ ■■■■□□□□□□□ Step 4/12 │
│ ●●●●○○○○○○○ 33% │
├─────────────────────────────────────────────────┤
│ [step-card] │
│ ┌─────────────────────────────────────────┐ │
│ │ Step 4: Reboiler 가온 │ │
│ │ │ │
│ │ □ TICA-6111A SP=81.5°C 설정 │ │
│ │ ✓ PV=79.6°C (설정 중...) │ │
│ │ □ Reboiler 응축수 드레인 밸브 개방 확인 │ │
│ │ [✔ 확인완료] ← 운전원 클릭 │ │
│ │ │ │
│ │ [← 이전 단계] [다음 단계 →] │ │
│ └─────────────────────────────────────────┘ │
├─────────────────────────────────────────────────┤
│ [참고 정보 패널 - collapsible] │
│ - 현재 컬럼 온도 프로파일 │
│ - 현재 물질수지 │
│ - 활성 알람 │
└─────────────────────────────────────────────────┘
```
### 5.2 sub-tab 구성
| 탭 | mode | 설명 |
|:---|:-----|:------|
| START-UP | `startup` | 초기 기동 → 정상 상태 도달 |
| 순도 확인 | `verify_purity` | 생산 전 물질수지 + 온도 프로파일 검증 |
| 생산모드 | `production` | 정상 운전 중 모니터링 및 미세 조정 |
| SHUTDOWN | `shutdown` | 정지 절차 |
### 5.3 step-card 구성 요소
- Step 번호 + 제목
- Action 항목 리스트 (체크박스 형태)
- 시스템 자동 확인 항목: ✓ / ✗ 아이콘
- 운전원 확인 항목: [확인완료] 버튼
- 진행 버튼: [← 이전] [다음 →]
- 참고정보 패널: 현재 공정 데이터 요약
## 6. MCP Tool: `execute_operation_guide`
### Signature
```python
@mcp.tool()
async def execute_operation_guide(
unit: str,
mode: str, # "startup" | "verify_purity" | "production" | "shutdown"
operator_feedback: str | None = None,
current_step: int = 1
) -> str:
"""
KB에서 SOP 조회 → 실시간 데이터 검증 → 다음 action 반환
"""
```
### 동작 흐름
1. KB에서 `unit` + `mode`에 해당하는 SOP 검색
2. `current_step`의 expected 조건을 실시간 데이터로 검증
3. 검증 실패 항목 있으면 → 경고 메시지
4. `operator_feedback`이 있으면 → 현재 step 메모에 기록
5. 다음 step 정보 + 검증 결과 + action 목록을 JSON으로 반환
### 응답 구조
```json
{
"success": true,
"unit": "C-6111",
"mode": "startup",
"current_step": 4,
"total_steps": 12,
"title": "Reboiler 가온",
"actions": [
{
"description": "TICA-6111A SP=81.5°C 설정",
"type": "system",
"status": "in_progress",
"detail": "PV=79.6°C, SP=81.5°C (설정 중...)"
},
{
"description": "Reboiler 응축수 드레인 밸브 개방 확인",
"type": "operator",
"status": "pending",
"detail": null
}
],
"all_verified": false,
"can_proceed": false
}
```
## 7. C# Controller: `/api/ops/*`
| Route | Method | Description |
|:------|:-------|:------------|
| `/api/ops/guide` | GET | unit + mode + step → SOP 조회 + 검증 |
| `/api/ops/confirm` | POST | 운전원 확인 feedback 전송 |
| `/api/ops/state` | GET | 현재 진행 상태 조회 (재접속 등) |
| `/api/ops/reset` | POST | 진행 상태 초기화 |
## 8. 프론트엔드 구현 순서
| 단계 | 파일 | 내용 |
|:----:|:-----|:------|
| 1 | `index.html` | nav item #18 + pane + script 추가 |
| 2 | `panes/ops.html` | UI 레이아웃 (sub-tabs, progress, step-card) |
| 3 | `css/ops.css` | 전용 스타일 |
| 4 | `js/ops.js` | `paneInit.ops` — 탭 전환, step 렌더링, confirm 버튼 |
| 5 | `server.py` | `execute_operation_guide` MCP tool |
| 6 | C# Controller | `/api/ops/*` 라우트 |
| 7 | SOP 문서 | KB ingest 용 청킹 |
## 9. 향후 확장
- **다중 unit 지원**: C-6111 외 C-6211 등으로 확장
- **에이전트 모드**: LLM이 조건 만족 시 자동으로 다음 단계 진행
- **히스토리 트래킹**: 각 startup/shutdown 이력 DB 저장 → 패턴 분석
- **Alarm 연동**: 비정상 상황 감지 시 자동 shutdown 권고
## 10. 구현 전 사전 검증 항목
> ⚠️ 현재 이 문서는 **아이디어 스케치(브레인스토밍) 수준**이다. 아래 항목에 대한 검증과 사전 작업 없이 구현에 들어갈 경우, 실제 플랜트와의 정합성 문제로 재작업이 발생한다.
### 10.1 SOP JSON 구조 검증
| 검증 항목 | 상세 | 확인 방법 |
|:----------|:-----|:---------|
| step 필드 적절성 | title/actions/verification_type/expected만으로 모든 절차 표현 가능? | 실제 절차서 1개를 JSON으로 변환해보기 |
| 중첩 조건 표현 | "A 또는 B 상태" 같은 OR 조건 필요? `expected` 값의 표현력 | 태그 상태가 binary가 아닌 경우 (범위, enum) |
| 분기/조건부 step | 특정 조건에서만 수행하는 step 처리 | 예: "진공압이 50 torr 이하이면..." |
| 병렬 step | 동시에 수행 가능한 여러 action | 정렬 순서 강제 vs 자유로운 병렬 |
| 비정상 경로 | 정상 절차 외의 예외 처리 (재시도, 우회) | step 실패 시 fallback 절차 |
### 10.2 DCS 태그 계측 범위 검증
| 검증 항목 | 상세 | 확인 방법 |
|:----------|:-----|:---------|
| 검증 가능한 태그 목록 | SOP의 `expected` 조건에 사용할 태그들이 실제 realtime_table에 존재? | `find_tags` + `v_tag_summary` |
| 태그 데이터 타입 | digital(R-RUN/L-STOP) / analog(PV float) / enum 구분 | 각 태그별 `.pv` 값 형식 확인 |
| 계측 불가 항목 | 수동밸브, local gauge, visual check — 태그 없음 | SOP에서 `operator` 타입으로만 처리 |
| 신뢰도 | 태그 값이 0 또는 null인 경우 (고장/fault) | TI-6111A(PV=0), LI-6128(PV=0) 같은 사례 |
**C-6111 예비 조사 결과 (2026-05-30):**
| 태그 | 계측됨 | 데이터형 | 비고 |
|:----|:------:|:--------|:------|
| ficq-6101.pv | ✅ | analog | Feed SP=820 ✓ |
| ficq-6113.pv | ✅ | analog | Reflux SP=350 ✓ |
| ficq-6118.pv | ✅ | analog | Product SP=777.2 ✓ |
| pi-6111.pv | ✅ | analog | Vacuum ~48.5 torr ✓ |
| tica-6111a.pv | ✅ | analog | Reboiler SP=81.5 ✓ |
| ti-6111a.pv | ❌ | analog | PV=0 → 고장 의심 |
| ti-6111b/c/d.pv | ✅ | analog | Column profile ✓ |
| li-6128.pv | ❌ | analog | Scrubber level PV=0 → 미계측 |
| p-6102.pv | ✅ | digital? | R-RUN / L-STOP (상태 확인 필요) |
| xv-6123.pv | ? | digital | OPEN/CLOSE (태그 형식 확인 필요) |
### 10.3 Mode 분류 검증
| Mode | C-6111 적용 여부 | 비고 |
|:-----|:--------------:|:------|
| **startup** | ⬜ | 최초 기동 절차 존재? SIP(Startup Inspection Plan) 보유? |
| **verify_purity** | ⬜ | 생산 전 순도 분석 절차? off-spec 시 재순환 루틴? |
| **production** | ⬜ | 정상 운전 중 모니터링 항목? 조정 주기? |
| **shutdown** | ⬜ | 정지 절차? emergency shutdown과 normal shutdown 분리? |
| **grade_change** | ⬜ | 제품 grade 전환 절차 필요한가? (C-6111 연속식 단일 제품?) |
| **emergency** | ⬜ | Alarm/interlock 조건 발동 시 대응 절차? |
### 10.4 운전원 피드백 종류
| 피드백 | 의미 | UI 액션 |
|:-------|:-----|:---------|
| ✅ **확인완료** | 지시받은 수동 조작 완료 | 다음 step 진행 가능 |
| ⏸️ **보류** | 조건 미충족으로 일단 대기 | step 유지, 진행 불가 |
| ⚠️ **이상있음** | 예상과 다른 상태 발견 | LLM이 재확인/대안 제시 |
| 💬 **메모** | 자유 텍스트 기록 (운전일지) | step 로그에 기록 |
### 10.5 SOP 문서 소스 현황
| 항목 | 상태 | 액션 |
|:-----|:----|:------|
| C-6111 startup 절차서 | ❓ | 보유 여부 확인 필요 |
| C-6111 shutdown 절차서 | ❓ | 보유 여부 확인 필요 |
| 운전 체크리스트 양식 | ❓ | 기존 양식이 있다면 JSON 구조 맞출 기준 |
| P&ID (PFD) | ✅ | 이미 추출 완료 (node_map_master) |
| 물질수지/에너지수지 | ✅ | 오늘 작성한 공식 문서 |
### 10.6 사전 작업 목록
| 우선순위 | 작업 | 설명 | 담당 |
|:--------:|:-----|:------|:-----|
| **P0** | SOP 문서 확보 | C-6111 startup/shutdown 절차서 원본 수집 | 운전원/공정 |
| **P0** | 태그 매핑 | SOP의 모든 valve/기기명을 실제 DCS 태그명에 매핑 | 공정+개발 |
| **P0** | C-6111 startup 시나리오 시뮬 | JSON SOP 1건을 직접 작성해보며 필드 적절성 검증 | 개발 |
| **P1** | DCS 태그 형식 확인 | digital 태그의 .pv 값 형식 (R-RUN/L-STOP 등) | 개발 |
| **P1** | 예외 처리 정의 | 각 step별 실패 시나리오 및 fallback 정의 | 공정 |
| **P1** | UI 프로토타입 | panes/ops.html mockup 제작 (하드코딩 step) | 개발 |
| **P2** | MCP tool 구현 | `execute_operation_guide` server.py에 추가 | 개발 |
| **P2** | 피드백 타입 시험 | 운전원 확인 → 다음 step 전환까지 end-to-end | 통합 |
### 10.7 구현 원칙
1. **SOP 구조는 실제 절차서를 JSON으로 변환해보기 전에 확정 금지** — 필드 부족/과잉이 발생할 수 있음
2. **하드코딩 mock으로 UI 먼저 검증** — MCP tool 구현 전에 pane HTML+JS를 mock data로 동작시켜 UX 확인
3. **P0 검증 완료 후 P1, P1 완료 후 P2 진행** — 병렬 가능한 항목은 병렬
4. **처음부터 모든 mode를 만들지 않음** — startup만 먼저 구현, 다른 mode는 startup 구조 검증 후 확장
---
## 11. 참고 문서
- `docs/측류추출식-통합유량설정공식.md` — C-6111 물질수지/환류/온도보정/V_loss 공식
- `docs/보조운전-브레인스토밍.md` (본 문서)

View File

@@ -0,0 +1,239 @@
# Feedforward Advisory — 스트림 파라미터 해설
## 운전원 교육 자료
> 대상: C-6111 PGMEA 측류추출 증류탑 — 각 스트림(P/R/D/B)별 파라미터 의미와 튜닝 기준
---
## 1. 스트림 역할 (Role)
| Role | 의미 | 적용 스트림 | 동작 방식 |
|:-----|:------|:-----------|:---------|
| **Commanded** | FF가 SP를 직접 계산 | **P**(주생성물), **R**(환류) | Deadtime → Lag → RateLimit → 권장SP |
| **LevelDriven** | 레벨 제어기가 SP 결정, FF는 기대치만 제시 | **D**(유출액), **B**(탑저) | K × Feed, deadtime/lag 없음, 참고용 |
| **Monitor** | 모니터링만, 권장 SP 없음 | (향후 확장) | SP 계산 안 함, PV만 표시 |
---
## 2. 공통 파라미터
### 2.1 K (TargetCoeff) — 목표 계수
**정의**: Feed 대비 해당 스트림의 목표流量 비율.
```
P_stream 권장SP = K × FeedFilter출력 (Commanded, lag/rate 적용 후)
D/B_stream 기대치 = K × FeedFilter출력 (LevelDriven, 즉시 반영)
R_stream 권장SP = K × P_stream 권장SP (환류, P 경유)
```
**C-6111 기본값**:
| 스트림 | K | 근거 |
|:------|:---|:------|
| P=0.95 | 측류 95% 추출 | 주생성물이 Feed의 95% |
| R=0.80 | 환류비 R/P=0.8 | P 대비 80% 환류 |
| D=0.02 | 유출액 2% | 드럼 퍼지량 |
| B=0.03 | 탑저 3% | 바텀 드로우량 |
**튜닝**: K의 합이 1.0을 넘으면 물질수지 불일치. K_P + K_D + K_B = 1.0이 이상적 (R은 환류라 수지에 포함 안 됨).
### 2.2 Grade (Confidence) — 신뢰도 등급
| Grade | 의미 | Auto-write | 운전원 대응 |
|:------|:-----|:-----------|:-----------|
| **A** | K/θ/τ가 잘 튜닝됨, 권장값 신뢰 가능 | ✅ 허용 | 권장값을 SP로 채택 가능 |
| **B** | 튜닝 불확실성 있음, 참고용 | ❌ 금지 | 운전원 판단 필요, SP 채택 시 주의 |
| **C** | 모델 신뢰 불가, 진단 우선 | ❌ 금지 | 사용하지 말 것, 엔지니어 진단 요청 |
---
## 3. Commanded 스트림 전용 파라미터 (P, R)
Commanded 스트림은 Feed 변화가 권장SP에 반영될 때까지 **3단계 지연**을 거칩니다:
```
FeedFilter출력 → [Deadtime θ] → [Lag τ] → [RateLimit] → 권장SP
```
### 3.1 θ_up / θ_dn (ThetaUpSec / ThetaDnSec) — Deadtime (불감시간)
**정의**: Feed 변화가 해당 스트림에 실제로 영향을 미치기까지의 **순수 지연 시간(초)**.
| 방향 | 파라미터 | 의미 |
|:-----|:---------|:------|
| Feed 증가 | θ_up | 상승 응답까지 걸리는 시간 |
| Feed 감소 | θ_dn | 하강 응답까지 걸리는 시간 |
**비대칭 deadtime**: θ_up과 θ_dn을 다르게 설정 가능 (상승/하강 응답 특성이 다른 공정용).
**C-6111 기본값**: P=60초 (상승/하강 동일). Feed 변화가 C-6111 탑을 거쳐 측류 추출점에 도달하는 시간.
**물리적 의미**: 칼럼 내 액체 홀드업, 트레이/패킹을 통과하는 시간, 응답 지연.
### 3.2 τ (TauSec) — Lag 시정수 (1차 지연)
**정의**: Deadtime 이후 Feed 변화가 지수적으로 정착하는 **시정수(초)**. 1차 저역통과필터의 τ.
```
Lag출력 = Lag출력 + (입력 - Lag출력) × ts / τ
ts=Scan, τ=900초:
1τ(900초) 후 63% 도달
2τ(1800초) 후 86% 도달
3τ(2700초) 후 95% 도달 (≈ 정상상태)
```
**C-6111 기본값**: P=900초(15분). 측류 추출 응답이 느린 이유:
- 칼럼 내 액체 홀드업 완료 시간
- 물질 이동(mass transfer) 속도
- 온도/조성 평형 도달 시간
### 3.3 Rate_up / Rate_dn (RateUpPerMin / RateDnPerMin) — 변화율 제한
**정의**: 권장SP가 **분당 최대 몇 단위까지 변할 수 있는지** 제한.
```
|권장SP(t) - 권장SP(t-1)| ≤ Rate × ts / 60
```
**C-6111 기본값**:
- P: up=30/min, dn=60/min (상승보다 하강 2배 빠름)
- R: up=30/min, dn=30/min (대칭)
**용도**: SP가 급격히 변하는 것을 방지 — DCS의 PID 제어기가 추종 가능한 범위로 제한.
### 3.4 θ vs τ vs Rate — 차이 이해
| 구분 | 성격 | 영향 | 단위 |
|:-----|:-----|:-----|:------|
| **θ (Deadtime)** | 순수 지연 | Feed 변화 후 아무 반응 없음 | 초 |
| **τ (Lag)** | 지수적 정착 | 변화가 서서히 나타남 | 초 |
| **Rate** | 변화율 제한 | SP의 기울기 제한 | /분 |
**직관적 비유 (온수 샤워)**:
- **θ**: 핸들 돌린 후 물이 뜨거워질 때까지 걸리는 시간
- **τ**: 뜨거워지는 속도 (급격/완만)
- **Rate**: 핸들을 1초에 얼마나 돌릴 수 있는지 제한
---
## 4. LevelDriven 스트림 전용 파라미터 (D, B)
LevelDriven은 단순 비례이므로 deadtime/lag/rate 파라미터가 **의미 없음** (0으로 설정):
```
기대치 = K × FeedFilter출력
→ deadtime 없음, lag 없음, rate 제한 없음
```
### 4.1 LevelTag — 레벨 태그
**정의**: 해당 LevelDriven 스트림을 구동하는 **레벨 제어기의 태그명**.
| 스트림 | LevelTag | 레벨 제어기 | 의미 |
|:------|:---------|:-----------|:------|
| D | lica-6113 | D-6113 환류버퍼드럼 레벨 | 유출액 = 드럼 레벨로 제어 |
| B | li-6111 | C-6111 탑저 레벨 | 탑저 = 칼럼 바텀 레벨로 제어 |
**LevelDriven 기대치와 실제 SP의 관계**:
```
FF 기대치 = K × Feed (참고용)
실제 DCS SP = LIC 출력 (레벨 제어기가 결정)
```
FF는 "Feed가 이만큼이면 D/B에 이 정도 flow가 필요할 것이다"는 **기대치**만 제시. 실제 SP는 레벨 제어기가 결정하므로, FF 기대치는 **운전원이 레벨 제어가 정상인지 확인하는 보조지표**.
---
## 5. RefluxFromProduct — P 경유 환류 (R 스트림)
**정의**: R(환류)이 P(주생성물) 권장SP를 기준으로 비례 계산되는지 여부.
```
RefluxFromProduct = true:
R_rec = K_R × P_rec (P의 deadtime/lag/rate을 상속받음)
RefluxFromProduct = false:
R_rec = (K_R × FeedFilter출력 → 독자적인 deadtime/lag/rate)
```
**C-6111 기본값**: R=true (P 경유). 이유:
- 환류량은 주생성물량에 비례
- P의 지연 특성(θ=60, τ=900)을 자연스럽게 상속
- 독립 계산 시 P와 R이 서로 다른 시점에 변동 → 불안정
---
## 6. SP 제한 (SpMin / SpMax)
**정의**: 권장SP가 가질 수 있는 **최소값/최대값**.
```
권장SP = Clamp(계산값, SpMin, SpMax)
```
**C-6111 기본값**:
- P: 0 ~ 9999 (사실상 무제한, Range만 0~9999)
- R: 0 ~ 9999
- D: 0 ~ 9999
- B: 0 ~ 9999
**용도**:
- 펌프 최소 유량 보호 (SpMin > 0)
- 배관/계기 최대 유량 초과 방지 (SpMax)
- 운전 범위를 물리적 한계 내로 제한
---
## 7. C-6111 기본값 종합표
| 파라미터 | P | R | D | B | 단위 | 비고 |
|:---------|:--|:--|:--|:--|:----|:-----|
| **Role** | Commanded | Commanded | LevelDriven | LevelDriven | — | |
| **K** | 0.95 | 0.80 | 0.02 | 0.03 | — | D+B = Feed의 5%, P = 95% |
| **θ_up** | 60 | — | — | — | 초 | P만 deadtime 적용 |
| **θ_dn** | 60 | — | — | — | 초 | |
| **τ** | 900 | — | — | — | 초 | P만 lag 적용 |
| **Rate_up** | 30 | — | — | — | /분 | 상승 변화율 제한 |
| **Rate_dn** | 60 | — | — | — | /분 | 하강 (2배 빠름) |
| **SpMin** | 0 | 0 | 0 | 0 | — | |
| **SpMax** | 9999 | 9999 | 9999 | 9999 | — | |
| **Grade** | A | A | B | B | — | D/B는 레벨 제어 의존, B 등급 |
| **RefluxFromProduct** | — | true | — | — | — | R은 P 경유 |
| **LevelTag** | — | — | lica-6113 | li-6111 | — | 구동 레벨 태그 |
---
## 8. 튜닝 가이드
### K 조정
```
K 합 체크: K_P + K_D + K_B = 1.0 (이상적)
현재: 0.95 + 0.02 + 0.03 = 1.00 ✅
K_P 증가 → P 권장 SP 상승 → R(환류)도 상승 (RefluxFromProduct=true)
K_B 증가 → B 기대치 상승 → 탑저 드로우 증가
```
### θ/τ 조정
```
θ가 너무 작음 → Feed 변화에 SP가 너무 빨리 반응 (불안정)
θ가 너무 큼 → 응답 지연, Feed 변화 후 오래 기다려야 함
τ가 너무 작음 → SP가 급변, DCS PID가 추종 못 할 수 있음
τ가 너무 큼 → SP 정착까지 너무 오래 걸림 (30분+)
튜닝 방법: Feed step 테스트 → 실제 PV 응답 곡선에서 θ와 τ 측정
```
### Rate 조정
```
Rate_up/dn이 너무 작음 → SP 변화가 너무 느려서 Feed 변화를 따라가지 못함
Rate_up/dn이 너무 큼 → SP가 급변, DCS 밸브가 추종 못 할 수 있음
적정값: DCS PID의 최대 추종 변화율 × 0.8 (여유)
```

View File

@@ -0,0 +1,261 @@
# Feedforward Advisory — 과도상태(Transient) 메커니즘
## 운전원 교육 자료
> 대상: C-6111 PGMEA 측류추출 증류탑 FF(Feedforward Advisory) 시스템
> 버전: 2026-05 Phase I
---
## 1. 개요
FF 시스템은 Feed(공급유량) 변동 시 각 스트림(P/R/D/B)의 **권장 SP(Setpoint)를 실시간 계산**하여 운전원에게 제시합니다. 그러나 Feed나 압력이 불안정할 때는 권장값을 곧바로 신뢰할 수 없습니다. 이때 **과도상태(Transient)** 메커니즘이 작동하여 권장값을 "참고용"으로 전환하고, 안정화될 때까지 기다립니다.
### ⚠️ 중요: FF는 Advisory(보조지표)입니다
**FF 시스템은 DCS의 실제 Setpoint(SP)를 절대 변경하지 않습니다.** Transient 여부와 관계없이:
- DCS SP는 운전원이 설정한 값 그대로 유지됨
- FF는 권장값(Recommended SP)을 화면에 표시만 함
- 운전원이 권장값을 검토한 후 **직접 DCS에 입력**해야 적용됨
- Transient 중에는 권장값에 `valid=false`(신뢰도 낮음) 플래그만 추가됨
즉, FF가 transient 상태라고 해서 **공정에 실제 변화가 일어나지는 않습니다.** 단지 운전원이 참고할 권장 숫자가 "아직 믿을 만한 상태가 아니다"라는 신호일 뿐입니다.
---
## 2. Transient 진입 조건
Transient는 다음 **3가지 조건** 중 하나라도 만족하면 발동합니다.
| 조건 | 감지 방식 | 파라미터 | 기본값 |
|:----|:---------|:---------|:------|
| **① FEED 이동** | Feed 유량의 순간변화율(미분)이 임계 초과 | `FeedMoveThreshold` | **5%/분** |
| **② 압력 불안정** | 압력PV가 필터 추종 범위 이탈 | `PressureBand` | **3.0** |
| **③ 정착 대기 중** | 위 조건이 해제된 후 SettleTimer가 0이 아님 | `SettleSec` | **1800초(30분)** |
### 2.1 FEED 이동 감지 — 상세
```
FeedFilter: 1차 저역통과필터 (τ=300초, 시정수 5분)
목적: 공급유량의 순간 노이즈 제거, 실질적인 변화만 포착
FeedDeriv: 필터 출력의 미분값 (틱당 변화량 → 분당 변화율)
moving = |dF| × 60 > FeedMoveThreshold (기본 5%/분)
```
예:
- Feed가 820→1000으로 180만큼 변화
- FeedFilter가 300초 시정수로 부드럽게 추종
- 1차 틱(2초)에서 dF ≈ (821.2-820)/2 = 0.6/sec = 36/min
- **36 > 5 → moving = true**
### 2.2 압력 불안정 감지 — 상세
```
PressFilter: 1차 저역통과필터 (τ=60초)
목적: 압력 신호의 고주파 진동 제거
pUnstable = |압력PV - PressFilter출력| > PressureBand (기본 3.0)
```
의미: 필터가 추종 가능한 범위를 실제 압력이 벗어나면 "불안정"으로 판단.
### 2.3 정착 대기(SettleTimer) — 상세
```
if (moving || pUnstable)
SettleTimer = SettleSec (1800초) // ← 리셋
else
SettleTimer = max(0, SettleTimer - ScanSec)
```
Transient 조건이 해제되어도 **SettleTimer가 0이 될 때까지(최대 30분) transient 유지.**
---
## 3. Transient 상태에서의 동작
### 3.1 UI 표시
```
┌─────────────────────────────────────────────────────┐
│ 과도상태: 압력 불안정 — 권장값 정착 대기 │
│ │
│ 스트림 │ PV │ 권장 SP │ Δ │ 신뢰 │
│ P │ 780.2 │ 779.0 │ -1.2 │ A (흐림) │
│ R │ 620.0 │ 623.2 │ +3.2 │ A (흐림) │
│ D │ 16.5 │ 16.4 │ -0.1 │ B (흐림) │
│ B │ 24.8 │ 24.6 │ -0.2 │ B (흐림) │
│ │
│ 물질수지: 정착 대기 (1795s) │
└─────────────────────────────────────────────────────┘
```
- 모든 스트림의 권장값이 **valid = false** (회색/흐리게 표시, `.ff-stale`)
- 권장값 계산은 **내부적으로 계속 진행**되지만, 운전원 화면에서는 "참고용" 표시
- 물질수지(V_loss, 수율) 계산 **중단**
- 우측 하단에 정착 대기 시간 카운트다운
### 3.2 Transient 중 Recommended SP는 어떻게 되나?
**Recommended SP는 계속 업데이트됩니다. 이전값에 고정되지 않습니다.**
```
예: Feed 820→1000 step, P stream 기준
t=0min Feed step, transient 시작
P_rec = 779 (deadtime 중, 이전 Feed≈820 기준)
t=1min P_rec = 781 (deadtime 끝나며 새 Feed 반영 시작)
t=5min P_rec = 799 (Lag τ=900s로 서서히 상승)
t=15min P_rec = 861
t=30min P_rec = 916 (transient 해제, valid=true 전환)
t=45min P_rec = 950 (정상상태 도달)
```
계산 자체는 멈추지 않습니다:
- FeedFilter, PressFilter, DeadTimeBuffer, Lag, RateLimiter 모두 **정상 작동**
- Recommended SP도 매 틱(2초)마다 **계속 재계산되어 갱신됨**
- **단, `valid=false` 플래그만 붙어서 화면에 흐리게 출력**
즉, transient가 풀리는 순간 **이미 최신 Feed를 반영한 권장값이 valid=true로 전환**됩니다.
---
## 4. Transient 종료 후 — 정상 상태 전환
### 조건
```
moving = false AND pUnstable = false AND SettleTimer = 0
```
### 전환 효과
1. 모든 스트림 `valid = true` — 권장값 본격 표시
2. 물질수지 계산 재개:
```
V_loss = FeedFilter출력 - (D_PV + P_PV + B_PV)
수율 = 100 × P_PV / FeedFilter출력
```
3. MassBalanceState 평가:
- `|V_loss| > 0.03 × Feed` → **"물질수지 불일치(계측 점검)"**
- `V_loss < 0` → **"음의 손실(스팬 오류 의심)"**
- else → **"정상"**
### 주의: Transient 해제 ≠ 정상상태 도달
Transient가 풀려도 P stream의 Lag(τ=900초=15분)가 아직 정착 중일 수 있음:
```
예) Feed 820→1000 변경 시:
t=0분 Feed step, transient 시작
t=30분 SettleTimer=0, transient 해제
→ P 권장은 아직 950(최종값)에 도달 전 (약 910~920)
t=45분 P 권장 95% 도달 (3τ)
```
운전원은 transient 해제 후에도 **권장값이 서서히 움직이는 것**을 정상으로 이해해야 함.
---
## 5. 스트림별 동작 차이
| 역할 | Deadtime | Lag | Rate Limit | Transient 영향 |
|:----|:---------|:----|:-----------|:---------------|
| **P** (Commanded) | θ=60초 | τ=900초 | 30/min | valid=false만 적용, 계산은 계속 |
| **R** (Reflux) | P 경유(상속) | P 경유 | 30/min | P와 동일 |
| **D** (LevelDriven) | 없음 | 없음 | 없음 | `K×Feed` 즉시 반영, valid=false |
| **B** (LevelDriven) | 없음 | 없음 | 없음 | `K×Feed` 즉시 반영, valid=false |
**LevelDriven**은 단순 비례식:
```
D_rec = 0.02 × FeedFilter출력
B_rec = 0.03 × FeedFilter출력
```
deadtime/lag이 없으므로 Feed 변동에 즉시 반응하지만, 어디까지나 **기대치(Feedforward bias)**입니다. 실제 SP는 레벨 제어기(LIC)가 결정합니다.
---
## 6. 설정 파라미터 튜닝 가이드
| 파라미터 | 현재값 | 느슨하게 | 엄격하게 | 영향 |
|:---------|:-------|:---------|:---------|:-----|
| `FeedMoveThreshold` | 5/분 | ↑ 증가 | ↓ 감소 | 크면 Feed 변동 둔감, 작으면 민감 |
| `PressureBand` | 3.0 | ↑ 증가 | ↓ 감소 | 크면 압력 둔감, 작으면 민감 |
| `SettleSec` | 1800초 | ↓ 감소 | ↑ 증가 | 작으면 빨리 해제, 크면 오래 대기 |
| `FeedFilterTauSec` | 300초 | ↓ 감소 | ↑ 증가 | 작으면 빠른 반응, 크면 늦은 반응 |
| `PressFilterTauSec` | 60초 | ↓ 감소 | ↑ 증가 | 작으면 압력 빠른 추종, 크면 늦음 |
### 튜닝 예시
**"transient가 너무 자주 걸려요" →**
- `FeedMoveThreshold` 증가 (예: 5→8) — 미세 Feed 변동 무시
- `PressureBand` 증가 (예: 3→5) — 압력 진동 허용폭 확대
- 단, 너무 느슨하면 실제 불안정 상황을 놓칠 수 있음
**"transient가 너무 오래 가요" →**
- `SettleSec` 감소 (예: 1800→900) — 정착 대기시간 단축
- 단, 30분은 의도된 값 — 압력/Feed가 안정된 후에도 일정 시간 관찰하도록 설계
---
## 7. 실제 운전 시나리오 예시
### 시나리오 1: Feed 정상 증가 (의도적)
```
운전 조작: FICQ-6101 SP를 820→1000으로 변경
FF 반응:
1. FeedDeriv 36/min → transient 시작
2. 30분간 valid=false (흐림 표시)
3. 30분 후 valid=true 전환
- P 권장 ≈ 910 (아직 950 도달 전, Lag 진행 중)
- D 권장 ≈ 20 (0.02 × 1000)
- B 권장 ≈ 30 (0.03 × 1000)
4. 약 45분 후 P 권장 950에 정착
```
운전원 행동:
- transient 중에는 권장값을 **참고**만 하고, 자신의 판단으로 SP 조정
- transient 해제 후 권장값이 합리적이면 추종
- P 권장이 최종값(950)에 도달하는 건 **15분 더 걸림** 인지
### 시나리오 2: 압력 진동 (진공펌프 기동)
```
현상: PICA-6111 압력이 3torr 이상 진동
FF 반응:
1. pUnstable = true → transient 시작
2. SettleTimer 1800초 리셋
3. 압력 안정 후에도 30분간 transient 유지
```
운전원 행동:
- 진공계 안정화 확인
- transient가 불편하면 `SettleSec` 또는 `PressureBand` 조정 검토
### 시나리오 3: Feed 미세 변동 (transient 미진입)
```
Feed 820→830 (+10, 약 1.2% 변화)
FF 반응:
1. FeedDeriv ≈ 2/min → 5 이하 → moving=false
2. Transient 미진입 → 권장값 계속 유효
3. P 권장: 0.95×830 ≈ 788.5 (lag/rate 적용)
```
---
## 8. FAQ
**Q: transient 중인데 권장값이 보이긴 하는데 흐려요. 왜죠?**
A: 계산은 계속되지만 운전원이 **아직 신뢰할 단계가 아니다**는 의미입니다. 압력이나 Feed가 안정된 후 30분이 지나면 선명하게 전환됩니다.
**Q: transient를 강제로 해제할 수 있나요?**
A: 현재 UI에는 강제 해제 기능이 없습니다. 설정에서 `SettleSec`을 0으로 줄이면 transient 시간을 없앨 수 있습니다. 단, 권장값의 신뢰성이 떨어질 수 있습니다.
**Q: transient 중에도 권장값을 SP에 반영해야 하나요?**
A: **아니요.** transient 중 권장값은 "참고용"입니다. 운전원의 경험과 판단으로 SP를 결정하세요. transient 해제 후 권장값을 검토하고 반영하세요.
**Q: P stream 권장값이 왜 이렇게 느리게 변하나요?**
A: Lag 시정수 τ=900초(15분) 때문입니다. Feed 변화가 Deadtime(60초)을 거쳐 Lag에 들어가면 15분에 걸쳐 서서히 정착합니다. 이는 공정의 실제 응답 특성을 모델링한 것입니다.
**Q: LevelDriven(D/B)은 왜 deadtime/lag이 없나요?**
A: D/B는 레벨 제어기(LIC)가 실제 SP를 결정합니다. FF가 계산하는 값은 **기대치(bias)**일 뿐입니다. 실제 레벨 제어 루프가 deadtime/lag을 처리하므로, FF 단에서는 즉시 반영해도 무방합니다.

View File

@@ -98,3 +98,133 @@ S = K_S × F
따라서 DCS 로직을 설계할 때는 완전 비례식만 적용하기보다, 운전원이 공정 상태를 보며 미세 조정할 수 있도록 **보정값(Bias)** 튜닝 탭을 반드시 확보해야 합니다.
특히 스팀 제어의 경우, 앞서 언급한 **탑 내부 차압[f(ΔP)]에 따른 감쇄(Override) 제어 알고리즘**을 상기 스팀 설정식에 더하여(Cascade/Override 구조) 안전성을 이중으로 확보해야 합니다.
## 리플럭스량 계산 재검토
의문이 맞습니다. **리플럭스량 350 → 33으로 줄어드는 것은 공정적으로 문제가 있습니다.**
### 🔍 문제점 분석
제 이전 계산에서 사용한 공식:
R = R_f × D = 2.0 × 16.36 = 32.72
이 공식은 **관계식 문서의 일반 증류탑 공식**입니다. 하지만 **측류 추출식(C-6111)** 에는 적합하지 않습니다.
### 📐 측류 추출식에서의 리플럭스량
측류 추출식에서는 리플럭스량이 **상부 제거량(D)** 이 아니라 **원료량(F)** 또는 **제품량(P)** 과 연동됩니다.
| 구분 | 현재 운전 | 설계 기준 (R/F) | 설계 기준 (R/P) |
|------|----------|----------------|----------------|
| **리플럭스량 (R)** | 350 | — | — |
| **원료량 (F)** | 818.13 | — | — |
| **제품량 (P)** | 481.05 | — | — |
| **R/F 비율** | 0.428 | 0.5~1.0 | — |
| **R/P 비율** | 0.727 | — | 0.8~1.2 |
### 📊 올바른 리플럭스량 산출
**현재 운전 상태의 R/F 비율(0.428)을 유지하거나, 설계 기준(R/F = 0.5~1.0) 적용:**
| 시나리오 | 계산식 | **새 SP값** | 현재 SP |
|----------|--------|------------|---------|
| **현재 R/F 유지** | 0.428 × 818.13 | **350** | 350 |
| **설계 R/F = 0.5** | 0.5 × 818.13 | **409** | 350 |
| **설계 R/F = 0.8** | 0.8 × 818.13 | **655** | 350 |
| **설계 R/F = 1.0** | 1.0 × 818.13 | **818** | 350 |
### 💡 권고
1. **리플럭스량 33은 너무 작음** — 컬럼 내 기-액 평형 유지 불가
2. **현재 운전 상태(R=350, R/F=0.428)는 합리적** — 반도체 등급 PGMEA 증류에 적합한 범위
3. **리플럭스량 조정 시** — R/F = 0.5~0.8 범위에서 점진적 조정 권장
### 📋 수정된 SP값 산출 (리플럭스량 제외)
| 태그명 | 역할 | 계산식 | **새 SP값** | 현재 SP |
|--------|------|--------|------------|---------|
| ficq-6114 | 경비물 제거량 (D) | 0.02 × 818.13 | **16.36** | 85.5 |
| ficq-6118 | 제품 추출량 (P) | 0.95 × 818.13 | **777.22** | 485 |
| ficq-6116 | 하부 제거량 (B) | 0.03 × 818.13 | **24.54** | 53.2 |
| ficq-6113 | 리플럭스량 (R) | **현재 R/F 유지** | **350** | 350 |
**리플럭스량은 현재 상태를 유지하고, D/P/B만 조정하시기 바랍니다.**
1. 측류 추출식 C-6111 — 통합 유량 설정 공식
📐 기본 물질수지
F = D + P + B
F: 원료투입량 (kg/hr)
P: 제품 추출량 (kg/hr) ← 주요 제어 변수
D: 경비물 제거량 (kg/hr)
B: 하부 제거량 (kg/hr)
📐 분할 비율 (설계 기준)
항목 계수 비율 근거
P k_P 0.95 주 제품 fraction
D k_D 0.02 경비물 fraction
B k_B 0.03 중비물 fraction
k_D + k_P + k_B = 1.00
📐 P 기준 환산식
설정값 공식 예 (P=777.2)
F P ÷ k_P 777.2 ÷ 0.95 = 818.1
D (k_D/k_P) × P (0.02/0.95) × 777.2 = 16.36
B (k_B/k_P) × P (0.03/0.95) × 777.2 = 24.54
📐 환류량 (온도보정 포함)
외부 환류 (FICQ 계측값):
R_ext = R_f × P
R_f: 제품기준 환류비 (설계 0.5~1.2)
현재 R_f = 350/777.2 = 0.45
내부 환류 (과냉각 보정):
R_int = R_ext × (1 + c_p × ΔT / λ)
c_p: PGMEA 비열 (kJ/kg·K)
λ: PGMEA 증발잠열 (kJ/kg)
ΔT: T_top - T_reflux_drum (°C)
= 컬럼 상부 온도 - 환류 drum 온도
보정계수 TCF = 1 + c_p × ΔT / λ
📐 컬럼 내부 실제 L/V 비
L/V = R_int / (R_int + P)
2. 실시간 데이터 적용
현재 컬럼 온도 Profile
태그 위치 PV (°C)
TICA-6111A 최하부 (Reboiler) 79.6
TI-6111B 원료투입구 위 중부 79.1
TI-6111C 제품추출 노즐 근처 중상부 78.8
TI-6111D 상부 제품추출 노즐 근처 77.8
→ 컬럼 상부 온도(T_top) = 77.8°C (TI-6111D)
현재 유량 현황
태그 역할 PV
FICQ-6101 F (원료) 820.7
FICQ-6114 D (경비물) 17.4
FICQ-6118 P (제품) 784.0
FICQ-6116 B (하부) 25.2
FICQ-6113 R_ext (환류) 350.7
→ P/F = 784/820.7 = 0.955 (설계 0.95와 일치 ✓)
온도보정 환류량 계산
PGMEA 물성치 (일반값, 실제 PGMEA 순도/압력에 따라 조정 필요):
물성 기호 값
비열 (액체) c_p 2.0
증발잠열 λ 330
c_p/λ 0.00606
ΔT를 추정할 환류 drum 온도 센서가 확인되지 않습니다. TI-6111D=77.8°C이므로, ΔT 시나리오별 결과:
ΔT (°C) TCF R_int (R_f=0.8, P=777.2) R_int (R_f=0.45, P=777.2)
0 (포화) 1.000 622 350
5 1.030 641 361
10 1.061 660 371
15 1.091 679 382
20 1.121 697 392
권장 설정값 (R_f=0.8, ΔT=5°C 가정)
설정값 공식 계산값 현재 SP
F (FICQ-6101) P ÷ 0.95 818.1 820
D (FICQ-6114) 0.02/0.95 × P 16.4 16.7
P (FICQ-6118) (기준) 777.2 777.2
B (FICQ-6116) 0.03/0.95 × P 24.5 24.54
R_ext (FICQ-6113) R_f × P 622 350
R_int (보정 후) 622 × 1.030 641 -
⚠️ 확인 필요 사항
1. 환류 drum 온도 센서 (reflux drum TI) 태그를 찾지 못했습니다 — ΔT 확인 후 TCF 재계산 필요
2. PGMEA 물성치(c_p, λ) 는 일반값입니다 — 실제 분석 데이터로 대체 권장
3. R_f = 0.8은 설계 범위 내 첫 권장값 — 순도 결과 보며 0.5~1.2 범위에서 조정

View File

@@ -1 +1 @@
{"vllm_model":"Qwen3.6-35B-A3B-FP8"}
{"vllm_model":"Qwen3.6-35B-A3B-FP8","temperature":0.1}

View File

@@ -0,0 +1 @@
{"ts": 1780099383.3920546, "tool": "query_events", "params": {"tag_name": "ficq-611%", "area": null}, "verifier_error": {"verifier_error": "R1.invalid_tag_format", "hint": "태그 형식 비정상: 'ficq-611%'. 예시: ficq-6113.pv, p-6102"}}