- PLCController.Address.cs: bit15 입출력 정의 (PLC/PC_MODE_CHANGE 0x0F, 양극 _P 0x73) - SeqAutoRunPTOP: ResumeMode 플래그, 정지 시 에코워드(PC_PAGE_NO/RECIPE_NO) 보존, CheckInitCondition Resume 핸드셰이크 스킵, CheckCycleStop bit15 OFF/해제 - UCMainAutoRun(VM/XAML): bit15 상승엣지 감지→팝업→Manual 전환, AutoRun Resume 버튼(bit15 ON시 표시) - docs: bit15 resume 작업지시서/분석/예상시나리오, 가접 레시피 인터페이스(20~23), 작업일지, 산출물 갱신 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
98 lines
6.3 KiB
Markdown
98 lines
6.3 KiB
Markdown
# bit15 Resume 재진입 문제 분석 — 작업 PC 전달용
|
|
|
|
- 작성일: 2026-06-21
|
|
- 대상 시퀀스: `Machines/ILSOS_PrismaticRD_PTOP/Sequences/SeqAutoRunPTOP.cs`
|
|
- 목적: PLC↔PC **bit15 기반 "이어하기(Resume)"** 시나리오 구현 시, AutoRun 재진입에서 깨질 지점과 권고 구현 방향 전달.
|
|
- 상태: **분석만** (소스 미수정). bit15는 현재 **미구현**.
|
|
|
|
---
|
|
|
|
## 1. 시나리오 (신호 타이밍)
|
|
|
|
1. PLC가 `PAGE_CHANGE_REQ(0x08)` + word(recipe/page) 송신.
|
|
2. PC가 recipe/page 적용·에코 후 `PC_PAGE_CHANGE_COMPLETE(0x08)` 송신.
|
|
3. **그다음** PLC가 입력 **bit15** ON → 장비 Stop.
|
|
4. 정지 중 작업자 수동 작업.
|
|
5. 신규 "이어하기" 버튼: AutoRun 시작 + PC→PLC **출력 bit15** ON → 중단 지점부터 이어서 용접.
|
|
|
|
> 핵심: bit15(stop)는 **페이지 체인지가 이미 끝난 뒤** 온다 → 정지 시점에 recipe/page는 **이미 적용·에코 완료** 상태.
|
|
|
|
---
|
|
|
|
## 2. 현 구조 핵심 사실 (확정)
|
|
|
|
- AutoRun 시작 = `_SeqAutoRunPTOP.Start(param, …)` (UCMainAutoRunViewModel.cs:244). Aurora `Start()`는 **Init 노드(맨 위)부터** 실행 → `Enter → CheckInitCondition → CheckPageNo`. **Resume/Pause 없음.**
|
|
- `CheckCycleStop`이 항상 `CheckPageNo`로 되돌아가는 무한 루프(SeqAutoRunPTOP.cs:829) → **정상 종료 노드 `Complete` 미도달.** 모든 세션은 Stop으로만 끝남.
|
|
- `SeqAutoRunPTOP` 인스턴스는 셋업 때 **1회만 생성**(EquipmentSetup.cs:203) → `_CurrentPageNo / plcPageNo / plcRecipeNo` 등 **C# 필드는 Stop 후에도 유지** (resume에 유리).
|
|
- bit15(=0x0F)는 입력/출력 맵 모두 `0x0A~0x0F` **예약 공백**(PLCController.Address.cs:27, 63) → 현재 미사용, 신규 정의 충돌 없음. (decimal 15=0x0F vs hex 0x15 여부만 PLC와 확정)
|
|
|
|
---
|
|
|
|
## 3. 재진입 시 문제점
|
|
|
|
### 3-1. Stop이 "이어가는 데 필요한 상태"를 전부 지움
|
|
`OnStopSequenceAutoRun`(UCMainAutoRunViewModel.cs:336) → `Stop()` → `OnStopped` → `OnSeqActionStop`(SeqAutoRunPTOP.cs:1078~):
|
|
- `PC_PAGE_NO=0`(:1101), `PC_RECIPE_NO=0`(:1102), `PC_ERROR_CODE=0`(:1100)
|
|
- 모든 용접 비트 false, `PC_PAGE_CHANGE_COMPLETE` false, `PC_AUTO_STATUS(_P)` false
|
|
- 레이저 게이트 OFF, **`_Scanner.StopExecution()` + `JumpAbs(0,0)`**(:1123-1124)
|
|
|
|
### 3-2. ★ 정지 시 레시피 롤백 — resume에 치명적
|
|
`OnStopSequenceAutoRun`이 `RecipeHelper.RollbackRecipe()`(:345). 내부 `Dispatcher.InvokeAsync(() => ReloadRecipe(SelectedRecipe.name))`(RecipeHelper.cs:104).
|
|
→ **실제 활성 레시피를 원래 레시피로 되돌림 + 비동기**. 정지 중 화면/Layers가 다른 레시피로 바뀜 → resume 기준이 어긋남.
|
|
|
|
### 3-3. PC_RECIPE_NO 에코 비대칭
|
|
- `PC_RECIPE_NO`는 **PC→PLC 출력 워드**(`eWordOutput`, D70002). PLC가 이 값을 읽어 레시피 정합을 확인 → **0이면 안 됨.**
|
|
- 정상 연속 운전 중엔 0 안 됨(마지막 에코값 유지). **0이 되는 건 Stop 때**(:1102).
|
|
- 재진입(같은 레시피)이면 `CheckRecipeNoComp`가 "읽은 레시피 == 현재 활성"이면 에코 없이 조기 return(:316-321) → **0인 채 남음.**
|
|
|
|
### 3-4. 페이지 요청을 "레벨"로 판정 (엣지 아님)
|
|
`CheckPageNo`는 `ReadBit(PLC_PAGE_CHANGE_REQ).data`를 레벨로만 봄(:378). 재진입 시 PLC가 0x08 유지면 즉시 통과(중복 처리), 안 주면 무한 대기(데드락).
|
|
|
|
### 3-5. 복구 단위 = "라인 단위 불가, 잘해야 페이지 단위"
|
|
`OnSeqActionStop`이 `StopExecution + JumpAbs(0,0)`로 스캐너 리스트 중도 취소(:1123) → 용접 중간 라인 복구 불가.
|
|
|
|
---
|
|
|
|
## 4. 결정 사항 (이번 시나리오)
|
|
|
|
- bit15 stop 시점엔 recipe/page **이미 적용 완료** → **추가 change 없음.**
|
|
- 팝업은 적용된 recipe/page를 **읽어 보여주는 read-only**.
|
|
- resume 재진입은 **페이지 핸드셰이크 스킵**, 용접리스트 업로드→용접부터 이어감.
|
|
|
|
---
|
|
|
|
## 5. 작업 PC 권고 구현 방향
|
|
|
|
1. **bit15 정지 구분 플래그 도입.** `OnSeqActionStop`은 일반/알람/ForceError 정지 공용이므로, "bit15 resume 정지일 때만" 아래 보존이 적용되게 분기. (알람 정지엔 미적용)
|
|
2. **bit15 정지 시 워드 보존:** `OnSeqActionStop`의 `PC_RECIPE_NO=0`(:1102) · `PC_PAGE_NO=0`(:1101) **쓰기 스킵.**
|
|
3. **`RollbackRecipe()` 스킵**(UCMainAutoRunViewModel.cs:345). 워드 보존과 **반드시 짝** — 안 하면 워드 ≠ 실제 활성 레시피.
|
|
4. **팝업(read-only):** 정지 시 recipe/page 읽어 작업자에게 표시. 실제 change 동작 없음.
|
|
5. **resume 재진입 분기:** `Start()`가 Init부터 타므로, bit15 플래그가 켜져 있으면 `CheckInitCondition`(:270, Decision)에서 `CheckPageNo`(:284) 대신 **`SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ`(:133)로 분기**해 핸드셰이크를 건너뛰고 업로드→용접부터. 페이지 컨텍스트는 유지된 `_CurrentPageNo` 사용.
|
|
|
|
---
|
|
|
|
## 6. 미해결 / 주의
|
|
|
|
- **mid-weld 복구 불가:** resume은 "중단 페이지 재시작" 단위. 용접 도중 멈춘 라인부터는 불가(3-5).
|
|
- **팝업값 ≠ 적용값 가능성:** 팝업은 정지 시점 값, 실제 진행은 resume 시점. 그사이 PLC가 또 바꾸면 불일치 → 정지 때 읽은 값을 **래치**해 resume에 쓰거나 "resume 시 재확인 후 적용"으로 정할 것.
|
|
- **bit15 번호 확정:** decimal 15(0x0F) vs hex 0x15 — 둘 다 현재 미사용. PLC 담당과 확정.
|
|
- **`Start()`=Init부터** 전제: 코드 구조상 확실하나 프레임워크 바이너리라 100% 확정은 아님. 필요 시 별도 확인.
|
|
|
|
---
|
|
|
|
## 7. 파일·라인 레퍼런스
|
|
|
|
| 항목 | 위치 |
|
|
|---|---|
|
|
| AutoRun 시작(Start) | UCMainAutoRunViewModel.cs:244 |
|
|
| Stop 버튼 + RollbackRecipe | UCMainAutoRunViewModel.cs:336-337, 345 |
|
|
| OnSeqActionStop(전체 리셋) | SeqAutoRunPTOP.cs:1078~ (워드 :1100-1102, 스캐너 :1123-1124) |
|
|
| CheckRecipeNoComp(에코 스킵/쓰기) | SeqAutoRunPTOP.cs:316-321, 350 |
|
|
| CheckPageNo(레벨 판정) | SeqAutoRunPTOP.cs:378 |
|
|
| CheckPageNoComp(에코/COMPLETE) | SeqAutoRunPTOP.cs:484, 491 |
|
|
| CheckCycleStop(루프백) | SeqAutoRunPTOP.cs:829 |
|
|
| Builder/Flow | SeqAutoRunPTOP.cs:122-179 |
|
|
| 인스턴스 1회 생성 | EquipmentSetup.cs:203 |
|
|
| RollbackRecipe 본체 | RecipeHelper.cs:104 |
|
|
| 비트/워드 맵 | PLCController.Address.cs (0x08 :23, 0x0F공백 :27/63, PC_RECIPE_NO :154) |
|