11 KiB
작업일지 — 2026-07-23
1. Recipe Laser Shot — Laser Ready / Guide Beam IO 번호 확인 및 상시 ON 레이저 대응
배경
현장 레이저가 기존과 달라 배선을 다른 곳에 물렸고, 레이저 컨트롤러를 상시 ON 상태로 둔 채 그 값을 읽어 TRUE로 유지돼야 레시피 출사 시퀀스가 동작하는 구조로 가야 함. Recipe의 Laser Shot 구간에서 Laser Ready 버튼 / Guide Beam 버튼이 물린 IO 번호 확인 요청.
현재 프로그램 SOURCE는 수정하지 않음 — 분석 및 수정안(DIFF)만 기록.
확인 결과 — 현재 사용 중인 IO 번호
| 항목 | 방향/번호 | enum 의미 | 소스 위치 |
|---|---|---|---|
| Laser Ready 판정(모니터링) | DI 11 && DI 15 | CoreLaser_Laser_Output_State / RingLaser_Laser_Output_State |
UCScannerObjectTeachingControlBoxViewModel.cs:271 |
| Laser Ready 버튼(토글 출력) | DO 9, DO 13 | CoreLaser_Control / RingLaser_Control |
같은 파일 :552~567 |
| Guide Beam 상태 표시 | DO 17 (읽기) | EX_Red_Control |
같은 파일 :270 |
| Guide Beam 버튼(토글) | DO 17 (쓰기) | EX_Red_Control |
같은 파일 :534~542 |
| 출사(TeachingRun) 게이트 | IsLaserReady == false → 차단 |
— | 같은 파일 :415~418 |
- Guide Beam은 DI가 없어 DO 17 명령 비트를 되읽어 표시(실제 빔 출력 피드백 아님).
- Laser Ready 판정 IO 변천:
DI 9→DI 12 && DI 24(260617) →DI 11 && DI 15(260618, 현재).
현재 구조가 상시 ON 레이저와 안 맞는 이유
- DO9/DO13 토글은 더 이상 Ready 성립 조건이 아님(안 눌러도 Ready여야 하고, 눌러도 무의미).
- 판정은 새로 물린 DI를 상시 읽어 TRUE 유지하는 형태여야 함.
- 변경 포인트는 271행 판정식(필수) + 버튼 의미 재정의(선택) 두 곳뿐.
작성한 수정안 (미적용)
- 판정 DI를 파일 상단 상수(
DI_LASER_READY_MAIN/DI_LASER_READY_SUB)로 추출 → 현장 번호 확정 시 상수만 교체.SUB < 0이면 단일 DI 판정으로 자동 동작. - 점검용
FORCE_LASER_READY(기본 false, true 커밋 금지) 추가. - Laser Ready 버튼: DO9/13 쓰기 차단 + 현재 DI 상태 토스트 안내(구 레이저 복귀 대비 주석 보존).
- 출사 게이트(
PerformCmdRunTeachingRun)는 변경 없음 —IsLaserReady가 TRUE 유지되면 자동 통과. - (별건)
LaserIOControl.csRingLaser_Control_Status = 23→ 실배선 기준24정정 권장.
주의 — DI/DO 실제 의미
인덱스의 실제 의미는 enum이 아니라 런타임 로드되는 DI.csv/DO.csv 맵이 결정한다
(Setting → Device(IODevice) Config의 IOInterfaceMapDI/DO, 소스 하드코딩 없음).
기본 DI.csv는 12=START SWITCH, 24=FAN 8 ALARM, 25=LASER Ready 로 enum과 불일치 가능 → 번호 확정 시 CSV 대조 필수.
잔여·후속 작업
- 현장 신규 배선 Ready DI 번호 확정(단일인지 Core/Ring 2개 AND인지 포함)
- 로드 중인
DI.csv에서 해당 번호 라벨 확인 - 판정부 적용 + 상수값 교체 → Recipe 화면에서 컨트롤러 ON만으로 Ready=TRUE 확인
- TeachingRun(출사)이 버튼 조작 없이 진입되는지 확인
- Guide Beam은 여전히 명령 비트 되읽기 — 신규 레이저에 가이드빔 제어선 별도 존재 시 DO 번호 재확인
(정식 경로 TruPulse
ExtPilotOnOff미구현)
상세 분석서: docs/분석/2026/07/23/Laser_Shot_IO_LaserReady_GuideBeam_분석.md
2. 시퀀스 측 레이저(IO) 인터락 추가 분석 — SeqComponentTeachingRun
Manual 출사를 SeqComponentTeachingRun 으로 돌릴 예정이므로, 시퀀스 안의 레이저 Ready 확인부까지 확인.
소스는 여전히 미수정(분석만).
확인 결과 — Ready 를 보는 곳은 3계층, 그중 실효는 1개뿐
| 계층 | 위치 | 판정 | 효력 |
|---|---|---|---|
| ① 화면 게이트 | ViewModel :415 ← :271 DI11 && DI15 |
IO 기반 | 유일한 실동작 IO 인터락(버튼 클릭 시점 1회) |
| ② 시퀀스 진입 | SeqComponentTeachingRun.cs:473 _Laser.GetLaserReady |
Aurora Laser 디바이스(IO 아님) | 결선과 무관 |
| ③ 출사 직전 | 같은 파일 :561 → LaserReadyResponse() :658 |
return true; 스텁 |
인터락 없음 |
→ 시퀀스 내부에는 IO(DI) 기반 Ready 확인이 없다. 실동작 인터락은 Head Theta(:572~613)뿐.
"Laser Ready" 정의가 3벌로 갈려 있음
- ViewModel
:271= DI 11 && DI 15(Laser_Output_State) LaserIOControl.cs:77= DI 9 && DI 13(Laser_Ready)- 시퀀스
:473= 레이저 디바이스 호출(IO 미사용)
부수 발견
LaserIOControl은 PTOP 에서 dead — IODevice 는PAIX_PTOP등록(EquipmentSetup.cs:153),SeqTestRun.cs:469의as LaserIOControl는 항상 null. 단SeqTestRun은 미사용 파일(확인 완료) → 실동작 리스크 없음.- Auto 경로엔 레이저 Ready 인터락 자체 없음 —
SeqAutoRunPTOP.cs:589는 no-op 이고 호출처도 없음. ePrismaticDIAddress/DOAddressenum 이PAIX_PTOP.cs/LaserIOControl.cs2벌 중복.
수정 방향(미적용) — 판정 1곳 + 호출 3곳
- 공용 게이트
WeldingCommon/Devices/Laser/LaserReadyGate.cs신설(상수 MAIN/SUB/FORCE,IsReady(IODevice)fail-closed) — 구식 csproj 라<Compile Include>수동 추가 필요 - ViewModel
:271→ 게이트 호출 - 시퀀스
:473→_Laser.GetLaserReady대신 게이트 - 시퀀스
:658 LaserReadyResponse()→ 게이트 (출사 직전 재확인 부활) LaserIOControl.GetLaserReady()도 게이트로 위임- Laser Ready 버튼(DO9/13) 쓰기 차단 + DI 상태 토스트
리스크: 4번은 "항상 통과 → 미충족 시 차단"으로 바뀌므로 Ready DI 번호 확정 후 마지막에 적용. Auto 경로 게이트 추가는 양산 정지 리스크가 새로 생기므로 현장 합의 후 별도 결정.
상세: 같은 분석서 §6~§9
3. 아키텍처 검토 — IO 직접 제어 vs Laser 추상화 계층 (학습용)
소스 수정 없음. 개념 정리 + 다음 프로젝트 방향성 기록.
논의
- 차장님 의견: 추상화 레벨이
Laser클래스이므로, 디바이스 등록 시점에 IO 보드를 Laser 에 물리고 IO 주소/비트 맵도 함께 등록해 한 곳에서 관리했어야 함. - PTOP 현실: IO 는
IODevice로 따로 등록 → 화면·시퀀스가 address 를 직접 읽어 개별 제어. - 결론(받은 답변): IO Device 는 IO Device 대로 쓰되 Laser Device 가 IO Device 에 의존적으로 동작하는 게 정석. 이력을 모르면 추적이 어려울 뿐, 사용에는 지장 없음.
확인한 사실
- Aurora 에 IO형 레이저 구현이 이미 존재 —
Laser.cs:90~103의eLaserType.IPG_YLS / Coherent_Arm_IO / Trumpf_IO가DeviceManager["IO_Board"]를 꺼내ILaser구현체에 주입. LaserTrumpf_IO는LaserOn/Off,GetLaserReady,PilotLaser, 300ms 상태 폴링·램프 갱신까지 전부 DI/DO 로 구현돼 있음 → 지금 ViewModel 이 손으로 하는 일이 이미 들어있음.- 단, 계층을 옮겨도 "매번 소스 수정"은 안 없어짐 —
LaserTrumpf_IO도 핀이ePTDIAddressenum 하드코딩. → 문제는 (A) 제어 경로 분산 과 (B) 핀 번호 하드코딩 2개이며 서로 독립.
(B) 해결 수단 — 이미 사용 가능
- 옵션 1(추천, 재빌드 0):
IOUnit.cs:367 GetDiIndex(string id)/:380 GetDoIndex로DI.csv라벨 조회 → 배선 변경 시 CSV 한 줄만 수정. - 옵션 2:
LaserInterlockSetting에 DI 번호 필드 추가 → 세팅 화면에서 변경(재빌드 없음). - 옵션 3(중장기):
LaserConfig확장 + IO형 일원화 — 공용AuroraLaser수정이라 타 장비 회귀 리스크.
다음 방향성
즉효로 옵션 1/2 + 판정 게이트 1곳 수렴 → 안정화 후 게이트 내부를 _Laser.GetLaserReady() 위임으로 교체해 Laser 계층에 흡수.
신규 프로젝트는 처음부터 eLaserType.*_IO 등록 + 핀 맵 Config/CSV 관리.
숙제
CommonDeviceIds.IODevice실제 값이"IO_Board"인지 (Laser.cs가 문자열 하드코딩 조회 → 다르면 IO형 전환 시 NRE)- PTOP 현재
LaserConfig.Type설정값 /Trumpf_IO핀 배치와 실배선 일치 여부 DI.csv에 신규 Ready 신호가 이름으로 등재됐는지(옵션 1 가능 여부)LaserTrumpf_IO.GetLaserReady()는 시뮬에서 false 반환(:273) → 개발 PC 출사 막힘, 전환 시 정책 확인
상세: 같은 분석서 §10~§17
4. 이설·다현장 대응 관점 — "왜 설정화인가"
질문: A공장에 맞춰 놓아도 B공장으로 이설하면 바뀌는 부분이 있는데, 소스 수정으로 대응하는 게 맞나? 답: 맞지 않다. 단 "전부 설정화"도 아니고 값의 종속성으로 3계층 분리가 먼저.
| 계층 | 내용 | 위치 | 이설 시 |
|---|---|---|---|
| ① 설비 고유·불변 | 시퀀스 흐름, 안전 판정 알고리즘, PLC 규약 | 코드 | 안 바뀜 |
| ② 호기·현장 가변 | IO 핀 매핑, PLC IP/국번, 원점·오프셋, 경로, 타임아웃 | 설정(CSV/json) | 여기만 교체 |
| ③ 생산 가변 | 파워·속도·좌표·페이지 | 레시피/모델 | 품종별 |
- 현 문제: ②인 Laser Ready DI 가 ①(코드)에 있음 → 레이저 교체만으로 재빌드. 실제 이번 건에서
DI9 → DI12&24 → DI11&15소스 3회 수정. - Aurora 는 ② 자리를 이미 제공 —
IOUnitConfig.IOInterfaceMapDI/DO,IODevice.cs:252CSV 로드,IOUnit.cs:367 GetDiIndex(string).DI.csv가 저장소에 없다는 것 자체가 "현장 데이터로 관리하라"는 설계 방증. - 권장: 소스 / 현장 프로파일(DI·DO CSV, DeviceConfig, Setting json, 보정파일) 분리 → 이설 시 프로파일만 교체.
단 ① 기동 시 매핑 검증+로그(미등재
-1이면 fail-closed·알람), ② 프로파일 형상관리(공장/호기별 백업) 를 반드시 같이 넣을 것. - 한계선: 인터락 판정 로직 자체는 코드에 유지(현장이 바꿀 수 있는 건 "어느 핀인가"까지). 설정 변경은 권한 제한 + 이력 로그.
- 진행 순서: 게이트 1곳 수렴 → CSV 라벨 조회 → (대체: Setting 노출) → 기동 검증·로그 → 안정화 후 Laser 계층 위임.
상세: 같은 분석서 §18~§23
5. 학습노트 (읽기용 정리본)
소스를 열지 않고도 흐름이 잡히도록 핵심 코드를 옮겨 담은 정리본을 별도 작성.
docs/분석/2026/07/23/레이저제어_구조_학습노트.md
- §0 30초 요약 → §1 Aurora 레이저 계층도 → §2 코드 읽는 순서(①~⑥)
- §3
LaserTrumpf_IO가 DI/DO 로 하는 일(코드 발췌) → §4 구현체가 갈리는 지점(Laser.cs:60~103) - §5 PTOP 실제 등록/화면 코드 → §6 시퀀스 Ready 3계층 + 정의 3벌 표
- §7 문제는 두 개(A 경로 분산 / B 핀 하드코딩, 서로 독립) → §8
IOUnit.GetDiIndex로 이름 조회 - §9 이설 관점 3계층 + 현장 프로파일 → §10 결론 3줄 → §11 셀프 체크 5문항 → §12 숙제