LGES-OC5-PtoP-Welder/Doc/인수인계/260916_자동운전_전환_사전점검.md
NohDoyeon241104 03bf31e38a docs: 자동운전 전환 사전점검 분석 (정적분석)
수동출사에서 자동운전 전환 시 레시피/페이지 이동·출사 경로 정적분석. 소스 무수정·런타임 검증 미실시.

결론: 출사 경로 자체는 정상. 다만 종결부 3노드 미실행(파형·카운트·비트리셋), 자동 경로 Door 인터락 부재, 중알람 정지 ID 불일치가 확인됨.

PLC 확인 4문항(PAGE_COMPLETE 감시 / Door 차단 보장 / REQ OFF 보장 / Resume REQ 재발행) 포함.
2026-09-16 16:24:06 +09:00

18 KiB

자동운전 전환 사전 점검 — 레시피/페이지 이동 및 출사 경로 분석

  • 작성일: 2026-09-16
  • 대상: SeqAutoRunPTOP (Machines/ILSOS_PrismaticRD_PTOP/Sequences/SeqAutoRunPTOP.cs)
  • 배경: 현장에서 현재 수동 출사로 운영 중. PLC 비트 조건에 따른 자동 운전으로 전환했을 때 시퀀스가 레시피/페이지를 스스로 이동해 정상 출사하는지 확인 요청.
  • 방법: 정적 분석 전용. 소스 무수정, 런타임 검증 미실시. 런타임으로 확인한 항목은 하나도 없으며, 모든 판정은 코드 경로 추적 결과다.

1. 결론 요약

출사 자체는 간다. 레시피 전환 → 페이지 전환 → 레이어 선택 → 리스트 업로드 → 발진까지 경로가 끊긴 곳은 없고, 260806~260818 에 들어간 에코 수렴 로직이 레시피/페이지 정합성을 노드 통과 조건으로 잡아주고 있다.

다만 사이클 종결부가 통째로 실행되지 않는다. 용접은 되는데 파형 저장·생산 카운트·출력비트 리셋이 영구히 빠진다. 그리고 자동 경로에는 Door 인터락이 없고, 중알람이 자동운전을 멈추지 못한다.

등급 항목 영향
치명 사이클 종결부 3노드 영구 미실행 파형 미저장 · 생산카운트 미증가 · 출력비트 미리셋
높음 자동 경로에 Door 인터락 없음 문 열림 상태에서도 PC는 출사를 막지 않음
높음 중알람이 자동운전을 정지시키지 못함 정지 대상 시퀀스 ID 불일치
중 REQ/TRIGGER 가 레벨 판정(엣지 아님) 이론상 같은 페이지 재출사 가능
중 빈 페이지 만나면 자동운전 정지 객체 0개 레이어에서 시퀀스 중단
중 bit15 Resume 핸드셰이크 스킵 미구현 Resume 후 PLC 새 REQ 없으면 교착
낮음 디버그 토스트가 매 사이클 표시 운전 중 화면 노이즈
낮음 진단계측 로그 잔존 MC 개별읽기 16회/초, 로그 증가

2. 자동 사이클 흐름 (실제 코드 경로)

Builder() 의 Flows 정의 기준 (SeqAutoRunPTOP.cs:211-253).

