LGES-OC5-PtoP-Welder/docs/작업지시서/2026_06_21_recipe_page_change_구현.md
NohDoyeon241104 6c230f701d docs: Recipe/Page 통합 핸드셰이크 분석·작업지시서 추가 + 작업일지 갱신
- 분석(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>
2026-06-20 21:25:41 +09:00

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 극성: 현재 코드 관례는 false write. 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 추가. 동작 순서:
    1. PLC_PAGE_CHANGE_REQ(0x08) ON 블로킹 대기 (기존 CheckPageNo 패턴 재사용, RECIPE_REQ 미감시)
    2. PLC_RECIPE_NO, PLC_PAGE_NO 각 3회 더블체크 → plcRecipeNo, plcPageNo, _CurrentPageNo = plcPageNo - 1
    3. 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 발진이 레시피×페이지 정합.
  • 작업일지 기록 + 커밋/푸시.