- 분석(191351): 동시수신 대응 단일 PAGE 게이트 핸드셰이크 확정안(8장) + ActivateRecipe→Layers 비동기 2-홉 race 분석, 대응안 A/B/C - 작업지시서(2026_06_21): 4노드→1노드 통합 구현 절차/검증/완료기준 - 작업일지: 19:xx 분석 + 일일요약 추가 (원격 PLC PC I/O Check 섹션 병합) - 소스 미수정 (문서만) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.9 KiB
6.9 KiB
작업지시서 — Recipe & Page Change 소스 수정 및 적용 테스트
- 작성일: 2026-06-20 (명일 2026-06-21 작업용)
- 대상:
Machines/ILSOS_PrismaticRD_PTOP/Sequences/SeqAutoRunPTOP.cs - 근거 분석:
docs/분석/2026/06/20/191351_recipe_page_통합신호_핸드셰이크_재구성_분석.md(8장 = 확정안) - 관련:
132647_uframe_가접_recipe_추가_seqautorun_분석.md,133714_recipe전환시_scout필드_이전레시피_잔존_분석.md - 현재 상태: 소스 미수정 (분석/프리뷰만 존재). 본 지시서대로 구현 착수.
목적: 현장 PLC가 Recipe·Page 신호를 동시에 주는 환경에 맞춰, 비대칭 4노드 핸드셰이크를 단일 PAGE 게이트 1노드로 통합한다. + 매 사이클 조건부 레시피 활성화 + Layers stale(race) 방지.
0. 착수 전 확정 사항 (PLC 담당/현장과 먼저 합의)
아래 3개는 코딩 시작 전에 값이 확정돼야 한다. 미확정이면 해당 부분 TODO로 두고 진행.
- C-1. PC_PAGE_CHANGE_COMPLETE 극성: 현재 코드 관례는
falsewrite. PLC 기대값(active-high/low) 확인. - C-2. 레시피 COMP 비트 불필요 확정: PC_RECIPE_NO 워드 에코만으로 PLC가 만족하는가(레시피 전용 COMPLETE 비트 폐기 OK?).
- C-3. Layers race 대응안 택1: (A) Dispatcher 동기 ReloadRecipe(권장) / (B) 로드완료 신호 폴링 / (C) DataModel 레시피Id 키.
1. 작업 범위 (Scope)
1-1. 변경 대상 파일
Machines/ILSOS_PrismaticRD_PTOP/Sequences/SeqAutoRunPTOP.cs(메인)- (대응안 A 선택 시) 시퀀스에서
RecipeHelper.ReloadRecipe동기 호출 경로 확인 —WeldingComponents/.../RecipeHelper.cs,MainPage.cs는 읽기만(수정 지양).
1-2. 제거 (통합으로 흡수)
- 노드 4개:
CheckRecipeNo,CheckRecipeNoComp,CheckPageNo,CheckPageNoComp - 상수 4개:
SEQ_CHECK_RECIPENO,SEQ_CHECK_RECIPENO_COMPLETE,SEQ_CHECK_PAGENO,SEQ_CHECK_PAGENO_COMPLETE - Flow 2줄:
CheckRecipeNo→CheckPageNo(REQ OFF 우회), 루프백CheckCycleStop→CheckRecipeNo
1-3. 추가
- 노드 1개:
CheckPageHandshake(+ 상수SEQ_CHECK_PAGE_HANDSHAKE) - 필드:
private short _prevRecipeNo = -1; - 헬퍼:
ReadWordVerified(eWordInput, times)(3회 검증 공통화),EnsureLayersReloaded(recipe)(대응안 A) - Flow:
... > CheckInitCondition > CheckPageHandshake > SetUploadWeldingList..., 루프백CheckCycleStop > CheckPageHandshake
2. 구현 절차 (Step)
Step 1. 단일 핸드셰이크 노드 골격
CheckPageHandshake추가. 동작 순서:PLC_PAGE_CHANGE_REQ(0x08) ON 블로킹 대기 (기존CheckPageNo패턴 재사용, RECIPE_REQ 미감시)PLC_RECIPE_NO,PLC_PAGE_NO각 3회 더블체크 →plcRecipeNo,plcPageNo,_CurrentPageNo = plcPageNo - 1- CellId/LotId 읽어 Status 반영 (기존
CheckPageNoComp로직 이식)
Step 2. 조건부 레시피 활성화 (가드)
recipeChanged = (plcRecipeNo != _prevRecipeNo) || (ActivatedRecipe()?.Id != plcRecipeNo)recipeChanged == true일 때만:recipe = _RecipeManager.Recipes().FirstOrDefault(x => x.Id == plcRecipeNo)(없으면 알람+return null)_RecipeManager.ActivateRecipe(recipe.Id, "PLC Recipe Change")EnsureLayersReloaded(recipe)← Layers 교체 "완료"까지 보장 (대응안 A)
else동일 레시피 → 활성화/재로드 스킵- 끝에
_prevRecipeNo = plcRecipeNo; - 첫 사이클(
_prevRecipeNo == -1)은 항상 1회 활성화.
Step 3. ★ Layers race 대응 (대응안 A — EnsureLayersReloaded)
ActivateRecipe만으로는 캔버스Model.Layers가 즉시 안 바뀜(UI Dispatcher 2-홉 비동기).- 대응안 A: 시퀀스에서 직접 동기 로드 후 진행.
Application.Current.Dispatcher.Invoke(() => RecipeHelper.ReloadRecipe(recipe.Name)); // 이중 로드 방지: 자동 체인(RMSHandlerForPTOP)과 겹치지 않도록 호출 위치/중복 확인 - 검증 기준은
ActivatedRecipe().Id일치가 아니라Model.Layers가 새 레시피로 교체 완료.
Step 4. Page 검증 (레시피 활성화 "후")
int recipePageCount = _ScannerCanvasUserCtrl.Model.Layers.Count();if (plcPageNo < 1 || plcPageNo > recipePageCount) { 알람/에러 + return null; }- 상한 하드코딩 금지 — 페이지는 사용자가 얼마든지 추가 가능.
Layers.Count()만 신뢰.
Step 5. 에코 + 완료비트
WriteWord(PC_RECIPE_NO, plcRecipeNo),WriteWord(PC_PAGE_NO, plcPageNo)WriteBit(PC_PAGE_CHANGE_COMPLETE, <C-1 확정값>)— PAGE COMPLETE 하나만 (레시피 COMP 비트 미사용, C-2)EVENT_AUTO_RUN_UPDATE_PAGENUM퍼블리시(기존 유지)
Step 6. Builder/Flow 정리
- 1-2 제거, 1-3 추가 반영.
Draw("SeqAutoRunPTOP.pdf")갱신 확인.
Step 7. (선택, 별도 작업) 가접 패스
- 본 지시서 범위 밖. 가접은 Case B면
ExecuteWelding에 선행 패스 추가(132647 문서). 별도 지시서로 분리 권장.
3. 검증 (Test)
3-1. 빌드
- MSBuild Debug|x64 솔루션 빌드 오류 0개.
3-2. 시퀀스 동작 테스트 (Seq 동작 테스트)
- 동일 레시피 + 페이지만 변경 반복: 레시피 활성화/ReloadRecipe 스킵 로그 확인, 페이지별 용접리스트 정상.
- 레시피 변경 사이클: RecipeNum 바뀐 사이클에만 활성화, Layers가 새 레시피로 교체된 뒤 용접리스트 생성되는지(=stale 아님) 확인.
- 페이지 수 다른 레시피 전환(예: 2페이지 ↔ 5페이지) 시
Layers.Count()가변 검증 정상. - PAGE_REQ → 에코(PC_RECIPE_NO/PC_PAGE_NO) → PAGE COMPLETE 핸드셰이크 PLC와 정상 종결.
- 잘못된 PageNo(범위 밖) 수신 시 에러/알람 처리.
3-3. 실제 Laser 동작 확인 (명일 병행)
- 레시피·페이지 정합 상태에서 실제 발진 라인이 해당 페이지 티칭과 일치.
4. 리스크 / 주의
- 이중 로드: 대응안 A의 수동 ReloadRecipe와 자동 체인(RMSHandlerForPTOP)이 겹쳐 2회 로드될 수 있음 → 호출 위치 정리.
- Dispatcher 데드락: 시퀀스 스레드에서
Dispatcher.Invoke(동기) 시 UI 대기 교착 주의 → 필요시InvokeAsync+완료대기 검토. - COMPLETE 극성 오설정(C-1) 시 PLC 핸드셰이크 영원히 안 끝남 → 착수 전 확정.
- 레시피축 stale은 어제(133714) 필드 저장 경로에서 이미 한 번 겪음 — 같은 비동기 갱신 타이밍 이슈축.
5. 완료 기준 (Definition of Done)
- 4노드 → 1노드 통합, 빌드 0 오류.
- 동일레시피 스킵 / 레시피변경 시 Layers 교체완료 후 용접리스트 생성, 둘 다 런타임 확인.
- PLC 핸드셰이크(에코+PAGE COMPLETE) 정상 종결.
- 실제 Laser 발진이 레시피×페이지 정합.
- 작업일지 기록 + 커밋/푸시.