Init
 → Sequence_Enter              :293   PC_AUTO_STATUS=ON, 레시피 핸들 확보
 → CheckInitCondition          :350   ★ 항상 RESYNC 로만 분기 (아래 6-C)
 → ResyncRecipePage            :598   재기동 시 PLC 워드로 Recipe/Page 선(先) 확정
 → CheckPageNo                 :689   PLC_PAGE_CHANGE_REQ(0x08) ON 대기  ◄── 사이클 진입점
 → CheckRecipeNoComp           :475   Recipe 수렴: 읽기→ActivateRecipe→Layers reload→에코→되읽기 확인
 → CheckPageNoComp             :953   Page 수렴: 읽기→_CurrentPageNo 갱신→에코→되읽기 확인
                                      + Recipe/Page 동시 최종확인 (어긋나면 Recipe부터 재확정)
 → SetUploadWeldingList_Params :1095  Layers[_CurrentPageNo] 의 객체를 용접 대상으로 선택
 → (SeqUploadWeldingList)      :181   RTC 리스트 생성 (서브시퀀스)
 → GetUploadWeldingList_Result :1159
 → WeldingStartReadBit         :1181  PLC_WELD_TRIGGER_REQ ON 대기
 → PreScoutCheck               :1412  M70509 ON 이면 Scout 실행, OFF 면 스킵
 → WaitWeldingStart            :1221  PC_WELD_TRIGGER_ACK=ON, PC_WELD_COMPLETE=OFF
 → ExecuteWelding              :1244  HeadTheta 인터락 → Gate ON → ExecuteList → Gate OFF
 → PostScoutCheck              :1430
 → WriteWeldComplete           :1464  PC_WELD_TRIGGER_ACK=OFF, PC_WELD_COMPLETE=ON
 → CheckCycleStop              :1379  ★ 무조건 CheckPageNo 로 회귀
      ┊
      ┊ (아래 3노드는 도달하지 않음)
 ┄ SaveResultData              :1478
 ┄ WriteCompletionPLCBit       :1512
 ┄ Complete                    :1530

3. 정상 동작이 확인된 부분

3-1. 레시피 이동

CheckRecipeNoComp (:475-579) 가 워드만 맞추고 끝내지 않는다. PLC_RECIPE_NO 읽기 → 등록 레시피 조회 → ActivateRecipe → WaitRecipeActivated 로 반영 대기 → RecipeHelper.OnActiveReloaded() 를 UI 스레드에서 동기 호출해 Model.Layers 갱신 보장 → PC_RECIPE_NO 에코 → 되읽기로 수렴 확인(:565-567) 후에만 다음 노드로 간다.

미등록 레시피나 0 이면 에코하지 않고 재시도(:516-533)한다. 에코가 안 나가면 PLC 게이트가 열리지 않으므로 잘못된 레시피로 출사가 나갈 수 없다. 설계가 맞다.

3-2. 페이지 이동

CheckPageNoComp (:953-1086) 도 같은 구조다. 추가로 두 가지가 좋다.

  • 페이지 상한을 활성 레시피의 레이어 수로 가변 검증(:998). 하드코딩이 없어 레시피별 2~5페이지에 대응한다.
  • Recipe/Page 동시 최종확인(:1035-1057). Page 수렴 중 PLC가 Recipe를 바꿔버린 260812 케이스를 잡기 위해, Page 확정 후 두 워드를 다시 읽어 둘 다 일치할 때만 통과한다. 어긋나면 Recipe부터 재확정한다.

3-3. 페이지 → 실제 용접 레이어 연결

_CurrentPageNo = p - 1 (:1009) 로 1-base→0-base 변환 후, SetUploadWeldingList_SeqParams 가 Model.Layers[_CurrentPageNo] 의 객체를 선택한다(:1110-1111). Layers 접근을 UI 스레드로 직렬화(:1105)해 레시피 reload 와의 race 를 막아뒀다. 정합한다.

3-4. 출사 게이트

ExecuteWelding (:1244-1377): HeadTheta 인터락 판정 → Laser_REMOTE DO ON → 15ms 대기 → ExecuteList → WaitForListTaskCompleted → Laser_REMOTE OFF → JumpAbs(0,0) 원점 복귀. 게이트 ON/OFF 짝이 맞고, 정지 시에도 OnSeqActionStop (:1786) 에서 OFF 를 보장한다.

