클레로보틱스
경력근거: 카메라, 로봇, PLC 등 산업용 장비 연동 및 시스템 통합(SI)
'고객의 제조 현장에서 발생하는 문제를 SW로 해결하고 맞춤형 머신비전 솔루션을 개발 담당' 이 이 자리의 직무 소개이고, 주요업무에는 '카메라, 로봇, PLC 등 산업용 장비 연동 및 시스템 통합(SI)' 과 '고객사 PoC, SW 배포, 디버깅 및 시스템 안정화' 가 있습니다. 카메라가 보정값을 제대로 내도 PLC 트리거가 늦거나 MES 서열과 어긋나면 로봇은 보정 없이 유리를 붙이고, 그 어긋남은 카메라·PLC·MES 기록을 한자리에 모아야 보입니다. 우대사항의 'TCP/IP, OPC UA, Modbus TCP 등 산업용 통신 개발 경험' 과 '산업용 다축 로봇암 제어 및 로봇-카메라 캘리브레이션 경험' 도 같은 자리를 가리키고, 회사 소개는 3D 카메라와 머신비전 솔루션이 '현대차그룹을 비롯한 주요 제조·로봇 산업 현장에 공급되고 있습니다' 라고 적습니다. 공고는 공정 이름을 들지 않으며, 글라스 장착 공정과 로봇 위치보정은 클레로보틱스가 자동차 조립 라인에 공급하는 제품에서 고른 주제입니다. 이 포트폴리오는 PLC 사이클·비전 보정값·생산 서열을 밀리초 시각과 차종 설정으로 맞대는 라인 연동 판정과, 합성 점군에서 유효 점 수와 보정량을 계산하는 구현을 보여줍니다. 완성차 글라스 장착 품질이나 로봇 비전 보정 알고리즘의 전문성은 주장하지 않습니다.
직무 소개가 고객의 제조 현장에서 생기는 문제를 SW 로 해결하는 일이고, 주요업무에 고객사 PoC·SW 배포·디버깅·시스템 안정화가, 자격요건에 국내외 출장과 현장 기술지원이 들어 있습니다. 교대마다 비전 보정값이 제때 맞는 설정으로 왔는지 차량별로 따지는 화면은 안정화 기간에 FDE 가 고객 라인 담당자와 같이 여는 물건입니다.
주요업무가 카메라, 로봇, PLC 등 산업용 장비 연동과 시스템 통합이고, 우대사항이 TCP/IP·OPC UA·Modbus TCP 개발 경험을 듭니다. 이 편은 PLC 사이클 기록과 비전이 로봇에 보낸 보정값을 차량 번호와 스테이션으로 맞추고 밀리초 시각으로 견주며, 2주차에는 PLC 시뮬레이터의 OPC UA 태그와 Modbus TCP 레지스터에서 바로 받습니다.
주요업무에 2D/3D 머신비전과 포인트클라우드 기반 SW 개발이, 우대사항에 OpenCV·Open3D·PCL 과 로봇-카메라 캘리브레이션 경험이 있습니다. 유효 점 수와 보정량은 Open3D 로 합성한 유리 가장자리 점군에서 직접 계산하고, 3주차에는 보정량이 한 축으로 쏠려 가는 추이를 캘리브레이션 점검 신호로 봅니다.
클레로보틱스 3D 카메라(CoPick3D)와 로봇 위치보정 소프트웨어(FineLocalizer)를 들인 완성차 공장의 글라스 장착 공정에 쓰는 관리자 페이지입니다. 고객사 생산기술 담당자는 교대가 끝날 때 열어 재검사로 보낼 차를 고르고, 파견 나온 클레로보틱스 FDE 는 PoC 기간 내내 띄워 두고 늦은 보정값이 어느 시간대에 몰리는지 봅니다. 세단·SUV·해치백·밴을 한 라인에서 섞어 만드는 공장을 가정하고, 앞유리(GL-F)·뒷유리(GL-R) 스테이션의 PLC 사이클마다 비전이 로봇에 보낸 보정값을 차대번호(VIN)로 맞춥니다. 그 보정값이 기한 안에 왔는지, MES 서열의 차종에 맞는 설정으로 찍었는지, 유리 가장자리 점군이 넉넉했는지, 보정량이 상한 안인지 따져 사이클마다 판정 하나를 내리고 근거가 된 시각·점 수·보정량을 보여줍니다.
클레로보틱스 3D 머신비전을 들인 완성차 공장의 글라스 장착 공정 생산기술 담당자와, 그 라인에 PoC·안정화로 파견된 클레로보틱스 FDE. 교대가 끝날 때마다 관리자 페이지에서 차량별 판정을 함께 보고, 보정 없이 지나간 차는 갭·단차 재검사로 보내고, 보정값이 늦게 온 차가 몰린 시간대는 PLC 신호 타이밍을, 차종 설정이 어긋난 차는 MES 서열 연동을 고친다
글라스 장착 로봇은 비전 보정값이 기한 안에 오지 않으면 기본 좌표로 유리를 붙이고, 그 차는 겉으로 멀쩡해 수정 라인에서 갭·단차가 잡히고서야 드러납니다. PLC 는 사이클 시각을, 비전 PC 는 보낸 보정값을, MES 는 서열을 따로 남겨서, 어느 차가 보정 없이 지나갔는지 알려면 FDE 와 생산기술 담당자가 세 기록을 시각과 차량 번호로 손으로 맞춰야 합니다. 사이클마다 비전 결과를 VIN 과 스테이션으로 맞추고 기한·차종 설정·유효 점 하한·보정량 상한을 계산하면, 교대가 끝나는 자리에서 재검사로 보낼 차와 PLC·MES·카메라 가운데 손볼 쪽이 나뉩니다.
생산기술 담당자와 FDE 가 한 교대의 MES 서열, PLC 사이클 기록, 비전 결과 기록, 차종별 비전 설정 네 파일을 올리면 사이클마다 여섯 판정 가운데 하나가 붙고, 차량을 펼치면 사이클 시작에서 기한·비전 도착·로봇 완료까지의 시각 띠와 기대 설정·찍은 설정, 점 수와 보정량이 나옵니다. 걸린 차량은 갭·단차 재검사 목록 CSV 로 내려받습니다. 네 파일은 지원자가 만든 라인 시뮬레이터가 내고, 점 수와 보정량은 Open3D 로 합성한 유리 가장자리 점군에서 계산합니다.
라인 시뮬레이터가 주간조 412대(앞·뒷유리 사이클 824개)를 돌리며 보정 누락·지연·서열 밀림·반사·차체 안착 틀어짐을 정해 둔 사이클에 심고, 그 시나리오 표를 정답으로 판정과 맞댄 리포트가 나옵니다. 같은 교대를 파일 대신 PLC 시뮬레이터의 OPC UA 태그 구독, Modbus TCP 레지스터 읽기, 비전이 로봇에 보내는 TCP/IP 전문 수신으로 받아, 파일로 받은 판정과 같은지 FDE 가 봅니다.
열 교대 분량의 판정을 쌓아 스테이션별로 늦은 보정값이 몰린 10분 구간과 축별 보정량 추이를 보여주고, 한 축으로 쏠린 폭이 정해 둔 값을 넘은 스테이션에는 로봇-카메라 캘리브레이션 점검 표시를 답니다. Claude Sonnet 이 교대 판정표로 고객 라인 담당자에게 보낼 교대 인계 메모 초안을 쓰고, FDE 가 고쳐서 보냅니다.
생산기술 담당자와 FDE 가 주간조 파일 네 개를 올리면 사이클이 여섯 판정으로 나뉘고, SIM-048214 앞유리를 펼치면 사이클 시작 뒤 7,730ms 에 온 보정값이 기한 1,500ms 와 로봇 완료 7,510ms 를 모두 넘긴 시각 띠로 나옵니다.
로봇 완료 시각이 비어 있는 SIM-048215 앞유리, 기한 1,200ms 와 유효 점 하한 4,500개에 꼭 맞춘 SIM-048216 뒷유리, 앞 차 설정으로 찍혀 점 수와 보정량도 같이 걸리는 SIM-048217 을 섞어도 판정이 판정식과 우선순위대로 나옵니다.
깨진 입력 여섯 종, 곧 날짜·밀리초 없이 '08:41:12' 로 적힌 PLC 시각, 'GLF' 처럼 목록 밖 스테이션 표기, '3,820' 처럼 쉼표 든 글자로 저장된 유효 점 수, 소문자 'x' 로 적힌 보정 축, '1.5s' 처럼 단위가 붙은 기한, 열 순서가 바뀐 비전 결과 파일을 넣어도 화면은 열리고, 읽지 못한 줄은 파일 이름과 줄 번호, 이유를 요약 줄의 읽지 못한 줄 칸에 남깁니다.
라인 시뮬레이터가 고장을 심어 둔 주간조 412대, 사이클 824개로 화면 판정이 시나리오 표와 맞은 사이클 수를 셉니다. 단, 고장과 정답을 모두 작성자가 정한 합성 기준이라 성능 검증이 아니라 데모 조건에서의 동작입니다.
위 수치는 작성자가 만든 라인 시뮬레이터 기록의 자가채점이며, 판정이 실제로 맞는 비율은 고객 라인의 PLC 로그와 비전 PC 기록, MES 서열, 생산기술 담당자의 갭·단차 재검사 결과가 있어야 잽니다. 이 포트폴리오는 그 측정을 바로 돌릴 수 있는 상태까지 만듭니다.
라인 시뮬레이터는 PLC 사이클·비전 결과·MES 서열을 한 프로그램이 같은 VIN 으로 찍어서, 시나리오 표에 적지 않은 어긋남은 만들지 못합니다. 주간조 412대에 심은 고장과 그 정답도 제가 정한 시나리오 표에서 나왔으므로 맞은 사이클 수는 제 시나리오를 제 판정식이 다시 읽은 결과라 성능 증명이 아니고, 고객 라인에서 VIN 을 잘못 읽거나 PLC 와 비전 가운데 한 기록만 남는 사이클이 얼마나 되는지는 그 라인의 기록을 받아야 압니다.
로봇 완료 시각이 비어 있는 SIM-048215 앞유리는 늦음 조건에서 완료 시각을 빼고 봐야 판정이 나오고, 기한 경계와 꼭 같은 1,200ms 에 온 SIM-048216 뒷유리는 '넘으면' 을 '이상' 으로 쓰면 늦음으로, 하한과 같은 유효 점 4,500개는 '미달' 을 '이하' 로 쓰면 점군 부족으로 걸립니다. 앞 차 설정으로 찍힌 SIM-048217 은 점 수와 보정량도 같이 걸려 우선순위가 없으면 판정이 셋으로 갈립니다.
로봇 완료 신호는 짧은 펄스라 수집기가 Modbus TCP 로 500ms 마다 읽으면 놓칠 수 있고, 그러면 SIM-048215 처럼 완료 시각이 빕니다. 그 사이클은 기한 조건으로만 판정하고 요약 줄에 따로 세며, 실제 도입에서는 완료 시각을 PLC 안에 붙잡아 두는 태그를 고객 PLC 담당자와 정합니다.
공고는 공정 이름도 로그 형식도 밝히지 않습니다. 글라스 장착 공정, 앞·뒷유리 두 스테이션, 다섯 차종을 섞어 만드는 혼류 라인, 차종별 기한·유효 점 하한·보정량 상한은 이 편의 가정이고, CoPick3D·FineLocalizer 가 실제로 남기는 결과 기록의 열도 모릅니다. 현장에서는 비전 PC 로그와 PLC 태그 목록부터 받아 차량 번호를 맞출 열과 시각 기준을 정합니다.
늦음 판정은 PLC 와 비전 PC 가 같은 시계를 쓴다는 전제 위에 섭니다. 시뮬레이터는 시계 하나로 시각을 찍어 이 차이가 없고, 고객 라인에서 두 장비의 시각이 수백 ms 어긋나 있으면 기한 1,500ms 판정이 통째로 밀리므로 그 차이부터 잽니다.
보정량을 절댓값이 가장 큰 축의 값 하나로 줄인 것은 카드 판정식에 맞춘 단순화이고, 실제 로봇 보정은 이동 세 축과 회전 세 축입니다. 회전 보정이 큰 차체는 이 판정에서 빠질 수 있어, 실제 도입에서는 축별 상한을 기준표에 더합니다.
이 포트폴리오는 장비 기록의 시각 맞추기, 차종 설정 대조, 합성 점군의 유효 점·보정량 계산을 보여줍니다. 완성차 글라스 장착 품질이나 로봇 비전 보정 알고리즘의 전문성은 주장하지 않습니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
고객 공장 MES 가 글라스 장착 라인에 내려 주는 생산 서열을 라인 시뮬레이터로 흉내 낸 표입니다. 세단·SUV 5인승·SUV 7인승·해치백·밴 다섯 차종을 한 라인에서 섞어 만드는 공장이라는 가정이고, VIN 자리에는 실제 차대번호 형식을 따르지 않는 시뮬레이터 번호(SIM-)를 씁니다. 끝의 서열 220번은 아직 글라스 장착 스테이션에 들어오지 않은 차량입니다.
| seq_no | vin | model |
|---|---|---|
| 211 | SIM-048211 | 세단 |
| 212 | SIM-048212 | SUV 5인승 |
| 213 | SIM-048213 | SUV 7인승 |
| 214 | SIM-048214 | SUV 5인승 |
| 215 | SIM-048215 | 해치백 |
아래 JSON Schema 를 그대로 만족하는 생산 서열을 한 교대 분량(60대)으로 더 만들어 주세요. {"type":"object","properties":{"seq_no":{"type":"integer","minimum":1,"description":"그 교대 생산 서열 번호입니다"},"vin":{"type":"string","description":"시뮬레이터가 붙인 차량 번호입니다(SIM- 뒤 6자리). 실제 차대번호 형식을 따르지 않습니다"},"model":{"type":"string","enum":["세단","SUV 5인승","SUV 7인승","해치백","밴"],"description":"서열에 적힌 차종입니다"}},"required":["seq_no","vin","model"]} seq_no 는 1씩 늘리고, vin 은 SIM- 뒤에 6자리 번호를 seq_no 와 같은 순서로 붙이며, 다섯 차종을 섞되 같은 차종이 세 대 넘게 이어지지 않게 하세요. 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) 차종이 대수마다 바뀌는 구간, (2) 서열 끝에 아직 스테이션에 들어오지 않은 차량 2대. 생성한 행은 반드시 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도(seq_no 가 '0213' 같은 문자열, model 이 'SUV5' 같은 목록 밖 표기)는 별도로 3건만 표시해 두세요.{"type":"object","properties":{"seq_no":{"type":"integer","minimum":1,"description":"그 교대 생산 서열 번호입니다"},"vin":{"type":"string","description":"시뮬레이터가 붙인 차량 번호입니다(SIM- 뒤 6자리). 실제 차대번호 형식을 따르지 않습니다"},"model":{"type":"string","enum":["세단","SUV 5인승","SUV 7인승","해치백","밴"],"description":"서열에 적힌 차종입니다"}},"required":["seq_no","vin","model"]}GL-F(앞유리)·GL-R(뒷유리) 스테이션 PLC 가 사이클마다 남긴 기록을 라인 시뮬레이터가 낸 표입니다. cycle_start 는 차체가 고정돼 비전 촬영 트리거가 나간 시각이고, robot_done_at 은 로봇이 유리를 창틀에 안착했다고 알린 시각입니다. 수집기가 짧은 완료 펄스를 놓친 사이클(GLF-005845)은 robot_done_at 이 null 이고, 뒷유리 사이클은 교대 일부만 옮겼습니다.
| cycle_no | vin | station | cycle_start | robot_done_at |
|---|---|---|---|---|
| GLF-005841 | SIM-048211 | GL-F | 2026-10-14T08:40:10.200+09:00 | 2026-10-14T08:40:17.050+09:00 |
| GLF-005842 | SIM-048212 | GL-F | 2026-10-14T08:41:11.400+09:00 | 2026-10-14T08:41:18.900+09:00 |
| GLF-005843 | SIM-048213 | GL-F | 2026-10-14T08:42:12.100+09:00 | 2026-10-14T08:42:18.960+09:00 |
| GLF-005844 | SIM-048214 | GL-F | 2026-10-14T08:43:13.000+09:00 | 2026-10-14T08:43:20.510+09:00 |
| GLF-005845 | SIM-048215 | GL-F | 2026-10-14T08:44:14.300+09:00 | — |
아래 JSON Schema 를 그대로 만족하는 PLC 사이클 기록을 스테이션마다 60사이클씩 더 만들어 주세요. {"type":"object","properties":{"cycle_no":{"type":"string","description":"스테이션 PLC 의 사이클 카운터 번호입니다(앞유리 GLF-, 뒷유리 GLR-)"},"vin":{"type":"string","description":"PLC 가 차체 태그에서 읽은 차량 번호입니다"},"station":{"type":"string","enum":["GL-F","GL-R"],"description":"GL-F 앞유리, GL-R 뒷유리 장착 스테이션입니다"},"cycle_start":{"type":"string","description":"차체가 고정돼 비전 촬영 트리거가 나간 시각입니다. ISO 8601, 밀리초, +09:00 입니다"},"robot_done_at":{"type":["string","null"],"description":"로봇이 유리를 창틀에 안착했다고 PLC 에 알린 시각입니다. 수집기가 완료 펄스를 놓치면 null 입니다"}},"required":["cycle_no","vin","station","cycle_start","robot_done_at"]} vin 은 함께 주는 생산 서열의 번호를 서열 순서대로 쓰고, cycle_start 는 같은 스테이션 안에서 55~65초 간격, GL-R 은 같은 차량의 GL-F 보다 세 대 뒤 시각으로 두며, robot_done_at 은 cycle_start 뒤 5~8초로 두세요. 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) robot_done_at 이 null 인 사이클 2건, (2) 함께 주는 비전 결과 기록에 짝이 없는 사이클 2건, (3) 사이클 간격이 평소의 두 배를 넘는 라인 정지 구간 1곳. 생성한 행은 반드시 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도(cycle_start 가 '08:41:12' 처럼 날짜·밀리초 없는 표기, station 이 'GLF')는 별도로 3건만 표시해 두세요.{"type":"object","properties":{"cycle_no":{"type":"string","description":"스테이션 PLC 의 사이클 카운터 번호입니다(앞유리 GLF-, 뒷유리 GLR-)"},"vin":{"type":"string","description":"PLC 가 차체 태그에서 읽은 차량 번호입니다"},"station":{"type":"string","enum":["GL-F","GL-R"],"description":"GL-F 앞유리, GL-R 뒷유리 장착 스테이션입니다"},"cycle_start":{"type":"string","description":"차체가 고정돼 비전 촬영 트리거가 나간 시각입니다. ISO 8601, 밀리초, +09:00 입니다"},"robot_done_at":{"type":["string","null"],"description":"로봇이 유리를 창틀에 안착했다고 PLC 에 알린 시각입니다. 수집기가 완료 펄스를 놓치면 null 입니다"}},"required":["cycle_no","vin","station","cycle_start","robot_done_at"]}비전 PC 가 로봇 제어기에 보낸 보정 전문을 기록했다고 가정한 표입니다. valid_points 와 offset_mm 은 지원자가 Open3D 로 합성한 유리 가장자리 점군(ply_file)에서 계산한 값이고, 반사 영역의 점을 뺀 사이클(SIM-048219 앞유리)과 차체 위치를 크게 옮긴 사이클(SIM-048213 뒷유리)이 있습니다. 서열이 한 대 밀려 앞 차 설정으로 찍은 사이클(SIM-048217)이 있고, 비전 결과가 아예 없는 SIM-048212 앞유리는 이 표에 행이 없습니다.
| vin | station | setting_id | valid_points | offset_mm | offset_axis | sent_at | ply_file |
|---|---|---|---|---|---|---|---|
| SIM-048211 | GL-F | SD-F-03 | 8,240 | 1.8 | X | 2026-10-14T08:40:11.040+09:00 | ply/1014D/SIM-048211_GL-F.ply |
| SIM-048213 | GL-F | S7-F-02 | 9,310 | 2.4 | Y | 2026-10-14T08:42:12.980+09:00 | ply/1014D/SIM-048213_GL-F.ply |
| SIM-048214 | GL-F | S5-F-04 | 7,880 | 2.1 | X | 2026-10-14T08:43:20.730+09:00 | ply/1014D/SIM-048214_GL-F.ply |
| SIM-048215 | GL-F | HB-F-01 | 6,410 | -1.2 | Z | 2026-10-14T08:44:15.120+09:00 | ply/1014D/SIM-048215_GL-F.ply |
| SIM-048216 | GL-F | S5-F-04 | 8,020 | 0.7 | Y | 2026-10-14T08:45:16.050+09:00 | ply/1014D/SIM-048216_GL-F.ply |
아래 JSON Schema 를 그대로 만족하는 비전 결과 기록을 PLC 사이클 기록과 짝이 맞게 100건 더 만들어 주세요. {"type":"object","properties":{"vin":{"type":"string","description":"비전 PC 가 받은 차량 번호입니다"},"station":{"type":"string","enum":["GL-F","GL-R"]},"setting_id":{"type":"string","description":"촬영에 쓴 비전 설정 번호입니다"},"valid_points":{"type":"integer","minimum":0,"description":"설정의 관심 영역 안에서 깊이 값이 있는 점의 수입니다"},"offset_mm":{"type":"number","description":"로봇에 보낸 위치 보정량 가운데 절댓값이 가장 큰 축의 값(mm, 부호 유지)입니다"},"offset_axis":{"type":"string","enum":["X","Y","Z"],"description":"offset_mm 이 어느 축 값인지입니다"},"sent_at":{"type":"string","description":"보정 전문을 로봇 제어기에 보낸 시각입니다. ISO 8601, 밀리초, +09:00 입니다"},"ply_file":{"type":"string","description":"유효 점 수와 보정량을 계산한 합성 점군 파일 경로입니다"}},"required":["vin","station","setting_id","valid_points","offset_mm","offset_axis","sent_at","ply_file"]} setting_id 는 대부분 생산 서열 차종의 기대 설정을 쓰고, sent_at 은 cycle_start 뒤 600~1,100ms, valid_points 는 그 설정 하한의 1.2~1.6배, offset_mm 은 -4~4 사이로 두세요. ply_file 은 ply/<날짜·교대>/<vin>_<station>.ply 형식입니다. 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) sent_at 이 기한을 넘거나 로봇 완료보다 늦은 결과, (2) 앞 서열 차량의 설정으로 찍은 결과, (3) valid_points 가 하한 아래인 결과, (4) offset_mm 절댓값이 상한을 넘는 결과, (5) sent_at 이 기한과 꼭 같거나 valid_points 가 하한과 꼭 같은 결과. 생성한 행은 반드시 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도(valid_points 가 '3,820' 같은 문자열, offset_axis 가 'x')는 별도로 3건만 표시해 두세요.{"type":"object","properties":{"vin":{"type":"string","description":"비전 PC 가 받은 차량 번호입니다"},"station":{"type":"string","enum":["GL-F","GL-R"]},"setting_id":{"type":"string","description":"촬영에 쓴 비전 설정 번호입니다"},"valid_points":{"type":"integer","minimum":0,"description":"설정의 관심 영역 안에서 깊이 값이 있는 점의 수입니다"},"offset_mm":{"type":"number","description":"로봇에 보낸 위치 보정량 가운데 절댓값이 가장 큰 축의 값(mm, 부호 유지)입니다"},"offset_axis":{"type":"string","enum":["X","Y","Z"],"description":"offset_mm 이 어느 축 값인지입니다"},"sent_at":{"type":"string","description":"보정 전문을 로봇 제어기에 보낸 시각입니다. ISO 8601, 밀리초, +09:00 입니다"},"ply_file":{"type":"string","description":"유효 점 수와 보정량을 계산한 합성 점군 파일 경로입니다"}},"required":["vin","station","setting_id","valid_points","offset_mm","offset_axis","sent_at","ply_file"]}차종과 스테이션마다 비전이 써야 할 설정과 그 기준값을 적은 기준표입니다. min_valid_points 는 보정을 믿을 수 있는 유효 점 하한, max_offset_mm 은 차체 안착이 정상일 때 나올 수 있는 보정량 상한, deadline_ms 는 로봇이 촬영 트리거 뒤 보정값을 기다리는 시간입니다. 값은 이 편이 정한 가정이고, 실제 라인에서는 설치 때 정한 값을 받아 바꿉니다.
| model | station | setting_id | min_valid_points | max_offset_mm | deadline_ms |
|---|---|---|---|---|---|
| 세단 | GL-F | SD-F-03 | 5,500 | 8 | 1,500 |
| 세단 | GL-R | SD-R-02 | 4,000 | 6 | 1,200 |
| SUV 5인승 | GL-F | S5-F-04 | 6,000 | 8 | 1,500 |
| SUV 5인승 | GL-R | S5-R-02 | 4,500 | 6 | 1,200 |
| SUV 7인승 | GL-F | S7-F-02 | 6,500 | 8 | 1,500 |
아래 JSON Schema 를 그대로 만족하는 비전 설정 기준표를 한 벌(10행) 더 만들어 주세요. {"type":"object","properties":{"model":{"type":"string","enum":["세단","SUV 5인승","SUV 7인승","해치백","밴"]},"station":{"type":"string","enum":["GL-F","GL-R"]},"setting_id":{"type":"string","description":"그 차종·스테이션에서 써야 할 비전 설정 번호입니다"},"min_valid_points":{"type":"integer","minimum":1,"description":"보정을 믿을 수 있는 유효 점 하한입니다"},"max_offset_mm":{"type":"number","minimum":0,"description":"차체 안착이 정상일 때 나올 수 있는 보정량 절댓값 상한(mm)입니다"},"deadline_ms":{"type":"integer","minimum":1,"description":"로봇이 촬영 트리거 뒤 보정값을 기다리는 시간(ms)입니다"}},"required":["model","station","setting_id","min_valid_points","max_offset_mm","deadline_ms"]} 같은 다섯 차종·두 스테이션 열 행을 다른 공장 라인에 설치한 본으로 가정해, model·station 조합은 그대로 두고 setting_id 와 min_valid_points·max_offset_mm·deadline_ms 만 바꿉니다. setting_id 는 차종 머리글자-스테이션-번호(예: SD-F-05) 형식에서 번호만 올리고, GL-R 행은 같은 차종 GL-F 행보다 유효 점 하한과 기한을 낮게 두세요. 쉬운 데이터만 만들지 말 것 — 다음 하드 케이스를 의도적으로 섞어라: (1) 보정량 상한과 기한이 나머지 행보다 큰 행 2개(같은 차종의 GL-F·GL-R), (2) 유효 점 하한이 3,500개 안팎인 GL-R 행 1개, (3) GL-R 행의 기한이 같은 차종 GL-F 행과 같은 행 1개. 생성한 행은 반드시 위 스키마를 통과해야 하며, 형식을 깨뜨리는 시도(deadline_ms 가 '1.5s' 같은 문자열, model 이 다섯 차종 밖인 행)는 별도로 3건만 표시해 두세요.{"type":"object","properties":{"model":{"type":"string","enum":["세단","SUV 5인승","SUV 7인승","해치백","밴"]},"station":{"type":"string","enum":["GL-F","GL-R"]},"setting_id":{"type":"string","description":"그 차종·스테이션에서 써야 할 비전 설정 번호입니다"},"min_valid_points":{"type":"integer","minimum":1,"description":"보정을 믿을 수 있는 유효 점 하한입니다"},"max_offset_mm":{"type":"number","minimum":0,"description":"차체 안착이 정상일 때 나올 수 있는 보정량 절댓값 상한(mm)입니다"},"deadline_ms":{"type":"integer","minimum":1,"description":"로봇이 촬영 트리거 뒤 보정값을 기다리는 시간(ms)입니다"}},"required":["model","station","setting_id","min_valid_points","max_offset_mm","deadline_ms"]}| Python | 라인 시뮬레이터, 네 파일 읽기, VIN·스테이션 짝짓기, 밀리초 시각 계산, 판정 규칙, FastAPI 판정 API 를 씁니다. |
| Open3D | 차종 설정마다 유리 가장자리 점군(PLY)을 합성하고 반사·가림 영역의 점을 빼거나 차체 위치를 옮긴 뒤, 관심 영역 안 유효 점 수와 가장자리 직선 맞춤으로 보정량을 계산합니다. |
| TCP/IP | 비전 PC 가 로봇 제어기에 보내는 보정 전문(VIN·설정·보정량·전송 시각)을 2주차에 소켓으로 받아 비전 결과 기록을 만듭니다. |
| OPC UA | 2주차에 asyncua 로 띄운 PLC 시뮬레이터 서버의 사이클 시작·로봇 완료·VIN 태그를 구독해 사이클 기록을 실시간으로 받습니다. |
| Modbus TCP | pymodbus 시뮬레이터의 로봇 완료 비트와 사이클 카운터 레지스터를 읽고, 폴링 주기 때문에 짧은 완료 펄스를 놓쳐 완료 시각이 비는 경우를 재현합니다. |
| 로봇-카메라 캘리브레이션 | 3주차에 스테이션별 보정량이 한 축으로 쏠려 가는 추이를 캘리브레이션 틀어짐 의심 표시로 씁니다. |
| React | 판정별 표, 차량 펼침의 시각 띠, 재검사 목록 CSV 내려받기 화면을 만듭니다. |
| SQLite | 교대별 판정과 수집 기록을 쌓아 라인 PC 한 대에서 판정 API 와 화면이 돌게 합니다. |
| Docker Compose (SW 배포) | 판정 API·화면·시뮬레이터·수집기를 한 명령으로 띄우고, 수집이 끊기면 마지막 수신 시각을 화면 위 알림에 남깁니다. |
| LLM API (Claude Sonnet) | 3주차에 교대 판정표로 교대 인계 메모 초안을 씁니다. |
✗ fail → SIM-048216 뒷유리가 늦음으로 걸리면 기한 비교를 '넘으면' 으로 고치고, SIM-048215 가 판정에서 빠지면 완료 시각이 빈 사이클의 늦음 조건부터 고칩니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우려면 시뮬레이터가 고장을 심은 주간조 사이클 824개를 정답으로 판정과 맞대고, 같은 교대를 OPC UA·Modbus TCP·TCP/IP 로 받아 파일 판정과 견줍니다.
✓ pass → 여기까지도 완결입니다. 더 키우려면 여러 교대를 쌓아 늦은 보정이 몰린 시간대와 보정량 쏠림을 보고 교대 인계 메모 초안을 붙입니다.
위 예측 UI 는 3주차까지 완주했을 때의 화면입니다. 1주차에 실제로 만드는 것은 아래 표시된 화면 하나입니다.
verdict사유 라벨 · cycle_no + 한 줄 요약(근거 수치 포함)화면·코드·면접에서 이 단어를 그대로 씁니다. 키는 출력 스키마의 enum 과 같습니다.
보정값 받고 장착보정 정상보정값 없이 장착보정 없음보정값이 장착 뒤에 도착보정 늦음다른 차종 설정으로 촬영차종 설정 어긋남점군이 모자란 채 보정점군 부족보정량이 한계를 넘음보정량 초과PLC 사이클 하나에 글라스 장착 비전 보정 판정 하나를 남기는 형식입니다. 기대 설정과 찍은 설정, 사이클 시작 기준 도착·완료 ms, 유효 점 수와 보정량을 그 기준값 옆에 둡니다.
{"type":"object","properties":{"cycle_no":{"type":"string","description":"판정한 PLC 사이클 번호입니다"},"vin":{"type":"string"},"seq_no":{"type":["integer","null"],"description":"build_orders 에서 찾은 서열 번호입니다"},"model":{"type":["string","null"],"description":"build_orders 에서 찾은 차종입니다"},"station":{"type":"string","enum":["GL-F","GL-R"]},"verdict":{"type":"string","enum":["보정값 받고 장착","보정값 없이 장착","보정값이 장착 뒤에 도착","다른 차종 설정으로 촬영","점군이 모자란 채 보정","보정량이 한계를 넘음"],"description":"걸린 판정이 여럿이면 보정값 없이 장착, 보정값이 장착 뒤에 도착, 다른 차종 설정으로 촬영, 점군이 모자란 채 보정, 보정량이 한계를 넘음 순으로 앞선 하나입니다. 하나도 걸리지 않으면 보정값 받고 장착입니다"},"also_found":{"type":"array","items":{"type":"string","enum":["보정값이 장착 뒤에 도착","다른 차종 설정으로 촬영","점군이 모자란 채 보정","보정량이 한계를 넘음"]},"description":"verdict 뒤로 밀린 나머지 판정입니다"},"expected_setting_id":{"type":["string","null"],"description":"서열의 차종과 스테이션으로 vision_settings 에서 찾은 설정입니다"},"used_setting_id":{"type":["string","null"],"description":"vision_results 의 setting_id 입니다. 비전 결과가 없으면 null 입니다"},"cycle_start":{"type":"string"},"robot_done_at":{"type":["string","null"]},"sent_at":{"type":["string","null"]},"deadline_ms":{"type":["integer","null"],"description":"기대 설정의 deadline_ms 입니다"},"sent_after_start_ms":{"type":["integer","null"],"description":"정적 계산값입니다. sent_at − cycle_start 의 밀리초이고, 비전 결과가 없으면 null 입니다"},"robot_done_after_start_ms":{"type":["integer","null"],"description":"정적 계산값입니다. robot_done_at − cycle_start 의 밀리초이고, robot_done_at 이 null 이면 null 입니다"},"valid_points":{"type":["integer","null"],"minimum":0},"min_valid_points":{"type":["integer","null"],"description":"기대 설정의 유효 점 하한입니다"},"offset_mm":{"type":["number","null"]},"offset_axis":{"type":["string","null"],"enum":["X","Y","Z",null]},"max_offset_mm":{"type":["number","null"],"description":"기대 설정의 보정량 상한입니다"},"evidence":{"type":"array","items":{"type":"object","properties":{"table":{"type":"string","enum":["build_orders","plc_cycles","vision_results","vision_settings"]},"row":{"type":["string","null"],"description":"그 표의 키입니다. build_orders 는 seq_no, plc_cycles 는 cycle_no, vision_results 는 vin/station, vision_settings 는 setting_id 입니다. agg 항목이면 null 입니다"},"field":{"type":"string"},"value":{"type":["string","integer","number","null"]},"agg":{"type":"string","enum":["count","sum","avg","min","max"]}},"required":["table","row","field","value"]}},"notes":{"type":"array","items":{"type":"string"},"description":"판정에 들지 않았지만 생산기술 담당자와 FDE 가 볼 사실입니다"},"summary":{"type":"string"}},"required":["cycle_no","vin","seq_no","model","station","verdict","also_found","expected_setting_id","used_setting_id","cycle_start","robot_done_at","sent_at","deadline_ms","sent_after_start_ms","robot_done_after_start_ms","valid_points","min_valid_points","offset_mm","offset_axis","max_offset_mm","evidence","notes","summary"]}[
{
"cycle_no": "GLF-005841",
"vin": "SIM-048211",
"seq_no": 211,
"model": "세단",
"station": "GL-F",
"verdict": "보정값 받고 장착",
"also_found": [],
"expected_setting_id": "SD-F-03",
"used_setting_id": "SD-F-03",
"cycle_start": "2026-10-14T08:40:10.200+09:00",
"robot_done_at": "2026-10-14T08:40:17.050+09:00",
"sent_at": "2026-10-14T08:40:11.040+09:00",
"deadline_ms": 1500,
"sent_after_start_ms": 840,
"robot_done_after_start_ms": 6850,
"valid_points": 8240,
"min_valid_points": 5500,
"offset_mm": 1.8,
"offset_axis": "X",
"max_offset_mm": 8,
"evidence": [
{
"table": "plc_cycles",
"row": "GLF-005841",
"field": "cycle_start",
"value": "2026-10-14T08:40:10.200+09:00"
},
{
"table": "plc_cycles",
"row": "GLF-005841",
"field": "robot_done_at",
"value": "2026-10-14T08:40:17.050+09:00"
},
{
"table": "build_orders",
"row": "211",
"field": "model",
"value": "세단"
},
{
"table": "vision_settings",
"row": "SD-F-03",
"field": "setting_id",
"value": "SD-F-03"
},
{
"table": "vision_settings",
"row": "SD-F-03",
"field": "deadline_ms",
"value": 1500
},
{
"table": "vision_results",
"row": "SIM-048211/GL-F",
"field": "sent_at",
"value": "2026-10-14T08:40:11.040+09:00"
},
{
"table": "vision_results",
"row": "SIM-048211/GL-F",
"field": "setting_id",
"value": "SD-F-03"
},
{
"table": "vision_results",
"row": "SIM-048211/GL-F",
"field": "valid_points",
"value": 8240
},
{
"table": "vision_settings",
"row": "SD-F-03",
"field": "min_valid_points",
"value": 5500
},
{
"table": "vision_results",
"row": "SIM-048211/GL-F",
"field": "offset_mm",
"value": 1.8
},
{
"table": "vision_settings",
"row": "SD-F-03",
"field": "max_offset_mm",
"value": 8
}
],
"notes": [],
"summary": "사이클 시작 뒤 840ms 에 세단 설정으로 찍은 보정값이 왔고, 유효 점과 보정량이 기준 안입니다."
},
{
"cycle_no": "GLF-005845",
"vin": "SIM-048215",
"seq_no": 215,
"model": "해치백",
"station": "GL-F",
"verdict": "보정값 받고 장착",
"also_found": [],
"expected_setting_id": "HB-F-01",
"used_setting_id": "HB-F-01",
"cycle_start": "2026-10-14T08:44:14.300+09:00",
"robot_done_at": null,
"sent_at": "2026-10-14T08:44:15.120+09:00",
"deadline_ms": 1500,
"sent_after_start_ms": 820,
"robot_done_after_start_ms": null,
"valid_points": 6410,
"min_valid_points": 5000,
"offset_mm": -1.2,
"offset_axis": "Z",
"max_offset_mm": 8,
"evidence": [
{
"table": "plc_cycles",
"row": "GLF-005845",
"field": "cycle_start",
"value": "2026-10-14T08:44:14.300+09:00"
},
{
"table": "plc_cycles",
"row": "GLF-005845",
"field": "robot_done_at",
"value": null
},
{
"table": "build_orders",
"row": "215",
"field": "model",
"value": "해치백"
},
{
"table": "vision_settings",
"row": "HB-F-01",
"field": "setting_id",
"value": "HB-F-01"
},
{
"table": "vision_settings",
"row": "HB-F-01",
"field": "deadline_ms",
"value": 1500
},
{
"table": "vision_results",
"row": "SIM-048215/GL-F",
"field": "sent_at",
"value": "2026-10-14T08:44:15.120+09:00"
},
{
"table": "vision_results",
"row": "SIM-048215/GL-F",
"field": "setting_id",
"value": "HB-F-01"
},
{
"table": "vision_results",
"row": "SIM-048215/GL-F",
"field": "valid_points",
"value": 6410
},
{
"table": "vision_settings",
"row": "HB-F-01",
"field": "min_valid_points",
"value": 5000
},
{
"table": "vision_results",
"row": "SIM-048215/GL-F",
"field": "offset_mm",
"value": -1.2
},
{
"table": "vision_settings",
"row": "HB-F-01",
"field": "max_offset_mm",
"value": 8
}
],
"notes": [
"PLC 기록에 로봇 완료 시각이 비어 있어 늦음은 기한 1,500ms 조건으로만 봤습니다.",
"완료 시각이 비어 있는 사이클은 요약 줄에 따로 셉니다."
],
"summary": "로봇 완료 시각은 비어 있지만 보정값이 기한 안인 820ms 에 왔고 점 수와 보정량이 기준 안입니다."
},
{
"cycle_no": "GLR-005844",
"vin": "SIM-048216",
"seq_no": 216,
"model": "SUV 5인승",
"station": "GL-R",
"verdict": "보정값 받고 장착",
"also_found": [],
"expected_setting_id": "S5-R-02",
"used_setting_id": "S5-R-02",
"cycle_start": "2026-10-14T08:48:18.700+09:00",
"robot_done_at": "2026-10-14T08:48:25.000+09:00",
"sent_at": "2026-10-14T08:48:19.900+09:00",
"deadline_ms": 1200,
"sent_after_start_ms": 1200,
"robot_done_after_start_ms": 6300,
"valid_points": 4500,
"min_valid_points": 4500,
"offset_mm": 2.2,
"offset_axis": "X",
"max_offset_mm": 6,
"evidence": [
{
"table": "plc_cycles",
"row": "GLR-005844",
"field": "cycle_start",
"value": "2026-10-14T08:48:18.700+09:00"
},
{
"table": "plc_cycles",
"row": "GLR-005844",
"field": "robot_done_at",
"value": "2026-10-14T08:48:25.000+09:00"
},
{
"table": "build_orders",
"row": "216",
"field": "model",
"value": "SUV 5인승"
},
{
"table": "vision_settings",
"row": "S5-R-02",
"field": "setting_id",
"value": "S5-R-02"
},
{
"table": "vision_settings",
"row": "S5-R-02",
"field": "deadline_ms",
"value": 1200
},
{
"table": "vision_results",
"row": "SIM-048216/GL-R",
"field": "sent_at",
"value": "2026-10-14T08:48:19.900+09:00"
},
{
"table": "vision_results",
"row": "SIM-048216/GL-R",
"field": "setting_id",
"value": "S5-R-02"
},
{
"table": "vision_results",
"row": "SIM-048216/GL-R",
"field": "valid_points",
"value": 4500
},
{
"table": "vision_settings",
"row": "S5-R-02",
"field": "min_valid_points",
"value": 4500
},
{
"table": "vision_results",
"row": "SIM-048216/GL-R",
"field": "offset_mm",
"value": 2.2
},
{
"table": "vision_settings",
"row": "S5-R-02",
"field": "max_offset_mm",
"value": 6
}
],
"notes": [
"도착 1,200ms 가 기한 1,200ms 와 같아 판정식의 '넘으면' 에 들지 않습니다.",
"유효 점 4,500개가 하한 4,500개와 같아 '미달' 에 들지 않습니다."
],
"summary": "기한과 같은 시각에 온 보정값이고 유효 점도 하한과 같아 보정값을 받고 붙인 사이클입니다."
},
{
"cycle_no": "GLF-005842",
"vin": "SIM-048212",
"seq_no": 212,
"model": "SUV 5인승",
"station": "GL-F",
"verdict": "보정값 없이 장착",
"also_found": [],
"expected_setting_id": "S5-F-04",
"used_setting_id": null,
"cycle_start": "2026-10-14T08:41:11.400+09:00",
"robot_done_at": "2026-10-14T08:41:18.900+09:00",
"sent_at": null,
"deadline_ms": 1500,
"sent_after_start_ms": null,
"robot_done_after_start_ms": 7500,
"valid_points": null,
"min_valid_points": 6000,
"offset_mm": null,
"offset_axis": null,
"max_offset_mm": 8,
"evidence": [
{
"table": "plc_cycles",
"row": "GLF-005842",
"field": "cycle_start",
"value": "2026-10-14T08:41:11.400+09:00"
},
{
"table": "plc_cycles",
"row": "GLF-005842",
"field": "robot_done_at",
"value": "2026-10-14T08:41:18.900+09:00"
},
{
"table": "build_orders",
"row": "212",
"field": "model",
"value": "SUV 5인승"
},
{
"table": "vision_settings",
"row": "S5-F-04",
"field": "setting_id",
"value": "S5-F-04"
},
{
"table": "vision_settings",
"row": "S5-F-04",
"field": "deadline_ms",
"value": 1500
},
{
"table": "vision_results",
"row": null,
"field": "vin",
"agg": "count",
"value": 0
}
],
"notes": [
"로봇은 기한 1,500ms 를 기다린 뒤 기본 좌표로 유리를 붙였고, 완료가 평소보다 늦은 7,500ms 입니다.",
"갭·단차 재검사 목록에 올립니다."
],
"summary": "앞유리 사이클은 끝났는데 이 차량의 GL-F 비전 결과가 한 건도 없습니다."
},
{
"cycle_no": "GLF-005844",
"vin": "SIM-048214",
"seq_no": 214,
"model": "SUV 5인승",
"station": "GL-F",
"verdict": "보정값이 장착 뒤에 도착",
"also_found": [],
"expected_setting_id": "S5-F-04",
"used_setting_id": "S5-F-04",
"cycle_start": "2026-10-14T08:43:13.000+09:00",
"robot_done_at": "2026-10-14T08:43:20.510+09:00",
"sent_at": "2026-10-14T08:43:20.730+09:00",
"deadline_ms": 1500,
"sent_after_start_ms": 7730,
"robot_done_after_start_ms": 7510,
"valid_points": 7880,
"min_valid_points": 6000,
"offset_mm": 2.1,
"offset_axis": "X",
"max_offset_mm": 8,
"evidence": [
{
"table": "plc_cycles",
"row": "GLF-005844",
"field": "cycle_start",
"value": "2026-10-14T08:43:13.000+09:00"
},
{
"table": "plc_cycles",
"row": "GLF-005844",
"field": "robot_done_at",
"value": "2026-10-14T08:43:20.510+09:00"
},
{
"table": "build_orders",
"row": "214",
"field": "model",
"value": "SUV 5인승"
},
{
"table": "vision_settings",
"row": "S5-F-04",
"field": "setting_id",
"value": "S5-F-04"
},
{
"table": "vision_settings",
"row": "S5-F-04",
"field": "deadline_ms",
"value": 1500
},
{
"table": "vision_results",
"row": "SIM-048214/GL-F",
"field": "sent_at",
"value": "2026-10-14T08:43:20.730+09:00"
},
{
"table": "vision_results",
"row": "SIM-048214/GL-F",
"field": "setting_id",
"value": "S5-F-04"
},
{
"table": "vision_results",
"row": "SIM-048214/GL-F",
"field": "valid_points",
"value": 7880
},
{
"table": "vision_settings",
"row": "S5-F-04",
"field": "min_valid_points",
"value": 6000
},
{
"table": "vision_results",
"row": "SIM-048214/GL-F",
"field": "offset_mm",
"value": 2.1
},
{
"table": "vision_settings",
"row": "S5-F-04",
"field": "max_offset_mm",
"value": 8
}
],
"notes": [
"보정값이 기한 1,500ms 를 6,230ms 넘겼고, 로봇 완료보다 220ms 늦게 왔습니다.",
"갭·단차 재검사 목록에 올립니다."
],
"summary": "보정값이 사이클 시작 뒤 7,730ms 에 와 기한 1,500ms 와 로봇 완료 7,510ms 를 모두 넘겼습니다."
},
{
"cycle_no": "GLF-005847",
"vin": "SIM-048217",
"seq_no": 217,
"model": "세단",
"station": "GL-F",
"verdict": "다른 차종 설정으로 촬영",
"also_found": [
"점군이 모자란 채 보정",
"보정량이 한계를 넘음"
],
"expected_setting_id": "SD-F-03",
"used_setting_id": "S5-F-04",
"cycle_start": "2026-10-14T08:46:16.000+09:00",
"robot_done_at": "2026-10-14T08:46:22.870+09:00",
"sent_at": "2026-10-14T08:46:16.910+09:00",
"deadline_ms": 1500,
"sent_after_start_ms": 910,
"robot_done_after_start_ms": 6870,
"valid_points": 3100,
"min_valid_points": 5500,
"offset_mm": 9.6,
"offset_axis": "X",
"max_offset_mm": 8,
"evidence": [
{
"table": "plc_cycles",
"row": "GLF-005847",
"field": "cycle_start",
"value": "2026-10-14T08:46:16.000+09:00"
},
{
"table": "plc_cycles",
"row": "GLF-005847",
"field": "robot_done_at",
"value": "2026-10-14T08:46:22.870+09:00"
},
{
"table": "build_orders",
"row": "217",
"field": "model",
"value": "세단"
},
{
"table": "vision_settings",
"row": "SD-F-03",
"field": "setting_id",
"value": "SD-F-03"
},
{
"table": "vision_settings",
"row": "SD-F-03",
"field": "deadline_ms",
"value": 1500
},
{
"table": "vision_results",
"row": "SIM-048217/GL-F",
"field": "sent_at",
"value": "2026-10-14T08:46:16.910+09:00"
},
{
"table": "vision_results",
"row": "SIM-048217/GL-F",
"field": "setting_id",
"value": "S5-F-04"
},
{
"table": "vision_results",
"row": "SIM-048217/GL-F",
"field": "valid_points",
"value": 3100
},
{
"table": "vision_settings",
"row": "SD-F-03",
"field": "min_valid_points",
"value": 5500
},
{
"table": "vision_results",
"row": "SIM-048217/GL-F",
"field": "offset_mm",
"value": 9.6
},
{
"table": "vision_settings",
"row": "SD-F-03",
"field": "max_offset_mm",
"value": 8
},
{
"table": "vision_settings",
"row": "S5-F-04",
"field": "model",
"value": "SUV 5인승"
},
{
"table": "build_orders",
"row": "216",
"field": "model",
"value": "SUV 5인승"
}
],
"notes": [
"찍은 설정 S5-F-04 는 바로 앞 서열 216번(SUV 5인승)의 GL-F 설정과 같습니다.",
"유효 점 3,100개와 보정량 9.6mm 는 세단 설정 SD-F-03 의 하한 5,500개·상한 8.0mm 로 견줬습니다."
],
"summary": "서열상 세단인데 SUV 5인승 설정 S5-F-04 로 찍었습니다."
},
{
"cycle_no": "GLF-005849",
"vin": "SIM-048219",
"seq_no": 219,
"model": "SUV 7인승",
"station": "GL-F",
"verdict": "점군이 모자란 채 보정",
"also_found": [],
"expected_setting_id": "S7-F-02",
"used_setting_id": "S7-F-02",
"cycle_start": "2026-10-14T08:48:18.400+09:00",
"robot_done_at": "2026-10-14T08:48:25.280+09:00",
"sent_at": "2026-10-14T08:48:19.310+09:00",
"deadline_ms": 1500,
"sent_after_start_ms": 910,
"robot_done_after_start_ms": 6880,
"valid_points": 3820,
"min_valid_points": 6500,
"offset_mm": 1.5,
"offset_axis": "X",
"max_offset_mm": 8,
"evidence": [
{
"table": "plc_cycles",
"row": "GLF-005849",
"field": "cycle_start",
"value": "2026-10-14T08:48:18.400+09:00"
},
{
"table": "plc_cycles",
"row": "GLF-005849",
"field": "robot_done_at",
"value": "2026-10-14T08:48:25.280+09:00"
},
{
"table": "build_orders",
"row": "219",
"field": "model",
"value": "SUV 7인승"
},
{
"table": "vision_settings",
"row": "S7-F-02",
"field": "setting_id",
"value": "S7-F-02"
},
{
"table": "vision_settings",
"row": "S7-F-02",
"field": "deadline_ms",
"value": 1500
},
{
"table": "vision_results",
"row": "SIM-048219/GL-F",
"field": "sent_at",
"value": "2026-10-14T08:48:19.310+09:00"
},
{
"table": "vision_results",
"row": "SIM-048219/GL-F",
"field": "setting_id",
"value": "S7-F-02"
},
{
"table": "vision_results",
"row": "SIM-048219/GL-F",
"field": "valid_points",
"value": 3820
},
{
"table": "vision_settings",
"row": "S7-F-02",
"field": "min_valid_points",
"value": 6500
},
{
"table": "vision_results",
"row": "SIM-048219/GL-F",
"field": "offset_mm",
"value": 1.5
},
{
"table": "vision_settings",
"row": "S7-F-02",
"field": "max_offset_mm",
"value": 8
}
],
"notes": [
"유효 점 3,820개는 하한 6,500개보다 2,680개 적고, 보정량 1.5mm 는 상한 안입니다."
],
"summary": "보정값은 기한 안에 왔지만 유효 점이 3,820개로 하한 6,500개에 못 미칩니다."
},
{
"cycle_no": "GLR-005841",
"vin": "SIM-048213",
"seq_no": 213,
"model": "SUV 7인승",
"station": "GL-R",
"verdict": "보정량이 한계를 넘음",
"also_found": [],
"expected_setting_id": "S7-R-03",
"used_setting_id": "S7-R-03",
"cycle_start": "2026-10-14T08:45:15.900+09:00",
"robot_done_at": "2026-10-14T08:45:21.700+09:00",
"sent_at": "2026-10-14T08:45:16.610+09:00",
"deadline_ms": 1200,
"sent_after_start_ms": 710,
"robot_done_after_start_ms": 5800,
"valid_points": 7050,
"min_valid_points": 5000,
"offset_mm": -7.4,
"offset_axis": "X",
"max_offset_mm": 6,
"evidence": [
{
"table": "plc_cycles",
"row": "GLR-005841",
"field": "cycle_start",
"value": "2026-10-14T08:45:15.900+09:00"
},
{
"table": "plc_cycles",
"row": "GLR-005841",
"field": "robot_done_at",
"value": "2026-10-14T08:45:21.700+09:00"
},
{
"table": "build_orders",
"row": "213",
"field": "model",
"value": "SUV 7인승"
},
{
"table": "vision_settings",
"row": "S7-R-03",
"field": "setting_id",
"value": "S7-R-03"
},
{
"table": "vision_settings",
"row": "S7-R-03",
"field": "deadline_ms",
"value": 1200
},
{
"table": "vision_results",
"row": "SIM-048213/GL-R",
"field": "sent_at",
"value": "2026-10-14T08:45:16.610+09:00"
},
{
"table": "vision_results",
"row": "SIM-048213/GL-R",
"field": "setting_id",
"value": "S7-R-03"
},
{
"table": "vision_results",
"row": "SIM-048213/GL-R",
"field": "valid_points",
"value": 7050
},
{
"table": "vision_settings",
"row": "S7-R-03",
"field": "min_valid_points",
"value": 5000
},
{
"table": "vision_results",
"row": "SIM-048213/GL-R",
"field": "offset_mm",
"value": -7.4
},
{
"table": "vision_settings",
"row": "S7-R-03",
"field": "max_offset_mm",
"value": 6
},
{
"table": "vision_results",
"row": "SIM-048213/GL-F",
"field": "offset_mm",
"value": 2.4
}
],
"notes": [
"같은 차량의 앞유리 사이클(GLF-005843) 보정량은 Y 축 2.4mm 로 상한 안입니다.",
"차체 안착이나 지그를 확인할 차량입니다."
],
"summary": "X 축 보정량 -7.4mm 가 SUV 7인승 뒷유리 상한 6.0mm 를 넘었습니다."
}
][자동 검증 · 코드가 판정합니다] 1. verdict 가 보정값 받고 장착·보정값 없이 장착·보정값이 장착 뒤에 도착·다른 차종 설정으로 촬영·점군이 모자란 채 보정·보정량이 한계를 넘음 여섯 값 중 하나인지, also_found 가 보정값이 장착 뒤에 도착·다른 차종 설정으로 촬영·점군이 모자란 채 보정·보정량이 한계를 넘음 네 값 중에서만 나오는지 확인합니다. 2. 필수 필드 cycle_no·vin·seq_no·model·station·verdict·also_found·expected_setting_id·used_setting_id·cycle_start·robot_done_at·sent_at·deadline_ms·sent_after_start_ms·robot_done_after_start_ms·valid_points·min_valid_points·offset_mm·offset_axis·max_offset_mm·evidence·notes·summary 가 모두 존재하는지 확인합니다. 3. 보정값 없이 장착: plc_cycles 의 vin·station 과 같은 vision_results 행 수를 다시 계산하고, 0 이면 이 판정입니다. 이 판정이면 sent_at·used_setting_id·valid_points·offset_mm 은 null 입니다. SIM-048212 앞유리(GLF-005842)가 이 경우입니다. 4. sent_after_start_ms 가 sent_at − cycle_start, robot_done_after_start_ms 가 robot_done_at − cycle_start 의 밀리초인지 다시 계산합니다. SIM-048214 앞유리는 7,730 과 7,510 입니다. 5. 보정값이 장착 뒤에 도착: sent_after_start_ms 가 deadline_ms 를 넘거나 robot_done_after_start_ms 보다 크면 이 판정이 걸리는지 다시 계산합니다. robot_done_at 이 null 이면 기한 조건만 봅니다. 기한과 꼭 같은 1,200ms 에 온 SIM-048216 뒷유리는 걸리지 않고, 완료 시각이 비어 있는 SIM-048215 앞유리는 820ms 로 기한 안이라 걸리지 않습니다. 6. 다른 차종 설정으로 촬영: build_orders 에서 vin 의 model 을 찾고, 같은 model·station 의 vision_settings.setting_id 가 expected_setting_id 인지 다시 계산합니다. used_setting_id 가 expected_setting_id 와 다르면 걸립니다. 세단 SIM-048217 은 SD-F-03 대신 S5-F-04 로 찍어 걸립니다. 7. 점군이 모자란 채 보정: valid_points 가 기대 설정의 min_valid_points 미만이면 걸리는지 다시 계산합니다. SIM-048219 앞유리는 3,820 < 6,500 으로 걸리고, 하한과 같은 4,500개인 SIM-048216 뒷유리는 걸리지 않습니다. 8. 보정량이 한계를 넘음: offset_mm 의 절댓값이 기대 설정의 max_offset_mm 를 넘으면 걸리는지 다시 계산합니다. SIM-048213 뒷유리는 |−7.4| > 6.0 으로 걸립니다. 9. 한 사이클에 여러 판정이 걸리면 보정값 없이 장착, 보정값이 장착 뒤에 도착, 다른 차종 설정으로 촬영, 점군이 모자란 채 보정, 보정량이 한계를 넘음 순으로 앞선 하나가 verdict 이고 나머지는 also_found 입니다. 세 판정이 같이 걸린 SIM-048217 로 이 순서를 다시 계산합니다. 10. evidence 의 table·field 가 build_orders·plc_cycles·vision_results·vision_settings 에 실재하는 컬럼인지 대조합니다. 11. agg 가 없는 evidence 의 value 가 그 row 의 그 컬럼 원문 값 그대로인지, agg 가 count 인 value 가 같은 vin·station 으로 센 행 수인지 확인합니다. 12. summary 가 존댓말로 끝나는지 확인합니다. [수동 검증 · 사람이 봅니다] 1. 걸린 차량을 갭·단차 재검사로 보낼지, 수정 라인에서 유리를 다시 붙일지는 생산기술 담당자가 정합니다. 2. 늦은 보정값이 몰린 시간대의 원인이 PLC 트리거인지 비전 PC 처리 시간인지는 FDE 가 고객 PLC 담당자와 확인합니다. 3. 다른 차종 설정으로 찍힌 차량이 MES 서열 전문 지연 때문인지는 고객 MES 담당자와 확인합니다. 4. 차종별 기한·유효 점 하한·보정량 상한이 그 라인에 맞는지는 설치 때 정한 값을 받아 맞춥니다. [평가 러너 · 2주차] 1. 라인 시뮬레이터가 고장을 심은 주간조 사이클 824개에서 verdict 가 시나리오 표의 정답과 같은 사이클 수를 셉니다. 2. 같은 교대를 파일과 OPC UA·Modbus TCP·TCP/IP 실시간 수신으로 각각 받아 판정이 다른 사이클 수를 셉니다. [판정식에 더한 정의 · 오너 확인 항목] 1. 같은 VIN 이 앞유리와 뒷유리 두 사이클로 화면에 서서 줄을 가를 키가 없었고, 보정량이 어느 축 값인지와 어느 합성 점군에서 계산됐는지 거슬러 볼 수 없었습니다. 그래서 카드 inputs 에 없던 plc_cycles.cycle_no 와 vision_results.offset_axis·ply_file 을 더했습니다. 2. 앞유리 GL-F 와 뒷유리 GL-R 두 스테이션을 두고, 판정은 차량 하나가 아니라 스테이션 사이클 하나마다 냅니다. 3. 유효 점 하한·보정량 상한·기한은 촬영에 쓴 설정이 아니라 서열 차종으로 찾은 기대 설정의 값입니다. 4. robot_done_at 이 null 이면 늦음은 기한 조건만으로 봅니다. 5. 판정 우선순위는 보정값 없이 장착, 보정값이 장착 뒤에 도착, 다른 차종 설정으로 촬영, 점군이 모자란 채 보정, 보정량이 한계를 넘음 순입니다.