PLC가 Page Change bit(0x08) 하나만 트리거로 보내면 Recipe No와 Page No를 함께 읽어 Recipe를 먼저 전환한 뒤 Page를 전환하도록 변경. Recipe Change bit(0x09)는 트리거로 미사용(enum 정의는 보존). - CheckRecipeNo Decision 제거, 흐름 재배선(CheckPageNo→Recipe→Page) - Recipe No 1회 읽기, 0/음수/미등록/동일이면 전환 생략(정지 안 함) - 실제 전환 시 ActivateRecipe 후 Dispatcher.Invoke(OnActiveReloaded)로 Model.Layers 동기 갱신 + 페이지 검증/레이어 선택을 UI 스레드 직렬화 (ActivateRecipe-Layers 비동기 race 차단) - PC_RECIPE_CHANGE_COMPLETE 미사용 처리, PC_RECIPE_NO 에코는 유지 VS Rebuild(Debug|x64) EXITCODE=0 확인. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
143 lines
12 KiB
Markdown
143 lines
12 KiB
Markdown
# 작업일지 — 2026-06-20
|
||
|
||
## 09:41 — Setting 정리: Axis Position Interlock 삭제 + Head Theta Interlock 영어화
|
||
|
||
### 변경 내용 (2파일)
|
||
- `WeldingComponents/WeldingCommon/Settings/SequenceSetting.cs`
|
||
- `[Category("Axis Position Interlock")]` 블록 **전체 삭제** (주석 + 속성 4개)
|
||
- 삭제 속성: `VerticalSector` / `VerticalTolerance` / `HorizontalSector` / `HorizontalTolerance`
|
||
- Serena `find_referencing_symbols` + grep 확인 결과 정의 파일 외 **참조처 없음** → 삭제 안전
|
||
- `Machines/ILSOS_PrismaticRD_PTOP/Settings/LaserInterlockSetting.cs`
|
||
- Head Theta Interlock 항목 `DisplayName` 5개 한글→영어화 (주석은 유지)
|
||
- `인터락 사용`→`Use Interlock` / `수평 각도(deg)`→`Horizontal Angle (deg)` / `수직 각도(deg)`→`Vertical Angle (deg)` / `허용 오차(±deg)`→`Tolerance (±deg)` / `PLC 스케일(deg×?)`→`PLC Scale (deg×?)`
|
||
- `[Category("Head Theta Interlock")]`는 기존부터 영어라 변경 없음
|
||
|
||
### 검증
|
||
- 서브에이전트로 MSBuild 빌드(Debug|x64) — **오류 0개**, 경고 655개(전부 기존·무관)
|
||
- 빌드 로그에 삭제 속성/변경 DisplayName 관련 오류·잔존 참조 없음
|
||
- 빌드 산출물: **WeldingCommon.dll**, **ILSOS_PrismaticRD_PTOP**
|
||
|
||
## 11:xx — AjinIO.IsConnected() 반전 로직 정정 + OnMonitoring 가드 정리
|
||
|
||
### 문제 (분석)
|
||
- 증상: `OnMonitoring()`의 `_IODevice.IsConnected()` 가드가 **시뮬에선 정상, 실제 Ajin 연결 시 동작 안 함**
|
||
- 원인: `AuroraDevices/AuroraIO/Vendor/AJINEXTEK/AjinIO.cs`의 `IsConnected()`가 **반대로 반환**
|
||
- `AxlGetBoardStatus(0)`이 `AXT_RT_SUCCESS`(정상)면 `false`, 에러면 `true` 반환 (파일 내 다른 호출부 관례와 정반대)
|
||
- 시뮬: 보드 없음 → 에러 → 우연히 `true` → 폴링 동작("정상"으로 보임)
|
||
- 실연결: 정상(SUCCESS) → `false` → 207줄 가드가 `return`으로 폴링 통째 스킵 → `IsGuidBeam`/`IsLaserReady` 미갱신
|
||
|
||
### 변경 내용 (2파일, 사용자 직접 수정)
|
||
- `AuroraDevices/AuroraIO/Vendor/AJINEXTEK/AjinIO.cs`
|
||
- `IsConnected()` → `return err == (int)AXT_FUNC_RESULT.AXT_RT_SUCCESS;` 로 정정 (SUCCESS=연결)
|
||
- `WeldingComponents/WeldingCommon/Views/Recipes/UCScannerObjectTeachingControlBoxViewModel.cs`
|
||
- `OnMonitoring()` 정리: 미연결 시 `IsGuidBeam/IsLaserReady=false` 후 `return` 가드를 앞으로 이동
|
||
- 연결 시에만 `ReadDO(17)`·`ReadDI(11)&&ReadDI(15)` 수행 (LaserReady 한 줄로 정리)
|
||
|
||
### 비고
|
||
- `AjinIO.cs`는 공용(AuroraIO.dll) — Ajin 보드 쓰는 타 머신에도 영향(반전 정정이 올바른 방향)
|
||
- 사용자 요청으로 **빌드 검증 생략**
|
||
|
||
## 13:26 — U-Frame 가접 추가 → Recipe 신규 시 SeqAutoRunPTOP 작업구간 분석 (소스 미수정)
|
||
|
||
### 배경
|
||
- 어제 U-Frame 용접 시 **밀착 불량**으로 품질 미달 → 결론: **가접(tack weld) 추가** 후 본접.
|
||
- 현재 샘플 1개에 **테이프**로 임시 고정 검증 중. SW상 결국 **Recipe 1개 추가** 예상.
|
||
- 가접 정의(현장 확인): 본접 전, 부품이 떨어지지 않도록 **Dot/짧은 Line을 미리 출사해 pre-fix**하는 작업.
|
||
|
||
### 분석 결론 (소스 수정 없이 분석만)
|
||
- `Machines/ILSOS_PrismaticRD_PTOP/Sequences/SeqAutoRunPTOP.cs` 노드별 검토
|
||
- **레시피 선택(CheckRecipeNo/Comp)**: 수정 불필요 — `.Id` 1:1 조회, 하드코딩 없음. 레시피 등록 + PLC 번호 송신만 하면 됨
|
||
- **페이지 처리(CheckPageNoComp)**: 수정 불필요 — 레이어 수 기반 가변 검증
|
||
- **리스트 업로드(SetUploadWeldingList)**: 조건부 — 가접이 같은 리스트 추가 오브젝트면 자동 포함
|
||
- **★ 용접 실행(ExecuteWelding, 라인 720)**: 핵심 분기점
|
||
- Case A: 가접 Dot/짧은 Line을 본접보다 **앞 순서 오브젝트**로 추가 → 한 리스트 연속 발진, 코드 수정 불필요(동일 파라미터·연속 Gate일 때)
|
||
- **Case B(이번 케이스 유력)**: 가접을 **별도 선행 패스**(다른 파라미터/별도 리스트)로 분리 → ExecuteWelding 수정, 필요 시 Builder Flow에 가접 전용 노드 추가
|
||
- 한 줄 요약: **레시피 추가 자체는 데이터 구동이라 소스 수정 거의 불필요. 가접을 "별도 동작"으로 돌릴 때만 ExecuteWelding이 작업 구간.**
|
||
|
||
### 결정 필요
|
||
- 가접 파라미터(파워/속도/체류시간)가 본접과 다른가? → 다르면 Case B
|
||
- 신규 레시피 번호(PLC_RECIPE_NO) 체계/매핑 (PLC측 확정 대기와 연계)
|
||
|
||
### 산출물
|
||
- 분석 문서: `docs/분석/2026/06/20/132647_uframe_가접_recipe_추가_seqautorun_분석.md`
|
||
|
||
## 13:37 — 레시피 전환 시 Scout Field가 "이전 레시피 필드"를 가져오는 버그 분석 (개선 필요, 소스 미수정)
|
||
|
||
### 증상 (현장 확인)
|
||
- 어제(06-19) PageIndex 주입 수정(`4a655ec`) 적용 후, 오늘 확인하니 **레시피 전환 시 새 레시피가 이전 레시피의 필드 영역을 그대로 가져옴.**
|
||
- 페이지 인덱스 정합성은 맞았으나 **레시피 단위 정합성**이 깨짐.
|
||
|
||
### 루트 원인
|
||
- `RecipeFieldScan`은 **싱글톤**이고 필드 데이터를 페이지명(`selectedIndex{N}`)으로만 키잉 — **레시피 식별자 없음.**
|
||
- **★ `MainPage.ReloadRecipe()`에서 필드 재로드(`SaveAndLoadFieldScanFromLasaDb()`)가 주석 처리됨** → 레시피를 바꿔도 싱글톤 `fieldScanDatas`가 이전 레시피 값 그대로 유지(stale).
|
||
- 그 결과 `SeqScoutNormal.LoadScoutField(pageIndex)`가 "올바른 페이지 × 이전 레시피 데이터"를 읽음.
|
||
- 어제 수정은 **페이지축 stale**을 고친 것이고, 오늘 버그는 **레시피축 stale**(별개 축).
|
||
|
||
### 개선안
|
||
- **단순 주석 해제는 위험** ⚠️ — `SaveAndLoadFieldScanFromLasaDb()`는 저장→로드 순서라, ReloadRecipe에서 `WorkRecipeFile`이 이미 새 경로로 바뀐 뒤 호출하면 **이전 레시피 stale 데이터를 새 레시피 FieldHelper.json에 덮어써 손상**시킴(주석 처리된 이유로 추정).
|
||
- **권장: "로드 전용" 메서드 추가**(`SaveFieldHelper` 없이 `LoadFieldHelper`만) → `ReloadRecipe`에서 `UpdateWeldingLinesRecipe()`로 Layers 채워진 뒤 호출하여 새 레시피의 FieldHelper.json만 로드.
|
||
- 검토: FieldHelper.json 부재 시 NRE, ChangeScoutImage 동반 필요 여부, PLC Recipe Change(`RMSHandlerForPTOP`) 경로 적용, 전환 시 저장 금지(저장은 필드변경/스카우트/레시피저장 때만).
|
||
- (선택) 근본: 싱글톤에 레시피 식별자 포함 또는 전환 시 명시적 Clear.
|
||
|
||
### 산출물
|
||
- 분석 문서: `docs/분석/2026/06/20/133714_recipe전환시_scout필드_이전레시피_잔존_분석.md`
|
||
|
||
## 13:50~14:xx — 레시피축 stale 수정 적용 + 서브에이전트 교차검증 + 정정
|
||
|
||
### 1차 수정 (불완전)
|
||
- `MainPage.cs`에 로드 전용 `LoadFieldScanFromLasaDb()` 추가 + `ReloadRecipe`에서 호출. 빌드 0 오류.
|
||
|
||
### 서브에이전트 교차검증으로 발견한 핵심 결함 (직접 코드 재확인 완료)
|
||
- **숨은 저장 경로**: `ReloadRecipe → UpdateWeldingLinesRecipe()(MainPage.cs:411) → UpdateLayersInfo() → toolStripComboBoxPage.SelectedIndex 설정(:364) → SelectedIndexChanged 핸들러(:1411) → SaveAndLoadFieldScanFromLasaDb()(:1418)`.
|
||
- 이 시점 싱글톤=이전 레시피(stale), WorkRecipeFile=새 경로 → **SaveFieldHelper가 stale을 새 레시피 FieldHelper.json에 덮어써 디스크 손상.** 1차 수정의 로드는 손상된 파일을 다시 읽어 무력화.
|
||
- 이 손상은 **수정 전부터 잠재**한 기존 거동 → 기존 레시피 전환 반복 시 일부 FieldHelper.json 오염 가능성(현장 점검 권장).
|
||
|
||
## 야간 작업 — PLC Page Change bit 단일 트리거 통합 (Recipe→Page)
|
||
|
||
### 배경/목표
|
||
- 기존: PLC가 Page Change bit(`PLC_PAGE_CHANGE_REQ` 0x08)와 Recipe Change bit(`PLC_RECIPE_CHANGE_REQ` 0x09)를 각각 줘서 Recipe/Page를 따로 처리.
|
||
- 변경: **Page Change bit(0x08) 한 bit만 트리거.** ON되면 Recipe No·Page No를 함께 읽어 **Recipe 먼저 전환 → Page 전환**. 0x09는 트리거로 미사용(enum 정의는 보존).
|
||
|
||
### 변경 파일: `Machines/ILSOS_PrismaticRD_PTOP/Sequences/SeqAutoRunPTOP.cs` (단일 파일)
|
||
- 흐름 재배선: `CheckInitCondition → CheckPageNo(0x08 대기) → CheckRecipeNoComp(레시피 먼저) → CheckPageNoComp(페이지)`. `CheckRecipeNo` Decision(0x09 peek) 노드/메서드/`SEQ_CHECK_RECIPENO` 상수 제거. 루프백·`CheckInitCondition`·`CheckCycleStop` 반환을 `SEQ_CHECK_PAGENO`로 변경.
|
||
- `CheckRecipeNoComp`: `PLC_RECIPE_NO` **1회 읽기**(3회 검증 제거→tact 절감). 0/음수/미등록/현재활성과 동일 → 전환·워드 재기록 생략(시퀀스 정지 없음). 실제 전환 시에만 `ActivateRecipe`+Id폴링 + **`Dispatcher.Invoke(RecipeHelper.OnActiveReloaded)` 동기 Model 갱신** + `PC_RECIPE_NO` 에코.
|
||
- **B-1(race 차단)**: `CheckPageNoComp`의 `Model.Layers.Count()` 검증과 `SetUploadWeldingList_SeqParams`의 레이어 선택을 `Dispatcher.Invoke`로 UI 스레드 직렬화.
|
||
- `PC_RECIPE_CHANGE_COMPLETE` write 3곳(CheckRecipeNoComp/RestoreDeviceStatus/OnSeqActionStop) 모두 제거(미사용 확정). `PC_RECIPE_NO` 에코는 유지.
|
||
|
||
### 핵심 근거 (Serena 추적)
|
||
- `ActivateRecipe`→`SYS_RECIPE_ACTIVATED`(UI dispatcher)→`EVENT_CHANGE_RECIPE_INFO`(UI dispatcher)→`RecipeHelper.OnActiveReloaded`→`MainPage.ReloadRecipe`→`UpdateLayersInfo`에서 `Model.Layers` 채움. 시퀀스(worker)는 `ActivatedRecipe().Id`만 폴링 → Layers 갱신과 **비동기 race**. 노드 순서만 바꾸면 race 악화 → B(동기 reload)+B-1(읽기 UI 직렬화)로 해소.
|
||
|
||
### 검증
|
||
- Serena LSP 진단 0건.
|
||
- 서브에이전트 시나리오 점검 ①무효 recipe+무효 page ②recipe=현재값 ③recipe 0/음수 ④없는 번호 ⑤PC 에코/표시: `short` 음수 recipe는 `==0`이 아니라 "미등록" 경로로 안전 차단 확인. 시2·3 PASS.
|
||
- 결정: **G1(무효/0/음수 recipe = 현 레시피 유지)이 정상**, **G2 `PC_RECIPE_CHANGE_COMPLETE` 미사용**.
|
||
- **VS Rebuild(MSBuild Debug|x64) EXITCODE=0, CS/MSB 에러 0건**(경고는 기존 코드, 이번 변경 무관).
|
||
- 인코딩 UTF-8 BOM+CRLF, 한글 정상.
|
||
|
||
### 후속(참고)
|
||
- page 무효 정지 시 알람/`PC_ERROR_CODE` 기록은 여전히 주석 처리 상태(별도 과제).
|
||
|
||
### 최종 수정 (적용·빌드 검증 완료)
|
||
- `MainPage.cs` 한 파일, 기존 소스 보존:
|
||
1. 가드 플래그 `private bool _suppressPageFieldSync = false;` 추가
|
||
2. 콤보박스 핸들러: `if (!_suppressPageFieldSync) SaveAndLoadFieldScanFromLasaDb();`
|
||
3. `ReloadRecipe`: `UpdateWeldingLinesRecipe()`를 try/finally로 감싸 전환 동안 가드 ON → 저장 스킵, 이후 `LoadFieldScanFromLasaDb()`로 새 레시피 필드만 로드
|
||
- 효과: (a) 전환 중 stale 저장 차단(손상 방지), (b) 새 레시피 필드 정상 로드 → 레시피축 stale 해소
|
||
- 평상시 사용자 페이지 전환은 가드 false라 무영향. WinForms 단일 UI 스레드 동기 발화라 경쟁 없음.
|
||
- **MSBuild Debug|x64 솔루션 빌드: 오류 0개** (경고 212개 전부 기존·무관)
|
||
|
||
### 잔여(선택)
|
||
- 인덱스 불변(0→0) 케이스 ChangeScoutImage 미동반 시 이미지/데이터 불일치 소지(Low~Med)
|
||
- 근본: 싱글톤에 레시피 식별자 도입 또는 전환 시 명시적 Clear
|
||
- 현장: 레시피 전환 → Scout Field 새 영역 반영 런타임 확인, 기존 오염된 FieldHelper.json 점검
|
||
|
||
## 14:xx — 현재 상태 정리 (레시피축 stale 수정 건)
|
||
- **수정 적용 완료**: `WeldingComponents/LASA/GUI/Page/MainPage.cs` (가드 플래그 `_suppressPageFieldSync` + 콤보박스 핸들러 가드 + ReloadRecipe try/finally + 로드 전용 `LoadFieldScanFromLasaDb`)
|
||
- **빌드 검증 완료**: MSBuild Debug|x64 솔루션, 오류 0개
|
||
- **미커밋 상태**: 커밋 전, 현장 런타임 확인 대기 중
|
||
- 다음 액션: ① 현장에서 레시피 전환 시 Scout Field 새 영역 반영 확인 ② 기존 전환으로 오염됐을 수 있는 FieldHelper.json 점검 ③ 확인 후 커밋
|
||
- 산출물: 분석 `docs/분석/2026/06/20/133714_recipe전환시_scout필드_이전레시피_잔존_분석.md` (4-B 교차검증 섹션 포함)
|
||
|
||
## PLC PC I/O Check 완료
|
||
- PLC ↔ PC I/O Check 완료
|