SAC — Infra Controller / Gateway
handover zone 안전 판단 · 게이트/전광판 command · device fact 정규화 계층
개요
SAC는 Infra Controller + Infra Gateway 계층이다. 카메라(HSS)·LiDAR·ICS의 사실(fact)과 Public Gateway의 상위 업무 context를 보고 handover zone 상태, 안전 latch, 게이트/전광판 command를 만든다.
READY·FULL·CAN_ENTER·ROBOT_IS_WORKING …)는
YMS/PMS 소유로 SAC 범위 밖이다. SAC는 그 이벤트에 반응해 인프라를 제어하고 결과를 handoff한다.
| 레이어 | 책임 |
|---|---|
| Public Gateway | PMS/YMS/FMS 업무 context 전달, 결과 handoff (얇은 변환기) |
| Infra Controller | HSS/PG/Gateway fact → 상태·안전·게이트 command intent |
| Infra Gateway | ADAM·QLight·LiDAR·ICS·차단기 정규화 + command dispatch/ack |
| HSS | 카메라 기반 사람/도어/정렬/높이/health fact producer |
아키텍처 · 데이터 경로
세 경계가 모두 양방향이다. 사실(fact)은 장치 → Gateway → Controller → Public GW 로 올라가고, 명령(command)과 업무 지시는 그 역방향으로 내려온다.
HSS는 Infra Controller에 직접 붙는다(카메라 fact). LiDAR·ICS는 Infra Gateway가 정규화해 Controller로 전달한다.
장치 health도 같은 경로를 탄다. 각 infra 장치의 상태·생존은 Infra Gateway가 모아 Controller까지 올린다 — 응답이 끊긴 것 자체를 판단 근거로 쓰기 위해서다. Gateway는 device/gateway 별 timeout 을 감시해 끊김을 사건으로 만들고, Controller는 그것을 안전 판단에 넣는다(연결 미확인은 통과 조건이 아니다).
| 소스 | 경로 | 예 |
|---|---|---|
| HSS | HSS → Infra Controller (직접) | 사람/도어/정렬/높이/health |
| LiDAR | LiDAR → Infra Gateway → Controller | 차량 높이 |
| ICS | ICS → Infra Gateway → Controller | e-stop, 경광등 |
입 · 출차 시퀀스 (게이트 타이밍)
입차 — 한 건이 오가는 순서
목업(/)의 시퀀스 패널이 이 순서다. 상위 표시는 PGW/YMS 가 답하는 자리이며, /theother 받은편지함이 그 답을 대신 준다.
| # | 방향 | 내용 | 외부(고객측) | 내부(로봇측) | 목업 API |
|---|---|---|---|---|---|
| 1 | SAC → PGW | LPR_RECOGNIZED 보고 — 차량이 존 앞에 도착 | CLOSED | CLOSED | /api/pg-lpr-report |
| 2 | 상위 → SAC | 예약 확인 + 차량 제원 + job(IN) | CLOSED | CLOSED | /api/pg-reservation-confirm |
| 3 | SAC → HSS | START_MONITORING VEHICLE_HEIGHT(제원 동반) → 높이 판정 | CLOSED | CLOSED | /api/hss-check {"check":"height"} |
| 3′ | SAC → PGW | ENTRY_PRE_AUTHORIZED 보고 + 입차 차단기 개방 | OPEN | CLOSED | 3번에서 자동 |
| 4 | HSS → SAC | VEHICLE_ACCESS IN — 차량이 존 안으로 | OPEN | CLOSED | /api/vehicle-state {"presence":"in"} |
| 5 | HSS → SAC | REALTIME_ALIGNMENT — 정렬 substate | OPEN | CLOSED | /api/vehicle-state {"alignment":"good"} |
| 6 | SAC → HSS | START_MONITORING ZONE_READY → 존 준비 판정 | OPEN | CLOSED | /api/hss-check {"check":"zone_ready"} |
| 7 | 상위 → SAC | 로봇 가용 + 운행가능 확인 → ENTRY_READY | OPEN | CLOSED | /theother 「운행가능 확인 → 로봇 호출」 |
| 8 | 상위 → SAC | 로봇 호출(/carry) | CLOSE | 외부 CLOSE 확인 후 OPEN | 같은 버튼 |
| 9 | RMS → SAC | 상차 시작 → 상차 완료 | CLOSE | OPEN → CLOSE | 시퀀스 패널 |
| 10 | HSS → SAC | VEHICLE_ACCESS OUT → ZONE_RELEASED | CLOSE | CLOSE | /api/vehicle-state {"presence":"out"} |
차단기를 여는 판단은 SAC 의 것이다. 계약상 개방은 entry_pre_authorized
승인이 서야 가능하고 그 승인은 PGW 의 carry-gate-in 으로 오지만, 운영상
예약 확인이 곧 승인이므로 SAC 은 예약이 확인된 차량에 한해 자기 높이 판정 직후 연다.
순서가 중요하다 — 승인을 높이 판정보다 먼저 세우면 높이 초과 차량에도 차단기가 열린다.
높이 초과는 입차 거부이고 비상정지가 아니다. 3′ 보고가 나가지 않고 차단기도 열리지 않으며, 전광판이 「높이제한초과 회차바랍니다」로 바뀐다. 정상화로 푸는 대상이 아니다. 문 열림·정렬 불량도 진행 차단일 뿐이다. 비상 해제를 막는 것은 비상 래치(비상정지 버튼, 차단기 닫힘 상태의 사람 감지, vision fail, 통신 끊김)뿐이다.
완료 보고는 차량 세션 안에서 처리돼야 한다. 10번(차량 OUT)을 9번의 완료 보고보다 먼저 보내면 세션이 끝나 완료가 맥락 불일치로 거부된다.
출차
| 단계 | 외부(고객측) | 내부(로봇측) |
|---|---|---|
| 로봇 호출 | CLOSED | OPEN |
| 운행 완료 | OPEN | CLOSE |
| 고객 출차 | CLOSE | CLOSE |
Public GW ↔ SAC 채널 계약
채널 의미·payload field는 SAC가 소유·정의한다(transport는 무관). pg/1.0은 PMS REST → YMS REST / FMS Redis / Infra REST|MQTT 얇은 변환기.
| channel | 방향 | 내용 |
|---|---|---|
| pg/v1/{site}/{zone}/vehicle-events | PG → SAC | LPR · gate · carry 이벤트 |
| pg/v1/{site}/{zone}/vehicle-context | PG → SAC | 차량 제원 |
| pg/v1/{site}/{zone}/job-context | PG → SAC | job_type(IN/OUT) · carry_phase |
| pg/v1/{site}/{zone}/operator-actions | PG → SAC | 키오스크 · 운행가능 · 시스템 e-stop/정상화 |
| pg/v1/{site}/{zone}/safety-overrides | PG → SAC | 권한 검증된 FORCE_PASS_ACTIVATE/CANCEL 전용 |
| infra/v1/{site}/{zone}/controller-status | SAC → PG | 상태 · force-pass lifecycle ACK |
API Reference
대시보드 HTTP API. 아래는 /api/openapi.json에서 자동 렌더링된다 — 스키마 탐색은 Redoc 뷰어 참고.
스펙 로딩 중…
실행 · 실험
python3 -m infra_controller.dashboard_server --host 127.0.0.1 --port 18020
| 포트/경로 | 용도 |
|---|---|
| :18020 | 목업 조작 뷰(차량 상태 조작판 · 시퀀스 · 물리 장치) |
| :18021 | routes 뷰(내부 메시지 로그) — /?view=routes 와 같은 화면 |
| /error | 오류 화면 — 모듈별 원인 · 담당 · 조치 (JSON: /api/errors) |
| /theother | 상위 업무 연계 시험 — PGW/YMS/RMS 대행 · 받은편지함 |
| /api/docs | 이 문서 |
| /api/redoc | 인터랙티브 API(Redoc) |
| /api/openapi.json | OpenAPI 스펙 |
PUBLIC_GATEWAY_BASE_URL=<pg-base> \ python3 -m infra_controller.adapters.public_gateway_client 12가3456
dev 연동 · 테스트 (pg/1.0 경유)
정식 경로: SAC → Public Gateway(pg/1.0) → YMS. SAC는 YMS를 직접 호출하지 않고 pg에 호출하며, gate-in 한 차량 정보도 pg를 통해 돌아온다. (pg는 PMS REST → YMS REST / FMS Redis / Infra REST|MQTT 얇은 변환기.)
gate-in 차량정보 호출 여정 (pg/1.0)
pg/1.0 surface (SAC가 쓰는 것)
| endpoint | 용도 |
|---|---|
| POST /robot-parkings/carry-gate-in | gate-in 호출 (body는 passthrough) |
| GET /robot-parkings | gate-in 한 차량/yard 조회 |
| GET /parking-spaces | 면 상태 조회 |
| POST /rms/{carry,drop-zone,pickup-zone}/event | 진행 이벤트 콜백 |
테스트 실행
PUBLIC_GATEWAY_BASE_URL=<pg-서비스-base> \
python3 -m infra_controller.adapters.public_gateway_client <차량번호>
# → POST {base}/robot-parkings/carry-gate-in → GET {base}/robot-parkings 매칭
dev.yms.hlrobotics.click) 루트에
없으므로(별도 프로세스), 그 base URL을 YMS/PMS 개발자에게 받으면 즉시 end-to-end 실행된다.
참고: YMS core(
POST /entries / GET /entries/{id})는 dev 루트에서 직접 응답하지만,
이는 pg를 우회하는 디버그 fallback일 뿐 정식 경로가 아니다 (--yms 옵션).