# FieldHelper 격자 배율 차이 — 드로잉↔용접 위치오차 원인 확정 - 작성일: 2026-08-01 - 대상: `_config_recipe/*/FieldHelper.json`, `SystemParameterILSOS.json`, `SeqAutoRunPrismatic.cs` - 계기: 2026-07-30~31 본접 레시피 용접 위치가 원점 기준으로 벌어지는 현상 - 상태: **원인 확정 (소스 수정 없음 — 설정/레시피 데이터 문제)** - 관련 문서: [드로잉_용접_위치오차_배율의심_분석.md](./드로잉_용접_위치오차_배율의심_분석.md), [2026-07-29 ScannerCalibration 분석](../../07/29/ScannerCalibration_MPosOffset_AlignDistortion_파라미터_분석.md) --- ## 0. 결론 기존 레시피(동탄 현장에서 생성)와 신규 레시피의 `FieldHelper.json` **필드스캔 격자 간격이 2.406% 다르다.** 원인은 `SystemParameter`의 **`LensMagnification` 값이 0.3277 → 0.32 로 바뀐 것**이다. 격자는 레시피 생성 시점 값으로 **파일에 고정 저장**되고 재스캔해도 갱신되지 않으므로, 기존 레시피는 옛 배율 격자를 그대로 들고 있다. 결과: **용접 오차 = 2.35% × 원점거리** (원점에서 0, 멀수록 비례 증가) --- ## 1. 비교 대상 | 구분 | 레시피 | 페이지 수 | 비고 | |---|---|---|---| | 정상 | `CC_Welding_Renewal` | 3 | 2026-08-01 신규 생성 | | 이상 | `U-Frame_Back_Pre_Welding` | 6 | 동탄 현장 생성 | 파일: `docs/현장 데이터_260801/_config_recipe/<레시피>/FieldHelper.json` --- ## 2. 측정 — 격자 간격이 다르다 같은 `RowIdx` / `ColIdx` 인데 `MotorPos` 값이 다르다. | 격자 | CC_Welding_Renewal (정상) | U-Frame_Back_Pre_Welding (이상) | |---|---|---| | Col3 X | -9.6000023 | -9.3744278 | | Col4 X | +9.5999985 | +9.3744278 | | Col5 X | 28.799995 | 28.123283 | | Col6 X | 48.000000 | 46.872139 | | Col7 X | 67.200005 | 65.620995 | | **X 스텝** | **19.2000** | **18.748856** | | Row0 Y | 69.119995 | 67.495880 | | Row1 Y | 53.759995 | 52.496796 | | Row2 Y | — | 37.497711 | | **Y 스텝** | **15.3600** | **14.999084** | ``` X: 19.2000 / 18.748856 = 1.0240625 Y: 15.3600 / 14.999084 = 1.0240625 ``` **X·Y 비율이 소수점 7자리까지 동일** → 회전·평행이동이 아니라 **순수 등방 배율(2.406%)**. > 파일 크기 차이(6페이지 vs 3페이지)는 페이지 수 차이일 뿐이며, 페이지당 블록 구조(2806줄)는 양쪽 동일하다. --- ## 3. 원인 — LensMagnification `Rect`는 양쪽 모두 1280 × 1024 px. 스텝을 픽셀로 나누면 픽셀 분해능이 나온다. ``` CC_Welding_Renewal : 19.200000 / 1280 = 15.360000 / 1024 = 0.0150000 mm/px U-Frame_Back_Pre_Welding: 18.748856 / 1280 = 14.999084 / 1024 = 0.0146475 mm/px ``` 소스의 산출식 (`Machines/ILSOS_PrismaticRD_PTOP/Sequences/SeqAutoRunPrismatic.cs:1208`): ```csharp var cameraROIWidth = ((imageWidthChild * _SystemParameter.CameraPixelSize) / _SystemParameter.LensMagnification) / 1000.0; ``` 현장 `_config_setting/SystemParameterILSOS.json` (2026-08-01 기준): ```json "CameraPixelSize" : 4.8, "LensMagnification" : 0.32 ``` | | 계산 | 결과 | |---|---|---| | 현재 설정 | 4.8 / 0.32 / 1000 | **0.015000 mm/px** → CC_Welding_Renewal과 일치 | | 역산 (기존 레시피) | 4.8 / 0.0146475 / 1000 | **LensMagnification = 0.32770** | 검산: `0.32 × 1.0240625 = 0.32770` — 정확히 일치. **→ `LensMagnification` 이 0.3277 에서 0.32 로 변경되었다.** (실측 보정값 → 렌즈 스펙 공칭값으로 교체된 것으로 추정) --- ## 4. 왜 "원점 기준으로" 벌어지는가 `FieldHelper.json` 의 `MotorPos` 격자는 **레시피 생성 시점에 계산되어 파일에 고정 저장**된다. 재스캔해도 저장된 좌표를 그대로 사용한다. > 근거: `U-Frame_Back_Pre_Welding` 페이지0은 2026-08-01 10:04 에 재스캔(`2026_8_1/1_100407.PNG`)했는데도 격자는 18.748856 그대로다. > 반면 09:39 에 스캔한 `CC_Welding_Renewal` 페이지0(`2026_8_1/1_093909.PNG`)은 19.2 이다. > 같은 날 20분 간격 스캔인데 격자가 다르다 = 격자는 스캔 시점이 아니라 **레시피 생성 시점** 값이다. 기존 레시피에서 벌어지는 일: | 단계 | 사용하는 배율 | 결과 | |---|---|---| | 스티칭 이미지 생성 | 저장된 격자 18.7489mm / 1280px | 스테이지가 **실제로 18.7489mm** 이동한 화면을 붙임 | | 티칭 좌표 환산 | 현재 파라미터 0.015 mm/px | 그 1280px 을 **19.2mm 로 해석** | 같은 픽셀 거리를 2.406% 크게 읽는다. 이미지 중심(= 필드 원점)에서는 오차 0, 멀어질수록 비례 증가. ### 오차량 오차 = `1 - 1/1.0240625` = **2.35% × 원점거리** | 원점거리 | 오차 | 해당 레시피 | |---|---|---| | 17mm | 0.40mm | `CC_Welding_Renewal` 도형 최대 반경 | | 27mm | 0.63mm | `CC welding`(구) 도형 최대 반경 | | 30mm | 0.70mm | — | | 66mm | **1.55mm** | `U-Frame_Welding` 라인 끝점 (±66mm) | | 94mm | 2.2mm | `U-Frame_Welding` 모서리 (-74.7, 63.5) | --- ## 5. 현장 시도 결과와의 정합 | 시도 | 내용 | 결과 | 본 분석으로 설명 | |---|---|---|---| | 관찰 | 같은 레시피 다른 페이지에서 원점 기준 벌어짐 | — | 배율 오차의 전형적 신호 | | 1 | CC 레시피에서 Scout 후 Dot 출사 | 정상 | 도형 반경 17mm → 오차 0.4mm | | 2 | CC 파라미터를 본접 레시피에 적용 | **안 맞음** | 파라미터는 좌표 계산에 관여하지 않음 | | 3 | CC 레시피 복사본으로 용접 | 정상 | 복사 시 **새 격자(19.2)까지 승계** | ### 지령좌표 계산 경로에 레시피 종속 항이 없음 (시도2 설명) ``` 지령 = 드로잉좌표(obj.PF1/PF2) + xOffset xOffset = _FlyOffsetX + _ExternalCommandOffset.X ``` | 항 | 값 | 근거 | |---|---|---| | `_FlyOffsetX/Y` | 0 | `Scanner.json` `UseMarkingOnTheFly: false` → `SeqUploadWeldingList.cs:156` | | `angleOffX/Y` | (1.05, -0.1) | SystemParameter Front/Down — 전역 | | `CellCenterOffsetX/Y` | 0 | PTOP에서 주입 경로 없음 (`SeqAutoRunPTOP.cs:647` 읽기만) | | 객체별 `ObjectOffset`/`VisionOffset`/`AlignOffset` | 전부 `{X=0, Y=0}` | 레시피 JSON 실측 | → 모든 레시피가 동일하게 (1.05, -0.1) 만 더해 발진한다. 파라미터·오프셋은 위치 오차 원인이 될 수 없다. --- ## 6. 조치 ### 6.1 즉시 (현장) **재티칭만으로는 해결되지 않는다.** `FieldHelper` 격자가 레시피에 남아 있으면 재티칭해도 동일하게 틀어진다. | 방법 | 내용 | 검증 | |---|---|---| | A (권장) | 레시피 **신규 생성** 또는 정상 레시피 **복사** 후 티칭 | 시도3에서 검증됨 | | B | 기존 레시피의 **필드스캔 격자 재생성** (이미지 재스캔 ≠ 격자 재생성) 후 재티칭 | 미검증 | ### 6.2 대상 레시피 (동탄 현장 생성분) `Bottom-Frame_Welding` · `Top-Frame_Welding` · `Rework-Frame_Welding` · `U-Frame_Welding` · `U-Frame_Back_Welding` · `U-Frame_Back_Pre_Welding` · `U_Frame _pre welding` · `CC welding` · `CDC` · `RMS` · `Test` · `Copy__U-Frame_Welding` 각 레시피의 `FieldHelper.json` 에서 Col3/Col4 X 값이 `±9.6` 이면 정상, `±9.3744` 면 재생성 대상이다. ### 6.3 확인 필요 1. **`LensMagnification` 0.3277 → 0.32 변경이 의도된 것인지** — 언제/누가 바꿨는지 확인. 0.3277 이 실측 보정값이었다면 되돌리는 것이 맞고, 그 경우 **기존 레시피가 정상이고 신규 레시피가 틀린 것**이 된다. 현재 실측 결과(신규 레시피 정상)는 0.32 쪽을 지지하지만, 최종 판단 근거는 렌즈 실측이어야 한다. 2. **mm/px 직접 실측** — 필드스캔 이미지에서 실물 치수를 아는 두 점(예: 100mm 간격 기준홀)의 픽셀 거리를 측정. `0.015` / `0.0146475` 중 어느 쪽인지 즉시 판별된다. 3. 배율 확정 후 `ScannerCalibration` 재실행 여부 판단 — 07-29 캘리는 `Align Distortion = 10mm` 로 수행되어 테이블 정확도가 보장되지 않는다 ([07/29 문서 §3](../../07/29/ScannerCalibration_MPosOffset_AlignDistortion_파라미터_분석.md)). --- ## 7. 재발 방지 | 항목 | 내용 | |---|---| | 운영 규칙 | **`CameraPixelSize` / `LensMagnification` 변경 = 전 레시피 필드격자 무효.** 변경 시 전 레시피 재생성 필요 | | 운영 규칙 | **ct5(보정 테이블) 교체 = 전 레시피 티칭 좌표 무효** | | 개선 제안 | 레시피 로드 시 저장된 격자 간격과 현재 파라미터 산출값을 비교해 불일치 시 경고 | | 개선 제안 | `FieldHelper.json` 에 생성 시점 `CameraPixelSize` / `LensMagnification` 을 함께 기록 | --- ## 부록 — 판별용 수치 ``` 정상 격자 : X 스텝 19.200000 / Y 스텝 15.360000 (0.015000 mm/px, LensMag 0.32) 이상 격자 : X 스텝 18.748856 / Y 스텝 14.999084 (0.0146475 mm/px, LensMag 0.3277) 배율 차이 : 1.0240625 (2.406%) 용접 오차 : 2.35% × 원점거리 ```