SAC — Infra Controller / Gateway

handover zone 안전 판단 · 게이트/전광판 command · device fact 정규화 계층

HSS → Controller 직접 LiDAR·ICS → Gateway 경유 Public GW ↔ 업무 context 인터랙티브(Redoc) →

개요

SAC는 Infra Controller + Infra Gateway 계층이다. 카메라(HSS)·LiDAR·ICS의 사실(fact)과 Public Gateway의 상위 업무 context를 보고 handover zone 상태, 안전 latch, 게이트/전광판 command를 만든다.

업무 상태기계(job/slot/Entry: READY·FULL·CAN_ENTER·ROBOT_IS_WORKING …)는 YMS/PMS 소유로 SAC 범위 밖이다. SAC는 그 이벤트에 반응해 인프라를 제어하고 결과를 handoff한다.
레이어책임
Public GatewayPMS/YMS/FMS 업무 context 전달, 결과 handoff (얇은 변환기)
Infra ControllerHSS/PG/Gateway fact → 상태·안전·게이트 command intent
Infra GatewayADAM·QLight·LiDAR·ICS·차단기 정규화 + command dispatch/ack
HSS카메라 기반 사람/도어/정렬/높이/health fact producer

아키텍처 · 데이터 경로

Public Gateway
PMS/YMS/FMS 업무 context
Infra Controller
상태 · 안전 · command 판단
Infra Gateway
정규화 · dispatch/ack
ICS · LiDAR · QLight · 차단기
device

세 경계가 모두 양방향이다. 사실(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는 그것을 안전 판단에 넣는다(연결 미확인은 통과 조건이 아니다).

소스경로
HSSHSS → Infra Controller (직접)사람/도어/정렬/높이/health
LiDARLiDAR → Infra Gateway → Controller차량 높이
ICSICS → Infra Gateway → Controllere-stop, 경광등

입 · 출차 시퀀스 (게이트 타이밍)

입차 — 한 건이 오가는 순서

목업(/)의 시퀀스 패널이 이 순서다. 상위 표시는 PGW/YMS 가 답하는 자리이며, /theother 받은편지함이 그 답을 대신 준다.

#방향내용외부(고객측)내부(로봇측)목업 API
1SAC → PGWLPR_RECOGNIZED 보고 — 차량이 존 앞에 도착CLOSEDCLOSED/api/pg-lpr-report
2상위 → SAC예약 확인 + 차량 제원 + job(IN)CLOSEDCLOSED/api/pg-reservation-confirm
3SAC → HSSSTART_MONITORING VEHICLE_HEIGHT(제원 동반) → 높이 판정CLOSEDCLOSED/api/hss-check {"check":"height"}
3′SAC → PGWENTRY_PRE_AUTHORIZED 보고 + 입차 차단기 개방OPENCLOSED3번에서 자동
4HSS → SACVEHICLE_ACCESS IN — 차량이 존 안으로OPENCLOSED/api/vehicle-state {"presence":"in"}
5HSS → SACREALTIME_ALIGNMENT — 정렬 substateOPENCLOSED/api/vehicle-state {"alignment":"good"}
6SAC → HSSSTART_MONITORING ZONE_READY → 존 준비 판정OPENCLOSED/api/hss-check {"check":"zone_ready"}
7상위 → SAC로봇 가용 + 운행가능 확인 → ENTRY_READYOPENCLOSED/theother 「운행가능 확인 → 로봇 호출」
8상위 → SAC로봇 호출(/carry)CLOSE외부 CLOSE 확인 후 OPEN같은 버튼
9RMS → SAC상차 시작 → 상차 완료CLOSEOPEN → CLOSE시퀀스 패널
10HSS → SACVEHICLE_ACCESS OUTZONE_RELEASEDCLOSECLOSE/api/vehicle-state {"presence":"out"}

차단기를 여는 판단은 SAC 의 것이다. 계약상 개방은 entry_pre_authorized 승인이 서야 가능하고 그 승인은 PGW 의 carry-gate-in 으로 오지만, 운영상 예약 확인이 곧 승인이므로 SAC 은 예약이 확인된 차량에 한해 자기 높이 판정 직후 연다. 순서가 중요하다 — 승인을 높이 판정보다 먼저 세우면 높이 초과 차량에도 차단기가 열린다.

높이 초과는 입차 거부이고 비상정지가 아니다. 3′ 보고가 나가지 않고 차단기도 열리지 않으며, 전광판이 「높이제한초과 회차바랍니다」로 바뀐다. 정상화로 푸는 대상이 아니다. 문 열림·정렬 불량도 진행 차단일 뿐이다. 비상 해제를 막는 것은 비상 래치(비상정지 버튼, 차단기 닫힘 상태의 사람 감지, vision fail, 통신 끊김)뿐이다.

완료 보고는 차량 세션 안에서 처리돼야 한다. 10번(차량 OUT)을 9번의 완료 보고보다 먼저 보내면 세션이 끝나 완료가 맥락 불일치로 거부된다.

출차

단계외부(고객측)내부(로봇측)
로봇 호출CLOSEDOPEN
운행 완료OPENCLOSE
고객 출차CLOSECLOSE

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-eventsPG → SACLPR · gate · carry 이벤트
pg/v1/{site}/{zone}/vehicle-contextPG → SAC차량 제원
pg/v1/{site}/{zone}/job-contextPG → SACjob_type(IN/OUT) · carry_phase
pg/v1/{site}/{zone}/operator-actionsPG → SAC키오스크 · 운행가능 · 시스템 e-stop/정상화
pg/v1/{site}/{zone}/safety-overridesPG → SAC권한 검증된 FORCE_PASS_ACTIVATE/CANCEL 전용
infra/v1/{site}/{zone}/controller-statusSAC → 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목업 조작 뷰(차량 상태 조작판 · 시퀀스 · 물리 장치)
:18021routes 뷰(내부 메시지 로그) — /?view=routes 와 같은 화면
/error오류 화면 — 모듈별 원인 · 담당 · 조치 (JSON: /api/errors)
/theother상위 업무 연계 시험 — PGW/YMS/RMS 대행 · 받은편지함
/api/docs이 문서
/api/redoc인터랙티브 API(Redoc)
/api/openapi.jsonOpenAPI 스펙
pg/1.0 gate-in 차량정보 (dev)
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 얇은 변환기.)

클라이언트 = pg surface 정렬 dev host 도달 (실측) ⚠️ pg 서비스 base URL 필요

gate-in 차량정보 호출 여정 (pg/1.0)

SAC 시퀀스
gate-in 호출 이전 (자유 구성)
POST /robot-parkings/carry-gate-in
pg → YMS 포워딩
응답 + GET /robot-parkings
gate-in 한 차량 정보 (pg 경유)

pg/1.0 surface (SAC가 쓰는 것)

endpoint용도
POST /robot-parkings/carry-gate-ingate-in 호출 (body는 passthrough)
GET /robot-parkingsgate-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 매칭
테스트에 필요한 단 하나 = pg 서비스 base URL. 클라이언트는 위 pg surface에 이미 정렬돼 있고, dev host 자체는 도달 확인됐다. pg 서비스는 docs host(dev.yms.hlrobotics.click) 루트에 없으므로(별도 프로세스), 그 base URL을 YMS/PMS 개발자에게 받으면 즉시 end-to-end 실행된다.

참고: YMS core(POST /entries / GET /entries/{id})는 dev 루트에서 직접 응답하지만, 이는 pg를 우회하는 디버그 fallback일 뿐 정식 경로가 아니다 (--yms 옵션).