홀리데이로보틱스
경력근거: 로그, 텔레메트리, 센서 데이터를 기반으로 문제 상황 분석 및 해결
홀리데이로보틱스는 공고에서 기준이 연구실 데모가 아니라 실제 현장이라고 못박고, FDE 의 업무를 고객사 환경 설치와 초기 셋업, 로그·텔레메트리 기반 문제 분석, 점검 결과 문서화로 적어 두었습니다. 도면 좌표와 실측 로그의 어긋남을 밀리미터로 계산해 리포트로 내는 도구는 그 세 업무가 한 줄로 이어지는 자리에 놓입니다. 다만 이 포트폴리오가 보여주는 것은 좌표 정합 계산과 현장 로그 처리 기술이며, 산업용 휴머노이드의 기구 설계나 현장 안전 규격 같은 도메인 전문성은 주장하지 않습니다.
공고가 '고객사 환경에 휴머노이드 시스템 설치 및 초기 셋업'을 첫 업무로 둡니다. 설치 좌표를 맞추는 계산이 그 자리에서 바로 필요합니다.
'로그, 텔레메트리, 센서 데이터를 기반으로 문제 상황 분석 및 해결'이 자격요건에 적혀 있습니다. 실측 로그를 받아 어긋남을 수치로 답하는 도구가 여기에 붙습니다.
'현장 요구사항, 점검 결과 문서화 및 엔지니어링 팀과 연계'가 업무로 들어 있습니다. 계산 결과를 그대로 리포트 파일로 냅니다.
고객사에서 받은 설비 도면 좌표표와 로봇 실측 로그를 맞춰 설치 오차와 지점별 도달 여유를 밀리미터로 계산하고, 보정값 파일과 점검 리포트를 내는 1주 FDE PoC CLI입니다.
홀리데이로보틱스 FDE 엔지니어입니다. 고객사 공장에 휴머노이드를 설치하러 나가서, 설비팀이 준 도면 좌표표와 로봇에서 뽑은 실측 로그를 노트북에서 눈으로 대조하며 베이스를 몇 밀리미터 옮겨야 하는지 감으로 잡던 사람입니다.
도면 좌표와 실측 좌표를 대응점으로 묶어 강체변환을 최소제곱으로 풀면, 설치 어긋남과 각 작업 지점의 도달 여유를 감이 아니라 밀리미터 수치로 답할 수 있습니다.
도면 좌표표(엑셀)와 실측 로그(CSV)를 넣으면 보정값 x·y·yaw 와 지점별 잔차·도달 여유를 계산해 터미널 요약, 점검 리포트(md), 보정값(yaml)을 내놓는 CLI입니다.
잔차가 큰 측정점을 이상치로 걸러 다시 추정하고, 참값을 아는 합성 현장으로 추정 오차 분포를 재며 재측정 요청 목록을 내는 단계입니다.
로봇 베이스 후보 위치를 격자로 훑어 모든 작업 지점이 여유를 만족하는 배치를 추천하고, rosbag2 로그에서 측정점을 직접 뽑아 오는 단계입니다.
도면 좌표표와 실측 로그를 넣으면 보정값 x·y·yaw 와 지점별 잔차·도달 여유가 터미널 요약과 리포트 파일로 나오는 걸 시연합니다
단위 혼입·높이 결측·중복 id·튄 측정점을 섞은 하드 케이스 30종을 넣어도 계산이 멈추지 않고 해당 지점만 remeasure 로 분리되는 걸 시연합니다
참값을 아는 합성 현장에서 추정한 보정값이 참값과 얼마나 떨어지는지 밀리미터·도 단위로 보여줍니다
측정: 참값 대비 절대 오차, 표본: 합성 현장 30종, 2주차
이상치를 걸러내기 전과 후의 잔차 중앙값·95퍼센타일 변화를 재서 걸러낸 효과를 수치로 보여줍니다
측정: 잔차 분포, 표본: 합성 현장 200건, 2주차
진짜 검증은 여기서 멈춥니다. 위 수치는 제가 만든 합성 현장의 참값과 비교한 자가채점이고, 실제 공장 바닥 기울기와 측정 지그 오차, 로봇 기구 편차가 섞인 오차는 홀리데이로보틱스 실장비와 고객사 현장이 있어야 측정됩니다. 이 포트폴리오는 그 측정을 바로 돌릴 수 있는 상태로 만듭니다.
이 포트폴리오가 보여주는 것은 좌표 정합 계산과 현장 로그 처리 파이프라인 기술이며, 산업용 휴머노이드의 기구 설계나 현장 안전 규격 같은 도메인 전문성은 주장하지 않습니다. 모르는 깊이는 면접에서 모른다고 말하는 편이 낫습니다.
고객사도 실장비도 없이 혼자 만든 것이라 모든 수치는 합성 현장의 참값과 비교한 자가채점입니다. 면접에서는 동작하는 계산과 실검증 준비 상태로 솔직히 설명합니다.
정답을 제가 만들었으니 잘 맞는 것이 당연합니다. 단위 혼입·높이 결측·중복 id·튄 측정점을 일부러 섞어 쉬운 문제만 푸는 것이 아님을 보입니다.
안전 판단은 자동 통과에 맡기지 않습니다. 도달 여유가 임계 아래로 내려간 지점과 사람 통로 경계는 통과시키지 않고 사람이 확인할 목록으로 분리합니다.
실제 도입에서 달라지는 것은 로봇 제원과 좌표계 정의, 도면 양식입니다. 고객사마다 다르므로 제원표와 표기 사전을 현장 값으로 갈아 끼워야 합니다.
① 인라인 샘플 · ② seed.json 다운로드 · ③ 증강 프롬프트. 세 층 모두 동일한 schema 에서 파생.
고객사 설비팀이 도면에서 뽑아 준 작업 지점 좌표표를 계산 입력으로 씁니다
| point_id | name_raw | drawing_x_mm | drawing_y_mm | drawing_z_mm | fixture_type | note |
|---|---|---|---|---|---|---|
| FP-001 | 투입 컨베이어 끝단 | 12,450 | 3,080 | 950 | conveyor | — |
| FP-002 | 투입컨베이어끝단(구도면) | 12,450 | 3,080 | 950 | conveyor | 구도면 표기가 그대로 남아 좌표가 겹칩니다 |
| FP-003 | 적재 팔레트 A | 13,820 | 2,410 | — | pallet | 높이 미기재 |
| FP-004 | 적재 팔레트 B | 13,820 | 1,650 | 180 | pallet | — |
| FP-005 | 검사대 | 11.2 | 2.95 | 1.05 | table | 이 행만 미터 단위로 적혀 있습니다 |
{"type":"object","properties":{"point_id":{"type":"string"},"name_raw":{"type":"string"},"drawing_x_mm":{"type":"number"},"drawing_y_mm":{"type":"number"},"drawing_z_mm":{"type":["number","null"]},"fixture_type":{"type":"string"},"note":{"type":["string","null"]}},"required":["point_id","name_raw","drawing_x_mm","drawing_y_mm","drawing_z_mm","fixture_type","note"]}. 쉬운 데이터만 만들지 마세요. 다음 하드 케이스를 의도적으로 섞으세요: 한 행만 미터 단위로 적힌 좌표(11.2 같은 값), drawing_z_mm 결측, 같은 좌표를 가리키는 구도면 중복 id, 셀 병합으로 이름과 좌표가 비어 버린 행, 띄어쓰기와 괄호가 흔들리는 설비 이름, 도면에 없는 현장 추가 지그. 형식을 깨뜨리는 행 3건도 별도로 넣으세요.{"type":"object","properties":{"point_id":{"type":"string"},"name_raw":{"type":"string"},"drawing_x_mm":{"type":"number"},"drawing_y_mm":{"type":"number"},"drawing_z_mm":{"type":["number","null"]},"fixture_type":{"type":"string"},"note":{"type":["string","null"]}},"required":["point_id","name_raw","drawing_x_mm","drawing_y_mm","drawing_z_mm","fixture_type","note"]}로봇 베이스 좌표계에서 찍은 실측 로그를 대응점으로 씁니다
| point_id | base_x_mm | base_y_mm | base_z_mm | samples_n | stddev_mm | captured_at |
|---|---|---|---|---|---|---|
| FP-001 | 940 | 78 | 948 | 20 | 0.6 | 2026-08-02T09:12:31+09:00 |
| FP-003 | 2,310 | -592 | — | 20 | 0.9 | 2026-08-02T09:14:02+09:00 |
| FP-004 | 2,312 | -1,352 | 176 | 20 | 0.7 | 2026-08-02T09:15:40+09:00 |
| FP-005 | -298 | -48 | 1,046 | 20 | 1.1 | 2026-08-02T09:17:12+09:00 |
| FP-006 | -518 | 1,218 | 1,396 | 20 | 0.8 | 2026-08-02T09:18:55+09:00 |
{"type":"object","properties":{"point_id":{"type":["string","null"]},"base_x_mm":{"type":"number"},"base_y_mm":{"type":"number"},"base_z_mm":{"type":["number","null"]},"samples_n":{"type":"number"},"stddev_mm":{"type":["number","null"]},"captured_at":{"type":"string"}},"required":["point_id","base_x_mm","base_y_mm","base_z_mm","samples_n","stddev_mm","captured_at"]}. 쉬운 데이터만 만들지 마세요. 다음 하드 케이스를 의도적으로 섞으세요: point_id 미기재(null), 도면 좌표표에 없는 id, 같은 지점을 나중에 다시 찍은 재측정 행, stddev_mm 이 15 를 넘는 튄 측정, samples_n 이 10 미만인 성급한 측정, base_z_mm 결측. 좌표는 도면 좌표에 알려진 평행이동과 회전을 적용한 값이어야 하고, 튄 행에만 그보다 큰 어긋남을 넣으세요. 형식을 깨뜨리는 행 3건도 별도로 넣으세요.{"type":"object","properties":{"point_id":{"type":["string","null"]},"base_x_mm":{"type":"number"},"base_y_mm":{"type":"number"},"base_z_mm":{"type":["number","null"]},"samples_n":{"type":"number"},"stddev_mm":{"type":["number","null"]},"captured_at":{"type":"string"}},"required":["point_id","base_x_mm","base_y_mm","base_z_mm","samples_n","stddev_mm","captured_at"]}| Python | 도면 엑셀과 실측 로그 읽기, 강체변환 최소제곱 추정, 잔차와 도달 여유 계산 |
| Linux | 고객사 현장 노트북에서 명령 한 줄로 도는 실행 환경 |
| ROS2 | 실측 로그를 rosbag2 덤프에서 뽑고, 계산된 보정값을 TF 프레임 값으로 내보냅니다 |
| Docker | 현장 노트북마다 파이썬 환경이 달라도 같은 계산 결과가 나오도록 묶은 실행 이미지 |
| gRPC | 2주차에 로봇 컨트롤러의 텔레메트리 스트림에서 측정점을 직접 받아 오는 경로 |
| C++ | 고객사 컨트롤러가 내보내는 바이너리 텔레메트리 덤프를 읽는 작은 리더 |
✓ pass → 여기까지가 그 자체로 제출 가능한 완성품입니다. 더 키우려면 2주차 이상치 제거와 오차 분포 측정으로 갑니다.
✓ pass → 여기서 멈춰도 완결입니다. 더 키우려면 3주차 베이스 배치 추천과 rosbag2 직접 읽기로 갑니다.
설치 보정값과 지점별 잔차·도달 여유 판정
{"type":"object","properties":{"fit":{"type":"object","properties":{"dx_mm":{"type":"number"},"dy_mm":{"type":"number"},"yaw_deg":{"type":"number"},"rms_mm":{"type":"number"},"matched_n":{"type":"number"}},"required":["dx_mm","dy_mm","yaw_deg","rms_mm","matched_n"]},"points":{"type":"array","items":{"type":"object","properties":{"point_id":{"type":"string"},"residual_mm":{"type":["number","null"]},"reach_margin_mm":{"type":["number","null"]},"verdict":{"type":"string","enum":["ok","tight","out_of_reach","remeasure","unmatched"]},"basis":{"type":"string"}},"required":["point_id","residual_mm","reach_margin_mm","verdict","basis"]}}},"required":["fit","points"]}[
{
"fit": {
"dx_mm": 11510.4,
"dy_mm": 3001.8,
"yaw_deg": 0.42,
"rms_mm": 3.1,
"matched_n": 8
},
"points": [
{
"point_id": "FP-001",
"residual_mm": 2.4,
"reach_margin_mm": 318,
"verdict": "ok",
"basis": "잔차 2.4mm 로 정합 오차 안이고 도달 반경까지 318mm 남았습니다"
},
{
"point_id": "FP-008",
"residual_mm": 3.6,
"reach_margin_mm": 24,
"verdict": "tight",
"basis": "높이 1972mm 로 도달 한계까지 24mm 만 남아 사람 확인이 필요합니다"
}
]
},
{
"fit": {
"dx_mm": 11510.4,
"dy_mm": 3001.8,
"yaw_deg": 0.42,
"rms_mm": 3.1,
"matched_n": 8
},
"points": [
{
"point_id": "FP-005",
"residual_mm": null,
"reach_margin_mm": null,
"verdict": "remeasure",
"basis": "도면 좌표가 미터 단위로 적혀 있어 정규화 뒤에도 값이 흔들려 재측정이 필요합니다"
},
{
"point_id": "FP-007",
"residual_mm": 27.9,
"reach_margin_mm": 402,
"verdict": "remeasure",
"basis": "재측정 행의 표준편차가 18.7mm 라 잔차 27.9mm 가 측정 흔들림으로 보입니다"
}
]
},
{
"fit": {
"dx_mm": 11510.4,
"dy_mm": 3001.8,
"yaw_deg": 0.42,
"rms_mm": 3.1,
"matched_n": 8
},
"points": [
{
"point_id": "FP-013",
"residual_mm": null,
"reach_margin_mm": null,
"verdict": "unmatched",
"basis": "실측 로그에만 있고 도면 좌표표에 없는 지점입니다"
},
{
"point_id": "FP-009",
"residual_mm": 4.1,
"reach_margin_mm": -86,
"verdict": "out_of_reach",
"basis": "도달 반경을 86mm 넘어서 베이스를 x 방향으로 120mm 옮겨야 들어옵니다"
}
]
}
]fit 값과 지점별 잔차·도달 여유는 참값을 아는 합성 현장으로 자동 검증하고, basis 문장의 타당성은 사람이 읽고 확인합니다.