- FieldHelper.json 분석 및 selectedIndexNo stale 버그 원인 정리 - A안(SeqScoutNormal PageIndex 주입) 수정안 작업지시서 작성 (소스 미수정, null 가드 포함) - 작업일지 16:30 항목 + 주말 출근(06.20~06.21) 기록 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
18 KiB
18 KiB
작업일지 — 2026-06-19
09:27
- External/Aurora/bin 을 git 커밋 대상에 포함시킴 (전역
bin/무시는 유지, negation 예외 처리).gitignore에!/External/Aurora/bin/,!/External/Aurora/bin/**두 줄 추가.gitignore자체가/.gitignore로 무시되어git add -f로 강제 추가- Aurora bin 산출물 14개 파일 + .gitignore 함께 커밋 (
7f464ab)
- 위 커밋 규칙을
docs/GIT_RULES.md로 문서화- bin 무시/예외, .gitignore 자체 커밋(-f) 규칙 정리
architecture.md에@import ./GIT_RULES.md연결 (목차 7번 추가)- 커밋 후 push (
de0c1c2)
09:39
- WPF 빌드 자동 생성 임시 파일
*_wpftmp.csproj를.gitignore에 추가AuroraPLC_2pjacgrp_wpftmp.csproj는 sln/csproj 어디에도 참조되지 않는 빌드 산출물 → 커밋 대상 아님- 매번 git status에 안 뜨도록
*_wpftmp.csproj무시 처리, push (3724007)
- 그 외 정리: rules.md 규칙 5번 .md 영문 작성 요건 제거(
3293455), PtoP PLC 인터페이스 xlsx(260617) 삭제(7cb6525) 커밋·push
09:47
- 어제 필드가 좁았던 부분 Scan Field size 변경하던 곳 위치
- 프로그램상 Setting - SystemParameterILSOS - Scout 영역의 Scan field size (캔버스 영역 지정)
- 어제 그 레시피에서 캔버스 크기가 작았던 이슈 때문에 수정한 부분으로, 이 위치가 캔버스(Scan field) 크기를 수정하는 곳임
10:00
- Recipe > Laser Shot > Laser Control - Guide Beam Status 의 Guide Beam 버튼 동작 소스 분석
- UI/바인딩:
WeldingComponents/WeldingCommon/Views/Recipes/UCScannerObjectTeachingControlBox.xaml의 Guide Beam 버튼 → ViewModelCMD_LaserGuideBeam(DelegateCommand) →PerformCmdLaserGuideBeam()호출 (ViewModel: 같은 폴더UCScannerObjectTeachingControlBoxViewModel.cs) - 버튼 핸들러(토글 동작):
PerformCmdLaserGuideBeam()(456~463줄)_Laser.GetPilotLaserSetBitStatus()가 false 면_Laser.PilotLaserOn(), true 면_Laser.PilotLaserOff()- 즉 현재 파일럿(Guide) 레이저 set 비트 상태를 보고 ON/OFF 를 번갈아 보내는 토글 버튼
- 디바이스 추상화:
_Laser는AuroraDevices/AuroraLaser/Laser.cs의 베이스Laser(DeviceManager[CommonDeviceIds.Laser]). 베이스는 IsSimul 이면 OK, 미활성/null 이면 GENERIC(GuideBeam 미동작), 아니면 내부ILaser구현체로 위임. 구체 타입은eLaserTypeconfig 로 결정(ArmLaser/TruPulse/IPG_IO/Trumpf_IO 등) - 실제 하드웨어 제어(예: IPG_IO
AuroraDevices/AuroraLaser/IPG/LaserIPG_IO.cs):PilotLaserOn()→SetLaserDOCommand(eADOAddress.GuideLaserEnable, true)→ IO보드WriteDoBit(GuideLaserEnable, true)PilotLaserOff()→ 같은 DO 비트를 false 로 Write → 가이드 빔 OFF
- 상태 표시(Guide Beam Status): ViewModel
OnMonitoring()타이머가_Laser.GetPilotLaserStatus()를 주기 폴링하여IsGuidBeam바인딩 갱신. IPG_IO 는 파일럿 DI 핀맵이 없어GuideLaserEnableDO 상태를 그대로 읽어 표시 - 주의:
OnMonitoring()의 TODO 주석대로 일부 Laser 디바이스는GetPilotLaserStatus()미구현 → 항상 false. 이 경우 버튼으로 DO 는 나가도 Status 표시는 갱신되지 않을 수 있음
- UI/바인딩:
10:21 — Guide Beam DO 주소 정합 (DO 3 → DO 17) 수정 및 현장 검증 대기
배경 / 문제
- 현장에서 가이드빔(적색광)이 안 나옴 → 원인 분석 결과 모니터링/제어가 보던 DO 비트가 실제 제어선과 불일치
- 기존 소스: 버튼·모니터링 모두
_Laser경로로eADOAddress.GuideLaserEnable(Ajin enum = raw 3)을 사용 - 현장 확인(도연님): 실제 가이드빔 제어선은 DO 17(EX_Red_Control). DO 3 은 PLC 인터페이스3 용으로 가이드빔과 무관
- DI 결선 없음 → 모니터링은 DO(명령) 신호를 그대로 표시하는 구조
분석 정리
- 동작 체인: Guide Beam 버튼 →
CMD_LaserGuideBeam→PerformCmdLaserGuideBeam()→ (기존)_Laser.PilotLaserOn/Off→ IO Laser 는GuideLaserEnable(raw 3) DO Write. 모니터링은OnMonitoring()타이머가GetPilotLaserStatus()(raw 3 DO read) →IsGuidBeam CommonDeviceIds.IODevice == "IO_Board"(EquipDefCommon.cs:115) → ViewModel_IODevice와 IO Laser 가 쓰는 보드 동일(PTOP=PAIX_PTOP)- IO 기반 Laser(IPG_IO/TruPulse_IO/Trumpf_IO/Arm_IO)는
GetPilotLaserStatus()구현되어 있음(미구현은 NL202/Rapid/YLPN/TrueDisk/TrumpfCore) - 현장 Laser 타입 = IO 기반
수정 내용 (커밋 보류 — 현장 검증 후 결정)
- 파일:
WeldingComponents/WeldingCommon/Views/Recipes/UCScannerObjectTeachingControlBoxViewModel.cs OnMonitoring()(174~181줄):_Laser.GetPilotLaserStatus()→_IODevice.ReadDO(17)+ IO 미연결 가드(미연결 시 false)PerformCmdLaserGuideBeam()(457~464줄):_Laser.PilotLaserOn/Off→_IODeviceDO 17 토글(현재값 읽어 반전)- 효과: 버튼이 쓰는 비트와 모니터링이 읽는 비트가 동일 DO 17 → 버튼/직접 SetBit 어느 쪽으로 켜도 Status 동기화
- 빌드 산출물: WeldingCommon.dll (현장 소스 덮어쓰기 시 재빌드 후 실행 폴더 반영 필요)
현장 검증 체크리스트
- 현장 PC 에 수정 소스 덮어쓰기 후 WeldingCommon 재빌드
WeldingCommon.dll실행 폴더 반영- Guide Beam 버튼 클릭 → 화면 Guide Beam Status 점등(ON) 확인 → 실패(변경 안 됨)
Guide Beam 버튼 재클릭 → Status 소등(OFF) 확인- DO 17 직접 SetBit → Status 동기화 확인 → 실패(모니터링이 DO 17 을 보는 것도 아님)
- 실제 가이드빔(적색광) 점등 여부 확인 → 점등 안 됨
현장 검증 결과 (실패 → 원복)
- 결론: DO 17 은 가이드빔 제어선이 아님. 버튼으로 변경도 안 되고, 모니터링이 DO 17 을 보는 것도 아니었음
- 수정분(
UCScannerObjectTeachingControlBoxViewModel.csOnMonitoring/PerformCmdLaserGuideBeam)git checkout으로 원복 (커밋 안 한 상태였음) - DO 3 / DO 17 모두 실제 가이드빔 제어선이 아닌 것으로 확인 → 실제 제어선 DO 주소 재확인 필요
TODO / 후속
- 현장 IO 인터페이스(결선)에서 실제 가이드빔 제어 DO 주소 재확인 (DO 3·17 아님)
- 주소 확정 후 동일 방식(버튼 write + 모니터링 read 동일 비트)으로 재시도
- 추후 실제 점등 피드백 DI 결선 추가되면, 명령 DO 대신 피드백 DI 로 표시하도록 전환 검토
11:03 — TeachingRun 인터락 알람 분석 + 알람부 종합 분석
TeachingRun 차단 원인 (현장 로그)
SeqComponentTeachingRun시작 시CheckCondition_Interlock()의HasAlarmLevelHigh()가 true → "Clear Heavy Alarms For Welding!" + 알람 202003 → FORCE_ERROR- 원인 = 현장 PLC 미연결 → SeqAlarmMonitor가 PLC Deactivated/Disconnect(H) 알람 set → latch로 남아 인터락
- 임시조치:
SeqComponentTeachingRun.csCheckCondition_Interlock()의 H알람 블록 주석 처리(테스트용, 원복 예정) → 레이저 출사 확인 완료
알람부 종합 분석 문서 작성
- 문서:
docs/분석/2026/06/19/110333_alarm_subsystem_analysis.md - 내용: 클래스 구조, 핵심 메서드(set-once/시뮬우회/Unknown=H/Clear전체일괄), 생성·전파 흐름, 시퀀스별 알람 참조표, 알람 코드 표, 리스크 6종, SeqAlarmMonitor self-clearing 개선안
- 핵심 리스크: 알람 latch(조건 해소 시 자동 Clear 없음) → PLC 재연결돼도 수동 ClearAll 전까지 인터락 지속
TODO / 후속
- 현장 MX Component 연결 설정 후 PLC 연결 → 중알람 자연 해소 여부 확인 (별도 분석 진행 중)
- 알람 인터락 블록 원복 (현장 PLC 정상화 후)
SeqAlarmMonitorself-clearing 개선 검토 (AlarmManager 공통 수정 → 승인 필요)
11:13 — MX Component PLC 연결 설정 분석
- 문서:
docs/분석/2026/06/19/111326_mxcomponent_plc_connection_analysis.md - 핵심: 연결 = 논리국번(Logical Station Number) 1개로 결정
- PC의 MX Component Communication Setup Utility 에 등록한 논리국번 ↔ 소스
_config_device/PLC.json의ConnConfig.StationNumber(기본 1, Gun 예시 22) 일치 필요 - 드라이버:
AuroraMXComponent/MXComponent.cs→ActUtlType64Class.ActLogicalStationNumber설정 후 Open
- PC의 MX Component Communication Setup Utility 에 등록한 논리국번 ↔ 소스
- PLC측 요청: CPU 기종 / 접속방식(CPU내장이더넷·이더넷모듈·CC-Link IE 등) / IP·포트 / MELSOFT 접속 허용
- 메모리맵 CSV 8종(
External/PLC/PLC_DeviceMap_*.csv)은 연결과 별개지만 데이터 정합 필요 — PTOP는 repo에 없음(현장 전용) - 연결되면 PLC 미연결 중알람 해소 → 단 latch라 ClearAll 1회 필요할 수 있음
12:22 — AjinIO.ReadDoBit(int) 미구현 분석 (스텁 유지 결정)
- 파일:
AuroraDevices/AuroraIO/Vendor/AJINEXTEK/AjinIO.csReadDoBit(int index)(496줄~) - 현황: bool 반환
ReadDoBit(int)만 미구현 스텁(return true). DO 읽기 API(AxdoReadOutport)는 같은 파일 469줄·GetDoArray에서 이미 검증됨 - 스텁 의존 호출처:
UCInformationPanelViewModel.cs5곳(ModeKeySolOn/SafetyDoorRelease 상태표시) — 전부 ePDOAddress(PAIX) → PAIX 보드 실행, PAIX는 정상 구현 → Ajin 스텁 실제 의존 코드 사실상 없음 - 결정: 스텁(
return true) 유지 + 구현(ReadDiBit 패턴)은 주석으로 보존 → 동작 변화 없음(현장 안전), 추후 활성화 용이 - 빌드 산출물: AuroraIO.dll
- 분석 문서:
docs/분석/2026/06/19/122201_ajinio_readdobit_analysis.md
12:47 — 가이드빔 제어 경로 추적 (IO → Laser/TruPulse) 및 미구현 확인
진행 경위
- 레시피 Guide Beam 을
_IODeviceDO 17(EX_Red_Control) read/write 로 수정 → 상태표시(읽기)는 동작, 물리 빔은 안 나옴 - 번들(DBW-MC)
RedLight Opened/Closed이벤트는 번들 RedClosed 버튼 수동조작 결과, DO 17과 무관 (Mod1_IO 비트만 일치) - → DO 17(IO) 경로는 가이드빔 제어가 아님. 레이저 타입 = TruPulse
핵심 발견 (TruPulse 가이드빔 미구현)
- 경로:
_Laser.PilotLaserOn()→ (TruPulse)PilotOnOffFunc→ExtPilotOnOff(레이저 IO 보드 write 의도) - 상태:
GetPilotLaserStatus()→PilotLaserEnable← TruPulseDi2 bit9 ExtPilotOnOff/ExtLaserEnable/ExtLaserDisable가 선언만 되고 할당부 없음(미구현 TODO)- 시뮬(현재): 베이스 no-op → 빔 안 나옴(정상) / 실모드: null → NRE 위험
- 현재 Laser 디바이스 = 시뮬레이션, 제어는 레이저 IO 보드로 한다고 함
처리 / 결정
- 레시피 DO 17 변경분 원복 안 함 — 필요 시 도연님이 주석 토글로 운용 (기존
_Laser코드 주석 보존됨) - IO 미연결 가드(
IsConnected)는 현장PC에서 동작 안 해 주석(개발PC에서 해제) — LaserReady 패턴과 동일 - 분석 문서:
docs/분석/2026/06/19/124752_guidebeam_trupulse_analysis.md
금일 작업 정리 (커밋 대상)
- 코드(미커밋):
AjinIO.cs(ReadDoBit 스텁 유지+구현 주석),SeqComponentTeachingRun.cs(중알람 인터락 임시 주석),UCScannerObjectTeachingControlBoxViewModel.cs(Guide Beam DO 17 + 가드 주석) - 분석 문서 4종: 알람부 / MX Component / AjinIO ReadDoBit / 가이드빔 TruPulse
- → 커밋·push (
3b8799a)
13:57 — Recipe View 진입 크래시 수정
- 증상: 빌드 후 Recipe View 진입 시 앱 종료(
0xe0434352, 미처리 CLR 예외), 로그에System.Exception(AuroraIO.dll) - 원인:
OnMonitoring()의IsGuidBeam = _IODevice.ReadDO(17);가 try/catch 밖에 있어, IO 보드 미연결(시뮬/개발PC)에서_iOUnit==null→ ReadDO 예외 → DispatcherTimer 틱에서 미처리 → 앱 종료- LaserReady(
ReadDI)는 try 안이라 안 터졌고, Guide Beam만 try 밖이라 터짐
- LaserReady(
- 수정:
IsGuidBeam = _IODevice.ReadDO(17);를 try 블록 안으로 이동 + catch 에서IsGuidBeam=false- → 가드 토글 불필요, 현장/개발 PC 모두 안전
- 함께:
AjinIO.ReadDoBit(int)스텁(return true) →AxdoReadOutport실제 구현 활성화(도연님) - → 커밋·push (
8bfeb73)
14:31 — ScoutNormal moveSleepTime 100 → 150 (현장 반영)
- 파일:
WeldingComponents/WeldingCommon/Sequences/Main/SeqScoutNormal.cs:241 - 변경:
moveSleepTime = 100;//50→150;//100;//50(msec) - 이유: Canvas(Scan field) 영역을 넓혀서 Scout Image 이동 시 sleep을 더 줘야 제대로(안정적으로) 촬영됨 (스캐너 Jump 후 정착 시간 확보)
- 흐름: Scanner JumpAbs →
Thread.Sleep(moveSleepTime)→ ChildImage Grab - 빌드 산출물: WeldingCommon.dll
15:04 — Laser Head Theta 각도 인터락 추가
목적
- 레이저 발진 시 헤드 각도(Theta)가 수평/수직이 아니면 발진 차단(인터락)
- 절대값 하드코딩 대신 세팅값 ±허용오차 범위에서만 발진 허용 (수평/수직 둘 다 허용)
변경 내용 (PTOP 로컬, 7파일)
Machines/ILSOS_PrismaticRD_PTOP/Settings/LaserInterlockSetting.cs(신규) —ISettingItem, 세팅 메뉴에 자동 UI인터락 사용(체크박스, 기본 false) / 수평·수직 각도(deg) / 허용오차(±2.5) / PLC 스케일(deg×10, 미확정→세팅화)
EquipDef.cs—SettingIds.LaserInterlock키EquipmentSetup.cs—RegisterSettings에 세팅 등록(메뉴 노출)Alarm/AlarmCode_PTOP.cs—ALARM_LASER_HEAD_THETA_INTERLOCK = 210620Device/PLC/PLCController.Address.cs—eWordInput.HEAD_THETA_POSITION(= D70510, index 10; 기존 EMPTY_10)Sequences/SeqAutoRunPTOP.cs—ExecuteWelding의 Laser Gate ON 직전 인터락- 체크박스 ON 시에만 동작 / PLC 미연결·미활성·스케일0 시 fail-closed(차단) / 알람 호출 try-catch /
return null(발진 차단)
- 체크박스 ON 시에만 동작 / PLC 미연결·미활성·스케일0 시 fail-closed(차단) / 알람 호출 try-catch /
검증
- WeldingCommon→PTOP 빌드 통과(Debug|x64, exit 0)
- 서브에이전트 리뷰로 fail-open 등 지적 → fail-closed·스케일0 가드·알람 방어 보강
raw/deg로그 남겨 실기에서 deg×10 스케일 확인 가능
런타임 설정(별도, 사용자 영역)
- CSV:
D:\ILSOSConfig\ILSOS_PrismaticRD_PTOP\External\PLC\PLC_DeviceMap_Word_Input_D_Device.csvindex10 = D70510 - 알람표:
...\_alarm\AlarmDescriptions.xlsm에 Code 210620 / Level H 행 추가 - 세팅 메뉴에서 "인터락 사용" 체크 + 수평/수직 값 설정
- → 커밋·push (
0e73086)
15:25 — Scout Image Sleep Time 사용자 설정 추가
목적
- ScoutNormal 이미지 스캔 시 같은 행 이동과 행 전환 이동(먼 거리) 의 sleep을 분리
- 두 값을 Recipe View > Scout Image 그룹에서 사용자 입력, 시퀀스가 RowIdx 기준으로 적용
변경 내용 (WeldingCommon, 4파일)
Settings/SystemParameter.cs—[Category("Scout")]ScoutSameRowSleepMs(150) /ScoutRowChangeSleepMs(300)Views/Recipes/UCScannerObjectTeachingControlBoxViewModel.cs— 바인딩 프로퍼티 2개(SetProperty) +SaveScoutSleep()(SettingEntry.Save) + ctor 초기화Views/Recipes/UCScannerObjectTeachingControlBox.xaml— Scout Image 그룹 4→6행, Selected Type↔Run 버튼 사이 입력 2줄, 버튼 그리드 재번호(Row 3/4)Sequences/Main/SeqScoutNormal.csCaptureNextPosition—prevRowIdx추적해isRowChange ? RowChange : SameRow분기 (기존moveSleepTime=150대체)
검증
- WeldingCommon.dll 빌드 통과(XAML 포함, exit 0)
- 서브에이전트 검증 통과(로직·XAML 그리드·VM·인코딩 PASS) → 작업지시서 삭제
- 공유(WeldingCommon)라 같은행은 150(기존 동일), 행 전환 기본 300ms(기존 150) — 타 머신도 영향, Recipe View에서 조정 가능
- → 커밋·push (
e263ab8)
16:30 — ScoutField 페이지별 로드 버그 분석 + 작업지시서 작성 (소스 미수정)
분석 (레시피 데이터 + 코드)
_config_recipe/<레시피>/분석: "Selected Scout Field" 팝업 값의 실제 저장처는FieldHelper.json(페이지 배열, 각 페이지FieldScans80셀=10×8,Enabled=선택 셀)ScannerObjectTeaching.json/LaserScannerTeaching.json/PLCRecipe.json/VisionInspectionRecipe.json은 전부 빈{}(미사용)
- 버그: 페이지 이동해도 그 페이지 필드를 다시 안 불러옴 → 항상 마지막 머문 페이지(보통 Page1) 필드로 ScoutNormal 동작
- 원인:
LoadScoutField()(MainPage.cs:499/502)가 GUI 전역selectedIndexNo만 키로 사용. 이 값은 WinForms 티칭 콤보박스toolStripComboBoxPage_SelectedIndexChanged(1393)에서만 갱신 → 운전(WPF)/자동운전/시퀀스 경로에선 stale - 비대칭: 저장
UpdateScoutField는 라이브SelectedIndex(490) 사용해 페이지별 정상 저장되나, 로드만 stale SeqScoutNormal_InitParam(SeqScoutNormal.cs:373)엔 페이지 인덱스 필드 없음 → 시퀀스가 처리 페이지를 모름
- 원인:
작업지시서 작성 (방식 A 채택, 소스는 미수정)
- 문서:
docs/작업지시서/2026-06-19_ScoutField_페이지인덱스_시퀀스주입.md - A안: InitParam에
PageIndex추가 →MainPage.LoadScoutField(int)오버로드 +GetCurrentPageIndex()(콤보박스 라이브값, fallback ActiveLayer.No) →SeqScoutNormal.cs:151에서_InitParam.PageIndex로 로드 → 호출부 2곳(UCScannerObjectTeachingControlBoxViewModel.cs:251,UCTestSequenceViewModel.cs:361)에서 주입 - null 가드 확정:
LoadScoutField(PageIndex) ?? LoadScoutField() ?? new List<>()(인덱스 초과 시 NRE 방지, 빈 리스트면 스캔 대상 없이 정상 종료) - B안(GUI 콤보박스 동기화)은 위험성으로 제외
- 기존 소스는 주석 처리 / 신규·변경 라인은 의도 주석 표기 형식으로 작성 (Before/After 포함)
- 상태: 도연님이 더블체크 후 git 반영 예정 → 추후 pull 받아 적용 (이번엔 소스 변경/커밋 없음)
주말 출근 예정
- 06.20(토)~06.21(일) 주말 출근 예정