9.8 KiB
레시피/페이지 정합성 인터락 — 수동출사 차단 (2026-09-14)
목적 : AutoRun 진행 중 수동출사(
Run Welding) 시, PLC 가 지시한 레시피·페이지와 어긋난 상태로 레이저가 나가는 것을 막는 인터락의 설계·적용·검증 내역을 남긴다.
- 대상 설비 : PtoP 각형화 단동 용접기 (유니셀)
- 이슈번호 :
ISSUE-260904-03- 커밋 :
f873e06/ 소스 마커 :[레시피/페이지 인터락 2026-09-04]- 관련 이슈 :
ISSUE-260904-02(레시피 저장 교차오염 — 검사 ②의 근거가 되는 구조적 원인)
표기 규칙 (기존 인수인계 문서와 동일)
| 표기 | 의미 |
|---|---|
| 🟩 소스확인 | PC 소스/설정 파일에서 직접 대조해 확인한 사실 |
| 🟦 현장기록 | 현장 로그·시험 기록에 남아 있는 값 |
| 🟨 미확보 | 아직 확인되지 않음. 이어받는 사람이 채워야 할 항목 |
1. 한 줄 요약
작업자는 화면 상단 띠에 뜬 PLC 지시 RECIPE/PAGE 를 보고 손으로 레시피·페이지를 맞춘 뒤
Run Welding 을 누른다. 그 맞춤이 실제로 됐는지 확인하는 코드가 없었다.
→ 버튼 핸들러 맨 앞에서 4종을 검사하고, 하나라도 어긋나면 확인창도 띄우지 않고 차단한다.
2. 어디가 비어 있었나 🟩
페이지 범위 검사·에코 일치·레시피/페이지 동시수렴은 이미 SeqAutoRunPTOP.CheckPageNoComp 에 있다.
비어 있던 것은 자동 시퀀스가 아니라 사람이 손으로 맞추는 구간 두 곳뿐이다.
| 구간 | 기존 검사 | 이번 조치 |
|---|---|---|
| 자동 사이클의 레시피·페이지 수렴 | ✅ CheckPageNoComp |
무수정 |
| 활성 레시피 ↔ 화면에 실제 로드된 레시피 | ❌ 없음 | ✅ 추가 (검사 ②) |
| PLC 지시 ↔ 활성 레시피/현재 페이지 | ❌ 없음 | ✅ 추가 (검사 ③④) |
3. 적용 위치 🟩
WeldingComponents/WeldingCommon/Views/Recipes/UCScannerObjectTeachingControlBoxViewModel.cs
| 항목 | 위치 |
|---|---|
| region 시작 | :509 |
CheckRecipePageBeforeTeachingRun() |
:530-590 |
| 호출부 | :596 — PerformCmdRunTeachingRun 의 첫 줄 |
메서드 1개 + 호출 1줄이 전부다. 시퀀스(SeqAutoRunPTOP)·RecipeHelper·MessageUtil 무수정,
신규 파일 없음.
3.1 순서가 중요하다
PerformCmdRunTeachingRun
① CheckRecipePageBeforeTeachingRun() ← 인터락. false 면 return
② "Start TeachingRun Sequence?" 확인창
③ IsLaserReady 검사
④ 시퀀스 Start
확인창보다 앞이다. 불일치 상태에서는 확인창조차 뜨지 않으므로, 작업자가 습관적으로 [예]를 눌러 통과시키는 경로가 없다.
4. 검사 4종 🟩
| # | 검사 | 판정 기준 | 불일치 메시지 |
|---|---|---|---|
| ① | 활성 == 선택 | RecipeManager.ActivatedRecipe().Name vs RecipeHelper.SelectedRecipe.name |
활성 레시피 [A] ≠ 선택 레시피 [B] |
| ② | 활성 == 실제 로드 파일 | DB.Recipe.Recipe.SelectedRecipeFile 의 폴더명 |
활성 레시피 [A] ≠ 화면 로드 [B] |
| ③ | PLC 지시 RECIPE == 활성 Id | Status.PlcGuideRecipeNo vs active.Id |
PLC 지시 RECIPE [n] ≠ 활성 레시피 번호 [m] |
| ④ | PLC 지시 PAGE == 현재 페이지 | Status.PlcGuidePageNo vs GetCurrentPageIndex()+1 |
PLC 지시 PAGE [n] ≠ 현재 페이지 [m] |
- 비교는 전부
OrdinalIgnoreCase, 빈 값이면 해당 검사를 건너뛴다. - 페이지는 0-base → 1-base 로 보정해서 비교한다(
GetCurrentPageIndex() + 1).
4.1 ②가 가장 강력하다
LASA 는 레시피를 메모리에 1개만 유지한다. 그래서 "활성 레시피"와 "화면에 실제 그려진 내용"이
어긋날 수 있다 — 이것이 ISSUE-260904-02(레시피 저장 교차오염)의 구조적 원인이기도 하다.
판정 기준으로 쓴 DB.Recipe.Recipe.SelectedRecipeFile 은 Recipe.Load() 가 성공했을 때만
세팅되는 실제 로드 이력이라, 이름 문자열보다 신뢰할 수 있다.
4.2 ★ 표시값끼리 비교하는 접근은 무의미하다 🟩
AutoRun 화면의 Page Num 표시값과 실제 용접 대상 레이어는 같은 변수(_CurrentPageNo)에서 나온다.
따라서 "화면 표시값 vs 실제값" 비교는 항상 일치하며 아무것도 잡아내지 못한다.
이어받는 사람에게 : 같은 접근을 다시 시도하지 말 것. 검증의 기준점은 반드시 ①선택 상태 ②파일 로드 이력 ③PLC 지시 — 즉 다른 출처의 값이어야 한다.
5. PLC 지시값은 가접 구간에만 내려온다 🟩
Status.PlcGuideRecipeNo / Status.PlcGuidePageNo 는 short? 이고,
bit15(수동용접) 구간에만 채워진다 (UCMainAutoRunViewModel:223).
화면 상단 띠 표시도 같은 값을 쓴다 (SyncPlcGuide, :96).
→ null 이면 ③④ 를 생략하고 ①② 만 본다. 가접 구간 밖에서 수동출사를 할 때 오탐이 나지 않게 하는 장치다.
PLC 워드를 직접 읽지 않은 이유 : 이 파일은 공용
WeldingCommon이다. 워드 주소를 직접 읽으면 공용 코드가 PTOP 설비에 종속된다. 그래서Status경유만 쓰기로 했다(2026-09-04 협의).
6. 차단 동작 🟩
불일치 항목을 모아서 한 번에 표시한다(재시도 횟수를 줄이기 위함).
| 상황 | 모달 제목 | 본문 |
|---|---|---|
| 활성 레시피 없음 | 출사 차단 |
활성 레시피가 없습니다. |
| 정합성 불일치 | 출사 차단 - 레시피/페이지 불일치 |
다음 항목이 일치하지 않아 출사를 차단했습니다. + 불일치 항목 · 목록 + 레시피와 페이지를 다시 맞춘 뒤 시도하십시오. |
| 검사 중 예외 | 출사 차단 |
레시피/페이지 검증 중 오류가 발생했습니다. + 예외 메시지 |
예외 시 fail-closed(2026-09-04 협의 확정). 검증이 불가능하면 출사를 막는 것이 이 인터락의 목적이다.
HeadTheta인터락(SeqAutoRunPTOP:1251)과는 별개 기능이며 서로 영향이 없다. on/off 설정 항목도 두지 않았다 — 끌 수 있으면 인터락이 아니다.
7. 현장 검증 (완료) 🟦
| 일자 | 내용 | 결과 |
|---|---|---|
| 2026-09-07 | Release 빌드 → WeldingCommon.dll 현장 파일 교체 |
완료 |
| 2026-09-08 | 레시피·페이지 일치 상태에서 수동출사 | 정상 출사 — 오탐 없음 |
| 2026-09-08 | 페이지를 어긋나게 두고 수동출사 | 차단 모달 표시 · 출사 안 됨 |
배포 후 1순위 확인 항목이 "정상 상태에서 확인창이 그대로 뜨는지(오탐 판별)" 였고, 통과했다.
8. 남아 있는 사항 🟨
- bit15 구간 밖에서는 ③④ 가 생략된다. 협의로 의도한 동작이지만, 가접이 아닌 일반 수동출사에서는
PLC 지시와의 대조가 이뤄지지 않는다는 뜻이다. 필요해지면
Status에 지시값을 채우는 구간을 넓히는 쪽으로 손대야 하며, PLC 워드 직접 읽기는 피할 것(§5 사유). - 레시피 번호 비교는
active.Id기준이다. 레시피 폴더명과 Id 가 어긋나는 운영이 생기면 ③이 오탐을 낸다. 현재는 어긋나지 않는다. - 검사 ①의
SelectedRecipe.name이 빈 값이면 조용히 건너뛴다. 이 경로는 현장에서 관측된 적이 없다.
9. 로그 grep 키
| 문자열 | 의미 |
|---|---|
[레시피/페이지 인터락] 통과. |
정상. 활성/페이지/PLC지시 값이 같이 찍힌다 |
[레시피/페이지 인터락] 출사 차단 — |
불일치 차단. / 로 구분된 항목 전체가 남는다 |
[레시피/페이지 인터락] 활성 레시피 없음 |
활성 레시피 미선택 상태에서 출사 시도 |
[레시피/페이지 인터락] 검사 실패 |
예외 → fail-closed. 나오면 원인 조사 필요 |
10. 매뉴얼 반영 (2026-09-14)
산출물 27번 HMI Manual 의 가접용접 덱에 이 인터락을 한 장으로 넣었다.
| 항목 | 내용 |
|---|---|
| 산출물 | Doc/산출물문서/27. HMI Manual_UBISAM_가접용접_매뉴얼_추가_260914_PTOP.pptx |
| 원본 | 같은 폴더 ..._260828_PTOP.pptx (무수정 보존) |
| 변경 | 8장 → 9장. 슬라이드 5 - 04) 레시피/페이지 정합성 인터락 신규 |
| 재번호 | 전 슬라이드 가접 용접 (n/9) · n / 9 · 부제 - 04)~- 08) |
| 생성기 | UnTrackedLocalFiles/manual_view_mockups/gen_gajeop_260914.py (+ gen_interlock_popup.py) |
슬라이드 구성 — 좌측 설명 4항목 + 콜아웃 2개
- Run Welding 시 자동 검사 — 누른 즉시 검사, 불일치면 확인창 없이 차단 (콜아웃 ①)
- 불일치 시 출사 차단 팝업 — 어긋난 항목 나열, 시퀀스 미시작 (콜아웃 ②)
- 검사 4종 — §4 표와 동일
- 차단됐을 때 조치 — 상단 띠 PLC 지시대로 재정렬 후 재시도
🟨 차단 팝업 그림은 실제 화면 캡처가 아니라 코드 기반 목업이다(
popups/InterlockBlockDlg.png). 문구만 소스와 일치시켰다. 현장 캡처를 확보하면 PPT 에서 이미지 도형만 교체하면 되고, 콜아웃·설명문은 그대로 유효하다.
가접용접 덱은
gen_27_manual.py계열이 아니라 별도 양식(Google Slides 계열)이다. 다음 개정도 기존 슬라이드를 복제해 텍스트만 갈아끼우는 방식으로 할 것 — 도형 XML 을 새로 쓰면 양식이 어긋난다.
변경 이력
| 일자 | 내용 | 작성 |
|---|---|---|
| 2026-09-14 | 최초 작성. 설계·적용(f873e06)·현장검증(260908) 정리 + 27번 HMI Manual 가접용접 덱 반영(260914) |
노도연 |