정정: WaitForListTaskCompleted(1000) 의 인자 단위는 초다 (ScannerUnit.cs:1095 public void WaitForListTaskCompleted(int timeOut) //단위는 초). 즉 1000초로, 긴 용접이 조기 절단될 위험은 없다. 이전에 "1초 하드코딩"으로 기록해 둔 메모가 있다면 잘못이다. 다만 초과 시 throw(:1104) 하며 ExecuteWelding 에 try/catch 가 없다.


4. 치명 — 사이클 종결부 3노드 영구 미실행

근거

// SeqAutoRunPTOP.cs:1379-1394
private string CheckCycleStop(...)
{
    if (ResumeMode) { ... }
    Log.I($"[CheckCycleStop] 사이클 계속 진행 → CheckPageNo 이동");
    return SEQ_CHECK_PAGENO;        // ← 분기 조건 없음. 무조건 이 한 줄.
}

SEQ_SAVE_RESULT_DATA / SEQ_WRITE_COMPLETION_PLC_BIT / SEQ_COMPLETE 로 가는 경로는 Flows 상 존재하지만(:242-244) 실행 시 선택되지 않는다.

자동 전환 시 실제로 빠지는 것

미실행 위치 결과
SaveScannerRecordFileForamt() :1484 → :1497 스캐너 파형(SaveRecord("AutoRunTDC")) 이 한 번도 저장되지 않음
생산 카운트 증가 :1541-1542 Total/Today 생산수량이 자동운전에서 절대 늘지 않음
RestoreDeviceStatus() :1518 → :1564 PC 출력비트 일괄 리셋 미수행
KEY_SEQUENCE_RESULT 기록 :1487 사이클 성공 여부가 남지 않음

가장 주의할 부수효과 — PC_PAGE_CHANGE_COMPLETE 가 계속 ON

CheckPageNoComp 가 매 사이클 이 비트를 true 로 쓴다(:1076). 이 비트를 false 로 내리는 곳은 RestoreDeviceStatus(:1568) 와 OnSeqActionStop(:1723) 둘뿐인데, 전자는 도달하지 않는다. → 자동운전 중에는 첫 페이지 전환 이후 계속 ON 상태로 latch 된다.

소스 주석(:1069, :1742)은 "PLC 는 이 비트를 보지 않는다(260806 확인)"라고 기록하고 있다. 그 전제가 맞으면 무해하고, 틀리면 2번째 페이지부터 PLC 가 전환 완료를 인지하지 못한다. → PLC 확인 항목 Q1.


5. 높음 — 안전/정지 계통

5-A. 자동 경로에 Door 인터락이 없다

AlarmManager.IsDoorOpen() 호출처를 전수 조사한 결과 수동 경로 2곳뿐이다.

  • SeqComponentTeachingRun.cs:285 (시퀀스 진입 전)
  • SeqComponentTeachingRun.cs:624 (출사 직전 최종 게이트)
  • UCScannerLaserControlViewModel.cs:295/387/516 (메뉴얼 직접 출사)

SeqAutoRunPTOP.cs 전체에 IsDoorOpen / Door 검사가 0건이다. ExecuteWelding(:1244-1377) 어디에도 없다. 즉 자동 운전 중 문이 열려도 PC 는 출사를 막지 않는다.

260902 Door 인터락 작업(ISSUE-260902-01)은 수동 출사 경로만 대상이었으므로 이는 누락이 아니라 범위 밖이었던 것이다. 다만 자동 전환 시에는 차단 책임이 전적으로 PLC/하드와이어에 있다. → PLC 확인 항목 Q2.

5-B. 중알람이 자동운전을 멈추지 못한다 (ISSUE-260828-02, 현재 소스에서 재확인)

// Alarm/AlarmManager_PTOP.cs:25-27
if (alarm.Level == AlarmLevel.H) {
    StopSequence(SequenceIds.SeqAutoRun);     // ← 구 Prismatic 시퀀스
}

실제 운전 중인 것은 SeqAutoRunPTOP 다(UCMainAutoRunViewModel.cs:101, 365). 등록도 두 ID 가 따로 되어 있다(EquipmentSetup.cs:218 vs :225). → H 레벨 중알람이 떠도 자동운전은 계속 돈다. 식별자 1개 교체로 해결되는 사안이지만 미수정 상태다.

추가로 ExecuteWelding 에 알람 검사 자체가 없어, 알람 상태에서도 발진 경로가 열려 있다.

5-C. 참고 — 수동 정지는 정상

OnStopSequenceAutoRun(:449-467) 은 _SeqAutoRunPTOP.Stop() 을 정확히 호출하고, OnSeqActionStop 에서 PC 출력비트 OFF + Laser_REMOTE OFF 까지 수행한다. 이쪽은 문제없다.


6. 중 — 동작 정합성

6-A. REQ / TRIGGER 가 레벨 판정이다 (엣지 아님)

// CheckPageNo :726
if (_PLC.ReadBit(eBitInput.PLC_PAGE_CHANGE_REQ).data) { ... break; }
// WeldingStartReadBit :1195
if (_PLC.ReadBit(eBitInput.PLC_WELD_TRIGGER_REQ).data) { ... break; }

두 대기 노드 모두 "ON 이면 통과"이지 상승엣지를 보지 않는다. CheckCycleStop 이 CheckPageNo 로 루프백할 때 PLC 가 아직 REQ 를 내리지 않았다면 같은 페이지를 다시 읽어 에코하고, TRIGGER_REQ 도 ON 상태면 같은 페이지를 한 번 더 용접한다.

실제로는 260826 진단계측에서 "성공 구간에는 REQ 가 OFF 로 떨어진다"고 관찰된 바 있어 PLC 가 비트를 내려주고 있는 것으로 보인다. 즉 현재 안전은 PLC 타이밍에 의존하고 있고, PC 쪽에는 중복 방지 장치가 없다. → PLC 확인 항목 Q3.

6-B. 빈 페이지를 만나면 자동운전이 멈춘다

// SetUploadWeldingList_SeqParams :1122-1126
if (_SelectedObjectList == null || _SelectedObjectList.Count() == 0) {
    Log.E("[SetUploadWeldingList] No welding objects found! Sequence will fail.");
    return null;                    // ← 시퀀스 중단
}

객체가 하나도 없는 레이어를 PLC 가 지정하면 그 자리에서 자동운전이 끝난다(재시작 필요). 전환 전에 운용 대상 레시피 전 페이지의 객체 수가 0 이 아닌지 확인해 두는 편이 안전하다.

6-C. bit15 Resume 핸드셰이크 스킵이 미구현 (ISSUE-260805-01, 재확인)

// CheckInitCondition :350-365 — 분기 조건 없이
return SEQ_RESYNC_RECIPE_PAGE;

Builder 에 정의된 Resume 스킵 경로 sb.Flows(sb[SEQ_CHECK_INIT_CONDITION] > sb[SEQ_SET_PARAMS_UPLOAD_WELDING_LIST_SEQ]); // :252 는 선택되지 않는 dead code 다.

ResumeMode=true 여도 ResyncRecipePage(:600) 에서 재동기만 건너뛸 뿐, 결국 CheckPageNo 의 PLC 새 REQ 대기로 들어간다. PLC 가 Resume 후 REQ 를 다시 주지 않으면 교착이다. 자동 전환 후 bit15(가변 용접) 운용을 함께 쓸 계획이면 이 항목이 먼저 정리돼야 한다.

6-D. 참고 — HeadTheta 인터락은 체크박스 의존

ExecuteWelding :1253 의 thetaSetting.HeadThetaInterlockEnabled 가 꺼져 있으면 각도 판정 전체가 스킵된다. 자동 전환 전 설정값 확인 필요(fail-closed 는 활성화된 경우에만 적용).


7. 낮음 — 운전 품질

7-A. 디버그 토스트가 매 사이클 뜬다

  • Sequence_Enter :298 — MessageUtil.ShowToast("Sequence_Enter") (기동 시 1회)
  • WeldingStartReadBit :1200 — MessageUtil.ShowToast("PLC_WELD_TRIGGER_REQ : ON") (매 사이클)

둘 다 // 디버그 끝내고 삭제 주석이 달린 채 살아 있다. 연속 자동운전 시 화면에 계속 뜬다.

7-B. 진단계측 로그 잔존

CheckPageNo 의 [진단계측 2026-08-26] region(:701-715, :752-765)이 1초 주기로 BuildHandshakeSnapshot() 을 호출한다. 이 헬퍼는 MC 개별읽기 16회(:788-804)다. page 대기가 길어지는 구간에서 PLC 통신 부하와 로그량이 함께 늘어난다. 원복 표기가 주석에 있으니 자동 안정화 후 제거 대상.

7-C. 정지 시 레시피 롤백

OnStopSequenceAutoRun :462 에서 RecipeHelper.RollbackRecipe() 를 호출한다. 자동 정지 후 활성 레시피가 직전 선택 레시피로 되돌아가므로, 정지 직후 화면 레시피가 PLC 지시와 달라 보일 수 있다. 동작 자체는 의도된 것으로 보이나 현장 혼선 여지가 있어 기록해 둔다.


8. PLC 확인 요청 항목

# 질문 왜 필요한가
Q1 PC_PAGE_CHANGE_COMPLETE(M70008)를 PLC 가 보는가? 본다면 엣지인가 레벨인가? 자동운전 중 이 비트가 계속 ON 으로 latch 된다(4장). 엣지를 본다면 2페이지째부터 전환 인지 실패
Q2 자동 운전 중 Door Open 시 레이저 차단은 PLC/하드와이어에서 보장되는가? PC 측 자동 경로에 Door 검사가 전혀 없다(5-A)
Q3 PLC_PAGE_CHANGE_REQ / PLC_WELD_TRIGGER_REQ 는 PC 응답 수신 후 반드시 OFF 로 내리는가? PC 가 레벨 판정이라 OFF 가 보장돼야 중복 출사가 없다(6-A)
Q4 bit15 Resume 후 PLC 가 새 PAGE_CHANGE_REQ 를 재발행하는가? 재발행이 없으면 Resume 교착(6-C)

9. 자동 전환 전 권고 순서

  1. Q1~Q4 를 PLC 측과 먼저 정리. 특히 Q2(Door)는 안전 항목이라 선행돼야 한다.
  2. 운용 레시피 전 페이지의 객체 수 확인 — 빈 레이어가 있으면 그 페이지에서 멈춘다(6-B).
  3. HeadTheta 인터락 체크박스 상태 확인(6-D).
  4. 첫 전환은 1사이클 단위로 — [CheckCycleStop] 사이클 계속 진행 로그가 뜨는 것을 확인하고, 그 뒤로 [SaveResultData] / [Complete] 가 안 뜨는 것이 현재 정상임을 인지한 상태로 관찰.
  5. 파형 데이터와 생산 카운트가 필요하면 4장 종결부 문제를 먼저 조치해야 한다(현재 ISSUE-260828-01 보류 중).
  6. bit15 가변 용접을 병행할 계획이면 6-C 선행.

10. 로그로 보는 판정 기준

정상 1사이클이면 이 순서로 찍힌다.

[CheckPageNo] PLC_PAGE_CHANGE_REQ 신호 대기 중...
---> [CheckPageNo] Check OK -> PLC_PAGE_CHANGE_REQ : ON
[CheckRecipeNoComp] PLC_RECIPE_NO 수렴 시작
---> [CheckRecipeNoComp] 수렴 완료 (N회차) - PC_RECIPE_NO: [xx]
[CheckPageNoComp] PLC_PAGE_NO 수렴 시작
---> [CheckPageNoComp] 수렴 완료 (N회차) - PC_PAGE_NO: [x], PC_Index: [x-1]
---> [CheckPageNoComp] Recipe/Page 최종 확인 완료 (1회차)
[SetUploadWeldingList] Selected PageNo [x-1] → Layer Name: [...], Object Count: [N]
---> [WeldingStartReadBit] PLC_WELD_TRIGGER_REQ ON 감지
[ExecuteWelding] Laser Gate ON (REMOTE)
[ExecuteWelding] WaitForListTaskCompleted 완료
[ExecuteWelding] Laser Gate OFF (REMOTE)
[WriteWeldComplete] 용접완료 송신 - COMPLETE=true
[CheckCycleStop] 사이클 계속 진행 → CheckPageNo 이동

주의해서 볼 로그:

로그 의미
[CheckPageNoComp] 최종 확인 불일치 반복 PLC 가 확정 후 Recipe/Page 를 계속 바꾸는 중 (260812 패턴)
[CheckRecipeNoComp] 미수렴 반복 에코가 PLC 에 반영되지 않음 — 통신 또는 워드 맵 확인
Invalid PageNo: N (활성 Recipe 페이지 수: M) PLC 지시 페이지가 레시피 레이어 수를 초과
No welding objects found! 빈 페이지 — 여기서 자동운전 종료(6-B)
[진단계측][CheckPageNo] 변화 가 길게 이어짐 REQ 대기 교착 — 스냅샷의 PAGE/REQ 값으로 PLC 스텝 확인
Object Count: [0] 빈 레이어 경고 신호

11. 근거 위치 정리

항목 파일:라인
노드 등록 / Flows SeqAutoRunPTOP.cs:172-253
CheckInitCondition 무조건 분기 SeqAutoRunPTOP.cs:350-365
CheckRecipeNoComp (에코 수렴형) SeqAutoRunPTOP.cs:475-579
ResyncRecipePage SeqAutoRunPTOP.cs:598-668
CheckPageNo (REQ 레벨 대기) SeqAutoRunPTOP.cs:689-777
진단계측 스냅샷 헬퍼 SeqAutoRunPTOP.cs:779-825
CheckPageNoComp (수렴 + 동시 최종확인) SeqAutoRunPTOP.cs:953-1086
페이지 → 레이어 선택 SeqAutoRunPTOP.cs:1095-1126
WeldingStartReadBit (TRIGGER 레벨 대기) SeqAutoRunPTOP.cs:1181-1218
ExecuteWelding (HeadTheta + Gate) SeqAutoRunPTOP.cs:1244-1377
CheckCycleStop 무조건 루프백 SeqAutoRunPTOP.cs:1379-1394
미도달 3노드 SeqAutoRunPTOP.cs:1478-1562
RestoreDeviceStatus SeqAutoRunPTOP.cs:1564-1580
OnSeqActionStop SeqAutoRunPTOP.cs:1713-1800
중알람 정지 대상 ID Alarm/AlarmManager_PTOP.cs:20-28
시퀀스 등록 (SeqAutoRun vs PTOP) EquipmentSetup.cs:218, 225
AutoRun 시작/정지/Resume Views/Main/UCMainAutoRunViewModel.cs:242-342, 449-467
PLC_AUTO_REQ 상승엣지 → 시작 이벤트 Devices/PLC/PLCController.Config.cs:125-131
WaitForListTaskCompleted 단위(초) LASA/GUI/Scanner/ScannerUnit.cs:1095-1107
Door 인터락 (수동 경로에만 존재) SeqComponentTeachingRun.cs:285, 624

12. 관련 이슈

이슈번호 관계
ISSUE-260828-01 본 문서 4장과 동일 건 (종결부 3노드). 현재 보류
ISSUE-260828-02 본 문서 5-B 와 동일 건 (중알람 정지 ID). 현재 OPEN
ISSUE-260805-01 본 문서 6-C 와 동일 건 (bit15 Resume). 현재 OPEN
ISSUE-260820-01 6-A 와 인접 (REQ 선행 / 지연). PLC 회신 대기
ISSUE-260826-01 6-A·6-C 와 인접 (page5→6 REQ 미발행). PLC 문의 발송
ISSUE-260902-01 5-A 의 배경 (Door 인터락은 수동 경로 한정 적용)

본 문서는 정적 분석 결과이며 소스를 수정하지 않았다. 런타임 검증은 수행하지 않았다.