From 3b8799aa51667dbfe0bc67c9d94e95b235cebad1 Mon Sep 17 00:00:00 2001 From: NohDoyeon241104 Date: Fri, 19 Jun 2026 12:49:08 +0900 Subject: [PATCH] =?UTF-8?q?feat/docs:=20=EA=B0=80=EC=9D=B4=EB=93=9C?= =?UTF-8?q?=EB=B9=94=C2=B7=EC=95=8C=EB=9E=8C=C2=B7PLC(MXComponent)=20?= =?UTF-8?q?=EB=B6=84=EC=84=9D=20=EB=B0=8F=20=ED=98=84=EC=9E=A5=20=EC=9E=84?= =?UTF-8?q?=EC=8B=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 분석 문서 4종 추가 (docs/분석/2026/06/19): 알람부 종합 / MX Component PLC 연결 / AjinIO.ReadDoBit / 가이드빔 TruPulse(ExtPilotOnOff 미구현) - AjinIO.ReadDoBit(int): 스텁(return true) 유지 + 구현(ReadDiBit 패턴) 주석 보존 - SeqComponentTeachingRun: 중알람 인터락 임시 주석 (현장 PLC 미연결 우회, 추후 원복) - 레시피 Guide Beam: DO 17 read/write + IsConnected 가드 주석 (필요시 주석 토글 운용) - 작업일지 2026-06-19 정리 Co-Authored-By: Claude Opus 4.8 --- .../AuroraIO/Vendor/AJINEXTEK/AjinIO.cs | 10 ++ .../Manual/SeqComponentTeachingRun.cs | 13 +- ...cannerObjectTeachingControlBoxViewModel.cs | 53 +++++--- .../06/19/110333_alarm_subsystem_analysis.md | 111 ++++++++++++++++ ...11326_mxcomponent_plc_connection_analysis.md | 82 ++++++++++++ .../06/19/122201_ajinio_readdobit_analysis.md | 68 ++++++++++ .../06/19/124752_guidebeam_trupulse_analysis.md | 59 +++++++++ docs/작업일지/2026_06_19.md | 123 ++++++++++++++++++ 8 files changed, 496 insertions(+), 23 deletions(-) create mode 100644 docs/분석/2026/06/19/110333_alarm_subsystem_analysis.md create mode 100644 docs/분석/2026/06/19/111326_mxcomponent_plc_connection_analysis.md create mode 100644 docs/분석/2026/06/19/122201_ajinio_readdobit_analysis.md create mode 100644 docs/분석/2026/06/19/124752_guidebeam_trupulse_analysis.md diff --git a/AuroraDevices/AuroraIO/Vendor/AJINEXTEK/AjinIO.cs b/AuroraDevices/AuroraIO/Vendor/AJINEXTEK/AjinIO.cs index 686ffef..af71ad8 100644 --- a/AuroraDevices/AuroraIO/Vendor/AJINEXTEK/AjinIO.cs +++ b/AuroraDevices/AuroraIO/Vendor/AJINEXTEK/AjinIO.cs @@ -497,6 +497,16 @@ namespace AuroraIO.AJINEXTEK { //현재 사용하지 않아서 추후 구현 return true; + + // [추후 구현] return true 스텁 의존 코드 확인 후 아래로 교체 (ReadDiBit(int) 패턴) + //uint data = 0; + // + //int err = (int)CAXD.AxdoReadOutport(index, ref data); + //if (err != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) + //{ + // throw new Exception(string.Format("ERR_IO_FAIL_TO_GET_BIT;ERROR CODE:{0}", err)); + //} + //return Convert.ToBoolean(data); } public override bool ReadDiBit(int index) { diff --git a/Machines/ILSOS_PrismaticRD_PTOP/Sequences/Manual/SeqComponentTeachingRun.cs b/Machines/ILSOS_PrismaticRD_PTOP/Sequences/Manual/SeqComponentTeachingRun.cs index 0c95add..d7b97f1 100644 --- a/Machines/ILSOS_PrismaticRD_PTOP/Sequences/Manual/SeqComponentTeachingRun.cs +++ b/Machines/ILSOS_PrismaticRD_PTOP/Sequences/Manual/SeqComponentTeachingRun.cs @@ -269,12 +269,13 @@ namespace ILSOS_PrismaticRD_PTOP.Sequences private bool CheckCondition_Interlock() { //// PLC, Data, IO 등 Interlock checking - bool boolian = AlarmManager.HasAlarmLevelHigh(); - if (boolian) { - Log.E($"Clear Heavy Alarms For Welding!"); - MessageUtil.ShowWarningToast(string.Format("Clear Heavy Alarms For Welding!")); - return false; - } + // [임시 우회] 테스트용으로 High(중대) 알람 인터락 주석 처리 — 테스트 후 반드시 원복할 것! + //bool boolian = AlarmManager.HasAlarmLevelHigh(); + //if (boolian) { + // Log.E($"Clear Heavy Alarms For Welding!"); + // MessageUtil.ShowWarningToast(string.Format("Clear Heavy Alarms For Welding!")); + // return false; + //} #warning to KSJ > 지워도 무방해보임 //boolian = AlarmManager.IsPlcDoorOpen(); diff --git a/WeldingComponents/WeldingCommon/Views/Recipes/UCScannerObjectTeachingControlBoxViewModel.cs b/WeldingComponents/WeldingCommon/Views/Recipes/UCScannerObjectTeachingControlBoxViewModel.cs index dd853f5..1d2047e 100644 --- a/WeldingComponents/WeldingCommon/Views/Recipes/UCScannerObjectTeachingControlBoxViewModel.cs +++ b/WeldingComponents/WeldingCommon/Views/Recipes/UCScannerObjectTeachingControlBoxViewModel.cs @@ -171,22 +171,32 @@ namespace WeldingCommon.Views private void OnMonitoring(object sender, EventArgs e) { - // TODO: Laser Device 에 구현된 내용에 따르면, 일부 Laser Device 는 구현이 되어 있지 않은 상태. 항상 false - if (_Laser.GetPilotLaserStatus()) { - IsGuidBeam = true; - } else { - IsGuidBeam = false; - } + // Guide Beam: DI 결선 없음 → 가이드빔 제어 DO 17 명령 비트를 그대로 표시 + // (기존 _Laser.GetPilotLaserStatus()는 DO 3=GuideLaserEnable 을 봤으나, 현장 가이드빔 제어선은 DO 17) + // IO 미연결 가드는 현장PC에서 동작 안 해 주석 (개발PC에서 주석 해제) + //if (_IODevice == null || !_IODevice.IsConnected()) { + // IsGuidBeam = false; + //} else { + // IsGuidBeam = _IODevice.ReadDO(17); + //} + IsGuidBeam = _IODevice.ReadDO(17); + + // [기존 소스 보존] Laser 디바이스 기반 Pilot 상태 (DO 3=GuideLaserEnable) — 일부 Laser 미구현 시 항상 false + //if (_Laser.GetPilotLaserStatus()) { + // IsGuidBeam = true; + //} else { + // IsGuidBeam = false; + //} try { - // 시뮬 아님 + IO보드 없음 → _iOUnit == null → ReadDI에서 NRE로 꺼짐. + // 시뮬 아님 + IO보드 없음 → _iOUnit == null → ReadDI에서 NRE로 꺼짐. - 현장PC 아닌 경우 개발PC에서 주석 해제 (시뮬안하고 레시피 들어갔을 때 프로그램 종료 방지) // IsConnected()가 _iOUnit null/미연결을 체크하므로, 미연결이면 폴링 스킵(꺼짐 방지). - if (_IODevice == null || !_IODevice.IsConnected()) - { - IsLaserReady = false; - } + //if (_IODevice == null || !_IODevice.IsConnected()) + //{ + // IsLaserReady = false; + //} // 변경 후 (260618: IO 결선 변경 12&24 → 11&15) - else if (_IODevice.ReadDI(11) && _IODevice.ReadDI(15)) + if (_IODevice.ReadDI(11) && _IODevice.ReadDI(15)) { IsLaserReady = true; } @@ -455,11 +465,20 @@ namespace WeldingCommon.Views private void PerformCmdLaserGuideBeam(object obj) { - if (!_Laser.GetPilotLaserSetBitStatus()) { - _Laser.PilotLaserOn(); - } else { - _Laser.PilotLaserOff(); - } + // Guide Beam DO 17 토글 — 모니터링도 같은 DO 17 을 읽어 표시 + // IO 미연결 가드는 현장PC에서 동작 안 해 주석 (개발PC에서 주석 해제) + //if (_IODevice == null || !_IODevice.IsConnected()) { + // return; + //} + bool cur = _IODevice.ReadDO(17); + _IODevice._iOUnit.WriteDoBit(17, !cur); + + // [기존 소스 보존] Laser 디바이스 기반 Pilot On/Off 토글 (DO 3=GuideLaserEnable) + //if (!_Laser.GetPilotLaserSetBitStatus()) { + // _Laser.PilotLaserOn(); + //} else { + // _Laser.PilotLaserOff(); + //} } private void PerformCmdLaserReadyCheck(object obj) diff --git a/docs/분석/2026/06/19/110333_alarm_subsystem_analysis.md b/docs/분석/2026/06/19/110333_alarm_subsystem_analysis.md new file mode 100644 index 0000000..8800e3f --- /dev/null +++ b/docs/분석/2026/06/19/110333_alarm_subsystem_analysis.md @@ -0,0 +1,111 @@ +# ILSOS PTOP 알람부(AlarmManager) 종합 분석 — 2026-06-19 + +> 계기: 현장 PLC 미연결 상태에서 `SeqComponentTeachingRun` 시작 시 H(중)알람 인터락(202003)으로 차단됨. +> 본 문서는 알람부 전체 구조·동작·시퀀스 참조·리스크·개선안을 정리한다. + +--- + +## 1. 클래스 구조 + +| 클래스 | 위치 | 역할 | +|--------|------|------| +| `AlarmManager` (base) | `WeldingCommon/Alarm/AlarmManager.cs` | 정적 싱글톤(`_Instance`). 알람 set/조회/시퀀스 정지 | +| `AlarmManager_PTOP` | `PTOP/Alarm/AlarmManager_PTOP.cs` | `StopSequenceByAlarm` — H알람 시 AutoRun 정지 | +| `AlarmCode` / `AlarmCode_PTOP` | `.../Alarm/AlarmCode*.cs` | 알람 코드 상수. PTOP는 base 상속 후 21xxxx 추가 | +| `IAlarmService` (Aurora 프레임워크) | External/Aurora | **활성 알람 목록·설명·레벨(H/L)** 보유 | + +- 알람 **레벨(H/L)** 은 소스 상수가 아니라 **Aurora 런타임 알람 테이블**에 정의됨(코드에 `AlarmLevel.H` 할당부 없음). + +## 2. 핵심 메서드 동작 (주의점) + +- **`Alarm(code)`** (79줄): 이미 활성이면 재set 안 함 → **set-once(중복 없음)**. +- **`HasAlarmLevelHigh()`** (172줄): 활성 알람 중 H 하나라도 있으면 true. **⚠️ Simulation이면 무조건 false**(시뮬은 인터락 우회). +- **`IsAlarmLevelHigh(code)`** (194줄): 설명 모르는 코드(`desc==null`)는 **위험으로 보고 H 취급** → 미정의 코드도 인터락 유발. +- **Clear**: 개별 `ClearAlarm()`은 **빈 함수**(주석만). 실제 해제는 **`ClearAllAlarm()`(전체 일괄)** 뿐. + - 트리거: `SYS_ALARM_RESET_ALL_ALARM` / `EVENT_RESET_ALL_ALARMS_REQUEST` → `_AlarmService.ClearAllAlarm()`. +- **PLC 알람워드 직접쓰기**(`WriteBit(HeavyAlarmStatusAddr..)`)는 AlarmManager 내에서 전부 **주석 처리**됨(대신 SeqStatusMonitor가 수행). + +## 3. 알람 생성·소멸·전파 흐름 + +``` +[생성] SeqAlarmMonitor (상시 주기 감시) + ├ PLC: EMO / Heavy / Door / 통신끊김 + ├ Laser/Scanner/LBAD/OCT/Chiller: Deactivated/Disconnect/Error + └ IO: Leak / null / deactivated + → AlarmManager.Alarm(code) ← set-only, ❌조건 해소 시 Clear 안 함(LATCH) + +[전파] EquipmentSetup.OnSetAlarm(code, isHeavy) (EquipmentSetup.cs:82) + → isHeavy 면 AlarmManager_PTOP.StopSequenceByAlarm(code) → H면 StopSequence(SeqAutoRun) 비상정지 + +[PLC보고] SeqStatusMonitor.UpdateStatus (SeqStatusMonitor.cs:86) + → PC_HEAVY_ALARM_STATUS = HasAlarmLevelHigh(), PC_LIGHT_ALARM_STATUS = HasAlarmLevelLow() + → PLC_ALARM_RESET 입력 시 EVENT_RESET_ALL_ALARMS_REQUEST 발행 → ClearAllAlarm() + +[차단] 각 시퀀스 시작 시 CheckCondition_Interlock() → HasAlarmLevelHigh() H면 시작 거부 +``` + +## 4. 주요 시퀀스별 알람 참조 + +| 시퀀스 | 인터락 체크 | 비고 | +|--------|------------|------| +| **SeqComponentTeachingRun** | `HasAlarmLevelHigh()` → "Clear Heavy Alarms" + 202003 (Door/EMO 주석) | **이번에 막힌 시퀀스** | +| SeqTeachingRun (Common) | `CheckCondition_Interlock()` = **빈 체크(true)** | 알람 체크 없음 | +| **SeqAutoRunPTOP** | `CheckCondition_Interlock()` = **빈 체크(true)** | 차단은 시작이 아니라 OnSetAlarm→StopSequence | +| SeqAutoRunPrismatic / ComponentWeld | 동일 패턴(빈 체크) | | +| ScoutNormal/FlyingVision, UploadWeldingList, ReceiveCellInfo, ReportCellResult, MarkGrid, ScannerCalibration | 대부분 빈 체크 | 공통 시퀀스 | +| **SeqStatusMonitor** | 알람을 **읽어 PLC 출력** + Reset 처리 | 차단 아님 | +| **SeqAlarmMonitor** | 알람을 **생성(set-only)** | latch 원인 | + +> 실제 알람으로 "시작 차단"하는 곳은 `SeqComponentTeachingRun`이 거의 유일. AutoRun 계열은 "운전 중 H알람 발생 시 비상정지" 방식. + +## 5. 알람 코드 표 (추정 레벨 — 권위값은 런타임 테이블) + +| 코드 | 이름 | 용도 | 추정 | +|------|------|------|------| +| 200xxx~203xxx | ALARM_SEQUENCE_* | 시퀀스 결과/초기조건 실패 | 혼합 | +| 203004 | AutoRun_HeavyAlarmOccured | 자동운전 중 중알람 | H | +| 210001/2/3 | PLC Deactivated/Disconnect/**EMO** | PLC 상태/비상정지 | H | +| 210004/5/6 | PLC Light / **Heavy** / Door Interlock | PLC 경/중/도어 | 210005·6 H, 210004 L | +| 210101/2/3 | Scanner Deactivated/Disconnect/Error | 스캐너 | H/혼합 | +| 210201~205 | Laser Deactivated/Disconnect/Error/Warning/**EMO** | 레이저 | 205·201 H, 204 L | +| 210206/7 | Laser Warning/Error MSG | 레이저 메시지(동적) | L/H | +| 210301~303 | LBAD Deactivated/Disconnect/Error | LBAD | H/혼합 | +| 210401~403 | OCT Deactivated/Disconnect/Error | OCT | H/혼합 | +| 210501~503 | Chiller Deactivated/Disconnect/Error | 냉각기 | H/혼합 | +| 210600~604 | IO Null/Deactivated/Disconnect/**Leak**(Scanner/Chiller) | IO보드/누액 | H | +| 210605~614 | IO MC/BoxTemp/ChillerLeak/Fan1~6 | (현재 대부분 주석) | 혼합 | +| 210700~705 | RMS_* 타임아웃/설정 | 레시피 관리 | L 추정 | + +## 6. 리스크 / 개선 포인트 + +1. **알람 Latch (최우선)** — `SeqAlarmMonitor`가 set만 하고 조건 정상화 시 `ClearAlarm` 안 함. → **이번 PLC 미연결 사례**가 정확히 이것: 연결 복구돼도 알람이 남아 차단, 수동 ClearAll 필요. +2. **개별 Clear 부재** — `ClearAlarm()`이 빈 함수 → 전체 일괄 해제만 가능, 특정 알람만 해제 불가. +3. **Unknown=H 취급** — 미정의 코드 활성 시 무조건 H 차단 → 알람 테이블 누락 시 의도치 않은 인터락. +4. **시뮬 우회** — `HasAlarmLevelHigh()`가 Simulation이면 false → 시뮬/현장 동작 차이. +5. **인터락 일관성 부재** — TeachingRun만 알람 차단, 나머지 시작 시퀀스는 빈 체크. 안전 정책 제각각. +6. **Door/EMO 주석** — SeqComponentTeachingRun·UCMainAutoRunViewModel의 Door/EMO 인터락 주석 → 현재 중알람 1종만 차단. + +## 7. 개선 제안 — SeqAlarmMonitor self-clearing + +각 검사 항목을 "조건 나쁨 → Alarm, 조건 좋음 → Clear" 대칭 구조로. 예(개념): + +```csharp +// AS-IS +if (!_Laser.IsActivated) AlarmManager.Alarm(ALARM_DEVICE_LASER_DEACTIVATED); +else { /* clear 없음 → latch */ } + +// TO-BE (self-clearing) — AlarmManager에 개별 ClearAlarm(code) 구현 전제 +if (!_Laser.IsActivated) AlarmManager.Alarm(ALARM_DEVICE_LASER_DEACTIVATED); +else AlarmManager.ClearAlarm(ALARM_DEVICE_LASER_DEACTIVATED); +``` + +- 전제: `AlarmManager.ClearAlarm(int code)` 실구현 필요(현재 빈 함수). `_AlarmService`에 단건 해제 API 확인 후 연결. +- 효과: PLC 재연결 등 조건 복구 시 알람 자동 해제 → 수동 ClearAll 불필요, 인터락 latch 해소. +- 범위: AlarmManager(공통) 수정 → **승인 필요 영역**. 적용 전 별도 협의. + +## 8. 부록 — 이번(PLC 미연결) 사례 요약 + +- PLC 미연결 → `SeqAlarmMonitor`가 PLC Deactivated/Disconnect(H) set → latch. +- `SeqComponentTeachingRun` 시작 → `HasAlarmLevelHigh()` true → 202003, FORCE_ERROR. +- 임시조치: `SeqComponentTeachingRun.CheckCondition_Interlock()`의 H알람 블록 주석(테스트용, **원복 예정**) → 레이저 출사 확인. +- 관련: [[axis-position-interlock-todo]] diff --git a/docs/분석/2026/06/19/111326_mxcomponent_plc_connection_analysis.md b/docs/분석/2026/06/19/111326_mxcomponent_plc_connection_analysis.md new file mode 100644 index 0000000..d6de06e --- /dev/null +++ b/docs/분석/2026/06/19/111326_mxcomponent_plc_connection_analysis.md @@ -0,0 +1,82 @@ +# MX Component PLC 연결 설정 분석 — 2026-06-19 + +> 계기: 현장 PLC 미연결 → 중알람 latch → TeachingRun 인터락 차단. +> PLC를 정상 연결하려면 무엇을 PLC측에 요청하고, PC 소스/설정의 어떤 값을 맞춰야 하는지 분석(수정 없음). +> 관련: [[110333_alarm_subsystem_analysis]] + +--- + +## 1. 연결 메커니즘 (소스 기준) + +- 드라이버: `AuroraDevices/AuroraMXComponent/MXComponent.cs` — Mitsubishi **MX Component** .NET 컨트롤 `ActUtlType64Class` 사용. +- PTOP 등록(`EquipmentSetup.cs:158`): + `new PLCControllerPTOP(PLCDevice, ePLCNetType.MXComponent, IsSimulation, PLCMMapFileType.CSV, AuroraEnv)` +- 연결 흐름: + ``` + PLCBase.DoActivate (PLCBase.cs:80) + → NetworkType == MXComponent + → PLCNet.SetInitParams(connConfig.StationNumber) // = ActLogicalStationNumber + → Open() → _actUtlType.ActLogicalStationNumber = N; _actUtlType.Open() + ``` +- **핵심 파라미터 = `StationNumber` (논리국번 / Logical Station Number)**. + `MXComponent.SetInitParams(int logicalStationNo)` → `_actUtlType.ActLogicalStationNumber = logicalStationNo` (MXComponent.cs:26~29). +- Open 결과: `0x00000000` 성공, 그 외 Hex 에러. `0x0180840B`(타임아웃) 시 1회 재시도(MXComponent.cs:48). + +## 2. 맞춰야 하는 값 — PC측 + +### (A) MX Component "Communication Setup Utility" (별도 PC 도구) +- MX Component 설치 시 함께 깔리는 **통신 설정 유틸리티**에서 **Logical Station Number** 를 등록. +- 등록 시 입력: PLC **CPU 기종**, **접속 경로**(CPU 내장 이더넷 / 이더넷 모듈 / CC-Link IE / USB / 시리얼), **PLC IP/포트**, 네트워크/국번. +- 이 유틸리티에 등록된 논리국번이 실제 통신 경로를 정의함. (소스는 "번호"만 들고, 실 경로는 유틸리티가 보유) + +### (B) 소스/설정 파일 — `StationNumber` 일치 +- 정의: `AuroraDevices/AuroraPLC/PLCBase.Config.cs:37` + `PLCMXComponentConnConfig.StationNumber` 기본값 **1** (주석: "Logical station No. (By PC Tool: Communication Setting Utility)"). +- 실제 값은 **디바이스 config 파일에 저장**: `_config_device/PLC.json` + ```json + { "ConnConfig": { "StationNumber": 22, "UpdateRateMS": 50 } } + ``` + (위는 Gun 예시 = 22. PTOP는 현장 값으로 별도 설정 필요) +- **편집 경로**: 프로그램 내 PLC 디바이스 설정 화면(`UCPLCDevice`)에서도 수정 가능, 또는 위 JSON 직접 편집. +- ⚠️ **(A)의 유틸리티 논리국번 == (B)의 PLC.json StationNumber** 이어야 연결됨. (현장 PLC.json은 repo에 없음 = 현장 전용) + +## 3. PLC측에 요청해야 할 것 + +| 항목 | 내용 | +|------|------| +| CPU 기종 | Q / L / iQ-R / iQ-F 등 정확한 모델 | +| 접속 방식 | CPU 내장 이더넷 / 이더넷 모듈 / CC-Link IE / USB / 시리얼 중 무엇 | +| 네트워크 정보 | PLC **IP 주소 / 포트**, 서브넷, (CC-Link IE면) 네트워크No·국번 | +| MELSOFT 접속 허용 | 이더넷 "MELSOFT 접속" 오픈 설정, 포트 개방(보통 5007/5006 등), 방화벽 | +| 국번 구성 | 멀티 CPU/증설 시 대상 station | + +→ 위 정보를 받아 **(A) Communication Setup Utility에 논리국번으로 등록**하고, 그 번호를 **(B) PLC.json StationNumber** 에 동일하게 넣으면 연결. + +## 4. 메모리맵 CSV (연결과 별개, 데이터 정합용) + +- `PLCMMapFileType.CSV` → `PLCBase.MemMapParser.cs`가 아래 8종 CSV를 읽어 디바이스 주소 매핑: + - `External/PLC/PLC_DeviceMap_Bit_Input_B_Device.csv` / `..._Output_B_Device` + - `..._Bit_Input_M_Device` / `..._Output_M_Device` + - `..._Word_Input_W_Device` / `..._Output_W_Device` + - `..._Word_Input_D_Device` / `..._Output_D_Device` + - 경로: recipePath 기준 `External\PLC\...` (현장 config 폴더). +- 연결(Open)과는 무관하지만, 연결 후 **읽고/쓰는 주소가 PLC 실제 디바이스와 맞아야** 알람/인터페이스가 정상. PTOP는 repo에 맵 CSV 없음(현장 전용) → [[plc-devicemap-260617-pending]] 참고. + +## 5. 점검 순서 (현장) + +1. PLC측에서 **CPU기종·접속방식·IP/포트·MELSOFT 접속 허용** 확보 +2. PC에서 **MX Component Communication Setup Utility** 실행 → 위 정보로 **논리국번**(예: 1) 등록 → 유틸리티 내 "통신 테스트" 통과 확인 +3. `_config_device/PLC.json` 의 `StationNumber` 를 그 논리국번과 동일하게 설정 (또는 PLC 디바이스 설정 화면) +4. 프로그램 재기동 → PLC Activate → 로그 `PLC Open success` 확인 (`Open: 0x00000000`) +5. 연결되면 SeqAlarmMonitor의 PLC Deactivated/Disconnect 알람 조건 해소 → (단, latch라 **ClearAll 1회** 필요할 수 있음, [[110333_alarm_subsystem_analysis]] 참고) + +## 6. 참고 — 에러코드 / 매뉴얼 + +- Open/Close 반환값은 MX Component 표준 Hex 에러코드. `0x0180840B` = 타임아웃(소스에서 1회 재시도). +- 상세 절차·에러표: `Doc/메뉴얼/공통/PLC/21. MX_Component_V4_프로그래밍_매뉴얼.pdf` (Communication Setup Utility / ActUtlType / 에러코드 장 참조). + +## 7. 요약 + +- **연결 핵심 = 논리국번 1개**. PC의 MX Component 유틸리티 등록값 ↔ 소스 `PLC.json StationNumber` 일치 + PLC측 이더넷/접속 허용. +- PLC.json·맵 CSV는 **현장 전용**(repo 없음) → 현장에서 값 세팅 필요. +- 연결되면 PLC 미연결 중알람 해소 → TeachingRun 인터락 정상화 (latch면 ClearAll 1회). diff --git a/docs/분석/2026/06/19/122201_ajinio_readdobit_analysis.md b/docs/분석/2026/06/19/122201_ajinio_readdobit_analysis.md new file mode 100644 index 0000000..5b9dfc3 --- /dev/null +++ b/docs/분석/2026/06/19/122201_ajinio_readdobit_analysis.md @@ -0,0 +1,68 @@ +# AjinIO.ReadDoBit(int) 미구현 분석 — 2026-06-19 + +> 계기: `AjinIO.cs`의 `ReadDoBit(int index)`(bool 반환)가 미구현 스텁(`return true`). +> DI 패턴 대비 분석 후, 현 상태는 **스텁 유지 + 구현 주석 보존**으로 결정(현장 반영 예정). +> 관련: [[110333_alarm_subsystem_analysis]] + +--- + +## 1. 현황 + +- 파일: `AuroraDevices/AuroraIO/Vendor/AJINEXTEK/AjinIO.cs` (보호 영역, 신중 수정) +- DI/DO 오버로드 4종(`IOUnit` 추상): + - `int ReadDoBit(int, ref bool)` (469줄) — `CAXD.AxdoReadOutport` 사용, **구현됨** + - `int ReadDiBit(int, ref bool)` (483줄) — `CAXD.AxdiReadInport`, 구현됨 + - `bool ReadDoBit(int)` (496줄) — **미구현 스텁(`return true`)** ← 대상 + - `bool ReadDiBit(int)` (501줄) — `CAXD.AxdiReadInport`, 구현됨(실패 시 throw) +- 즉 **DO 읽기 API(`AxdoReadOutport`)는 같은 파일에서 이미 검증**됨(469줄·`GetDoArray` 399줄). bool 반환 오버로드만 DO쪽이 비어 있었음. + +## 2. 구현안 (DI 패턴 그대로) + +```csharp +public override bool ReadDoBit(int index) +{ + uint data = 0; + int err = (int)CAXD.AxdoReadOutport(index, ref data); + if (err != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) + throw new Exception(string.Format("ERR_IO_FAIL_TO_GET_BIT;ERROR CODE:{0}", err)); + return Convert.ToBoolean(data); +} +``` +- `ReadDiBit(int)`(501줄)와 완전 동일 구조, API만 `AxdiReadInport → AxdoReadOutport`. + +## 3. 스텁 의존 호출처 분석 (영향 범위) + +`bool ReadDoBit(int)` 호출처 전수: + +| 호출처 | 위치 | 용도 | +|--------|------|------| +| `UCInformationPanelViewModel.cs` | 46, 53, 82, 115, 132 (5곳) | ModeKeySolOn / SafetyDoorRelease **상태 표시** | + +- 5곳 모두 **`ePDOAddress`(PAIX 주소)** 사용 → 실제 **PAIX 보드에서 실행**. +- **PAIX의 `ReadDoBit(int)`는 정상 구현**(PAIXIO.cs:288, `GetDoArray`로 읽음) → 이 호출처는 이미 정상 동작. +- `(int, ref bool)` 오버로드 호출(`UCTestDeviceViewModel.cs:264`)은 Ajin도 구현돼 있어 무관. +- **결론: Ajin 스텁(`return true`)에 실제 의존하는 코드는 사실상 없음.** 영향은 "Ajin 보드 장비에서 위 5개 호출이 도는 경우"로 한정되며, 그 경우 오히려 항상 true가 오표시였음(상태 표시용, 안전제어 아님 → 위험 낮음). + +## 4. 현재 결정 상태 (스텁 유지 + 구현 주석 보존) + +```csharp +public override bool ReadDoBit(int index) +{ + //현재 사용하지 않아서 추후 구현 + return true; + + // [추후 구현] return true 스텁 의존 코드 확인 후 아래로 교체 (ReadDiBit(int) 패턴) + //uint data = 0; + //int err = (int)CAXD.AxdoReadOutport(index, ref data); + //if (err != (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS) + // throw new Exception(...); + //return Convert.ToBoolean(data); +} +``` +- 동작 변화 없음(`return true` 유지) → 현장 안전. 구현은 주석으로 보존해 추후 활성화 용이. +- 빌드 산출물: **AuroraIO.dll**. + +## 5. 후속 (활성화 조건) + +- Ajin 보드 장비에서 DO 상태 표시 정확성이 필요해질 때, 주석 해제 + 위 5개 호출처 회귀 확인. +- 활성화 시 실패 처리(throw) 영향 검토: `ReadDiBit(int)`와 동일 정책이라 일관성은 확보됨. diff --git a/docs/분석/2026/06/19/124752_guidebeam_trupulse_analysis.md b/docs/분석/2026/06/19/124752_guidebeam_trupulse_analysis.md new file mode 100644 index 0000000..8e01d2d --- /dev/null +++ b/docs/분석/2026/06/19/124752_guidebeam_trupulse_analysis.md @@ -0,0 +1,59 @@ +# 가이드빔(Guide Beam) 제어 경로 분석 — TruPulse — 2026-06-19 + +> 계기: 레시피 Guide Beam 버튼/상태가 현장에서 동작하지 않음. IO(DO)→Laser 순으로 추적. +> 결론: 가이드빔은 **Laser(TruPulse) 디바이스 기능**이며, 제어 콜백 **`ExtPilotOnOff`가 미구현(미할당)**. +> 관련: [[110333_alarm_subsystem_analysis]] + +--- + +## 1. 잘못된 경로였던 IO(DO 17) 시도 요약 + +- 레시피 ViewModel(`UCScannerObjectTeachingControlBoxViewModel.cs`)에서 `_IODevice`(메인 IO_Board=PAIX_PTOP)의 + **DO 17(EX_Red_Control)** 을 read/write 하도록 수정 → 상태 표시(읽기)는 동작 확인. +- 그러나 **물리적 가이드빔(적색광)은 출력 안 됨**. +- 현장 확인: 번들(DBW-MC Laser SW)의 `RedLight Opened/Closed` 이벤트는 **번들의 RedClosed 버튼 수동 조작** 결과로, + 우리 DO 17과 무관. `Mod1_IO:000100↔000000` 비트만 DO 17과 일치. +- → **DO 17(IO) 경로는 가이드빔 제어가 아님.** (메인 IO_Board와 레이저 가이드빔 입력은 별개) +- 현 상태: 원복하지 않고 **주석 토글로 필요시 전환**(도연님 운용). 기존 `_Laser` 코드는 주석 보존됨. + +## 2. 실제 경로 = Laser(TruPulse) 디바이스 + +레이저 타입 = **TruPulse** (`eLaserType.TruPulse`, `Laser.cs:70`). + +``` +_Laser.PilotLaserOn() (베이스 Laser, Laser.cs) + └ IsSimul 이면 return E1.OK (no-op) ← 현재 시뮬이라 여기서 멈춤 + └ 실모드: TruPulse.PilotLaserOn() (TruPulse.cs:817) + └ return PilotOnOffFunc(true) + └ (Laser.cs:74) core.PilotOnOffFunc = (on) => ExtPilotOnOff(on) + └ ExtPilotOnOff(true) ← ★ 레이저 IO 보드 write 의도 콜백 +``` + +상태 읽기: +``` +GetPilotLaserStatus() → PilotLaserEnable ← (TruPulse.cs:174) Di2 & (1<<9) + (QueryStatusHwInterface 로 TruPulse 컨트롤러에서 직접 읽음) +``` + +## 3. ★ 핵심 문제: `ExtPilotOnOff` 미구현(미할당) + +- `Laser.cs` 27~29줄에 `ExtLaserEnable` / `ExtLaserDisable` / `ExtPilotOnOff` **선언만** 존재. +- 전체 소스에 **`ExtPilotOnOff = ...` 할당부 없음**(검색 0건). `updateCore` 구독(`UCTruPulseManualViewModel`)도 core 참조만 받고 콜백 미주입. +- 결과: + - **시뮬(현재)**: 베이스에서 no-op → 빔 안 나옴, 상태 항상 true. (정상) + - **실모드**: `ExtPilotOnOff(true)` 호출 시 **null → NullReferenceException** 위험. +- → "레이저 IO 보드로 가이드빔 제어"는 **설계 의도이나 구현 미완(TODO)**. + +## 4. 결론 / TODO + +| 구간 | 상태 | +|------|------| +| 가이드빔 제어 의도 | TruPulse → `ExtPilotOnOff` → 레이저 IO 보드 DO | +| 실제 구현 | ❌ 미구현 (`ExtPilotOnOff` 미할당) | +| 현재 운영 | 시뮬 → no-op (물리 빔 안 나오는 게 정상) | +| 레시피 DO 17(`_IODevice`) 변경 | 잘못된 경로(메인 IO_Board), 원복 안 함 — 주석 토글로 운용 | + +추후 실제 가이드빔 구현 시: +- `_Laser.ExtPilotOnOff = (on) => { 레이저IO보드._iOUnit.WriteDoBit(<가이드빔 DO>, on); return 0; };` 구현 +- "레이저 IO 보드" 디바이스/DO 주소 확정 (메인 PAIX와 별개 여부) +- Laser 디바이스 **비시뮬 + Activated** diff --git a/docs/작업일지/2026_06_19.md b/docs/작업일지/2026_06_19.md index 171fc19..f1860ee 100644 --- a/docs/작업일지/2026_06_19.md +++ b/docs/작업일지/2026_06_19.md @@ -15,3 +15,126 @@ - `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 버튼 → ViewModel `CMD_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` 구현체로 위임. 구체 타입은 `eLaserType` config 로 결정(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 핀맵이 없어 `GuideLaserEnable` DO 상태를 그대로 읽어 표시 + - **주의**: `OnMonitoring()` 의 TODO 주석대로 일부 Laser 디바이스는 `GetPilotLaserStatus()` 미구현 → 항상 false. + 이 경우 버튼으로 DO 는 나가도 Status 표시는 갱신되지 않을 수 있음 + +## 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` → `_IODevice` **DO 17 토글**(현재값 읽어 반전) +- 효과: 버튼이 쓰는 비트와 모니터링이 읽는 비트가 **동일 DO 17** → 버튼/직접 SetBit 어느 쪽으로 켜도 Status 동기화 +- 빌드 산출물: **WeldingCommon.dll** (현장 소스 덮어쓰기 시 재빌드 후 실행 폴더 반영 필요) + +### 현장 검증 체크리스트 +- [x] 현장 PC 에 수정 소스 덮어쓰기 후 WeldingCommon 재빌드 +- [x] `WeldingCommon.dll` 실행 폴더 반영 +- [x] Guide Beam 버튼 클릭 → 화면 Guide Beam Status 점등(ON) 확인 → **실패(변경 안 됨)** +- [ ] ~~Guide Beam 버튼 재클릭 → Status 소등(OFF) 확인~~ +- [x] DO 17 직접 SetBit → Status 동기화 확인 → **실패(모니터링이 DO 17 을 보는 것도 아님)** +- [x] **실제 가이드빔(적색광) 점등** 여부 확인 → **점등 안 됨** + +### 현장 검증 결과 (실패 → 원복) +- **결론: DO 17 은 가이드빔 제어선이 아님.** 버튼으로 변경도 안 되고, 모니터링이 DO 17 을 보는 것도 아니었음 +- 수정분(`UCScannerObjectTeachingControlBoxViewModel.cs` OnMonitoring/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.cs` CheckCondition_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 정상화 후) +- `SeqAlarmMonitor` self-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 +- 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.cs` `ReadDoBit(int index)` (496줄~) +- 현황: bool 반환 `ReadDoBit(int)`만 미구현 스텁(`return true`). DO 읽기 API(`AxdoReadOutport`)는 같은 파일 469줄·GetDoArray에서 이미 검증됨 +- 스텁 의존 호출처: `UCInformationPanelViewModel.cs` 5곳(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 을 `_IODevice` **DO 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` ← TruPulse `Di2 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