Repository navigation
sequence
갱신 2026-08-28. 명령을 누가 발행하는가가 08-08 판과 다릅니다. 아래 §0 이 지금 구조이고, 그 뒤 시나리오별 그림은 로봇 쪽 동작(ack 2단계·상태· 비상정지)을 읽는 데 씁니다.
로봇이 받는 토픽·페이로드는 MQTT_SCHEMA-SPOT, 도착 자동화 규칙·큐의 자세한 설계는 LOCATION_AUTOMATION_DESIGN 에 있습니다.
로봇 토픽 robot/{robotId}/command 에 발행하는 것은 OC 서버뿐입니다.
태블릿도 관리자 화면도 직접 쏘지 않습니다 — 서버에 요청하고, 서버가 큐로 순서를
정해 냅니다.
flowchart TD
T["태블릿<br/>선택지를 고른다"] -->|"orchestration/{sess}/task(event)/option/select"| S
A["관리자·테스트 콘솔"] -->|"orchestration/{sess}/spot/command"| S
V["Vision<br/>vision/position/person"] -->|"장소 도착 감지"| S
S["OC 서버"] --> DB[("DB<br/>선택지의 spot_action<br/>장소→웨이포인트 라벨<br/>도착 자동화 규칙")]
DB --> S
S --> Q["디바이스 명령 큐<br/>SQS FIFO · 디바이스별 직렬"]
Q -->|"robot/spot-01/command"| R["SPOT"]
R -->|"robot/spot-01/ack"| Q
Q -->|"완료되면 다음 액션"| Q
R -->|"state · plan · waypoints"| S
S -->|"orchestration/spot/{id}/*<br/>orchestration/{sess}/spot/*"| T
| # | 계기 | 서버가 하는 일 |
|---|---|---|
| 1 | 태블릿이 선택지를 고름 | 그 선택지에 spot_action 이 설정돼 있으면 즉시 발행. 선택 자체가 승인이라 별도 확인 절차가 없다. navigate_to 면 목적지를 그 자리에서 계산한다 — 세션의 다음 방문 장소를 찾고, 그 장소에 매핑된 웨이포인트 라벨을 꺼낸다 |
| 2 | 관리자·테스트 콘솔 |
orchestration/{sessionId}/spot/command 를 받아 그대로 큐에 넣는다. 세션에 배정된 SPOT 이 없으면 거절 |
| 3 | 장소 도착 자동화 (2026-08-22 신규) | Vision 이 방문객 좌표를 계속 발행 → 서버가 장소로 매핑 → 장소가 바뀐 순간 그 (사용자·장소·태스크/이벤트) 에 걸린 규칙을 찾아 자동 발행. 보유 아이템·첫 방문 여부 같은 조건과 쿨다운을 본다 |
Enqueue → 디바이스별 그룹(spot:{robotId})으로 직렬화
→ delay_ms 대기 → MQTT 발행
→ 완료 신호 대기 SPOT 은 ack 의 종결 status (SUCCESS/FAULT_*/ABORTED/TIMEOUT)
→ 다음 액션 적재 규칙 안의 액션 체인
→ timeout_ms(기본 30초) 넘으면 timeout 으로 기록하고 다음으로
왜 한 곳으로 모았나 — SPOT 은 한 번에 하나만 실행하고 실행 중 새 명령은 BUSY 로
거절합니다(§9.1). 태블릿·자동화·콘솔이 서로 모른 채 각자 보내면 뒤엣것이 그냥 죽습니다.
2026-08-10 에 서버가 순서를 맡기로 정했고, 08-22 에 디바이스 공통 큐로 일반화됐습니다.
로봇 쪽은 이 변화로 바뀐 것이 없습니다. 받는 토픽·페이로드·ack 규약이 그대로입니다. 아래 그림들의 화살표 출발점(태블릿)은 옛 판이라 §0 으로 읽어주세요.
sequenceDiagram
participant 태블릿
participant MQTT as MQTT
participant SPOT
participant OC as OC-SERVER
participant 로봇팔
태블릿-->>MQTT: 1. pub (이동 명령 토픽) {destination: "A"}
MQTT-->>SPOT: 2. sub (이동 명령 토픽)
MQTT-->>OC: 3. sub (이동 명령 토픽) → 진행 중 상태 변경
SPOT-->>MQTT: 4. pub (이동 완료 토픽) {status: "arrived", location: "A"}
MQTT-->>OC: 5. sub (이동 완료 토픽)
OC-->>MQTT: 6. pub (로봇 팔 명령 토픽)
MQTT-->>로봇팔: 7. sub (로봇 팔 명령 토픽)
로봇팔-->>MQTT: 8. pub (로봇 팔 작업 완료) {status: "complete"}
MQTT-->>OC: 9. sub (로봇 팔 작업 완료)
OC-->>MQTT: 10. pub (이동 명령 토픽) {destination: "B"}
MQTT-->>SPOT: 11. sub (이동 명령 토픽)
SPOT-->>MQTT: 12. pub (이동 완료 토픽) {status: "arrived", location: "B"}
위 다이어그램에 대해 SPOT 쪽에서 제안하는 규칙입니다. 이견 있으면 알려주세요.
| # | 제안 | 왜 |
|---|---|---|
| 1 | 정밀 정렬은 SPOT 이 한다. 서버가 보낼 명령이 없다 | 로봇팔이 작업하려면 SPOT 이 cm 단위로 서 있어야 합니다. 적재 지점의 AprilTag 를 보고 SPOT 이 스스로 맞춥니다 |
| 2 | 이동 완료(4번)를 받은 뒤에 로봇팔에 지시(6번)한다 | 접수 응답은 "출발했다"일 뿐입니다. 도착 전에 팔이 움직이면 충돌합니다 |
| 3 | 이동이 실패하면 로봇팔 명령을 보내지 않는다 | SPOT 이 없는 자리에서 팔이 작업하면 위험합니다 |
| 4 | 적재 지점에 AprilTag(36h11 / 146mm)를 붙인다 | SPOT 이 자기 위치를 맞추는 기준입니다(팔을 위한 표식이 아닙니다). 웨이포인트 이동만으로는 오차가 수십 cm 라, 팔이 고정 좌표로 작업하려면 SPOT 이 매번 같은 자리에 서 줘야 합니다 |
| 5 | 적재 중에는 SPOT 에 다른 명령을 보내지 않는다 | 팔이 작업하는 동안 SPOT 이 움직이면 안 됩니다 |
| 6 | 목적지(destination)는 이름 붙인 지점만 쓴다 |
SPOT 이 waypoints 토픽(retained)으로 갈 수 있는 곳 목록을 발행합니다. 그 목록에 없는 값은 거부됩니다 |
| 7 | 이동 완료 응답에 결과 코드를 함께 싣는다 | 위 다이어그램의 {status:"arrived"} 는 성공만 표현합니다. 실패했을 때도 같은 토픽으로 이유가 와야 서버가 다음 판단을 할 수 있습니다 (자세한 값은 MQTT_SCHEMA-SPOT) |
미검증 — 이 흐름은 아직 로봇팔과 함께 시험해보지 않았습니다. 정렬 정확도와 소요 시간은 합동 시험 후에 채우겠습니다.
로봇팔이 관여하지 않는 SPOT 시나리오들입니다. 사람이 시작하는 명령은 태블릿이 선택지 선택으로 알리고, OC 서버가 그것을 SPOT 명령으로 바꿔 발행합니다 (§0). 태블릿은 로봇 토픽에 직접 쏘지 않습니다.
전시 컨셉은 고객의 요청을 받으면 시스템이 알아서 시나리오를 돌리는 것입니다. 그 "알아서" 가 일어나는 자리는 태블릿·OC 서버 쪽이고, SPOT 은 그 결과로 정해진 시나리오를 실행합니다.
고객 요청 → 어떤 시나리오를 돌릴지 판단 → 지령 발행 → SPOT 이 실행 (관리자가 미리 DB 에 설정 → OC 서버가 조회) (판단 안 함)SPOT 은 "무엇을 할지" 를 스스로 고르지 않습니다. 받은 시나리오를 어떻게 수행할지(경로, 자세, 정렬)만 정합니다.
SPOT 이 지령 없이 스스로 하는 일은 두 가지뿐입니다 — 이미 받은 명령을 마무리하는 것(추종 종료 후 위치 재확인 등)과 안전 동작(통신 두절 시 정지, 유휴 시 착석).
토픽·페이로드 상세는 MQTT_SCHEMA-SPOT 참조.
sequenceDiagram
participant 태블릿
participant MQTT
participant SPOT
participant OC as OC-SERVER
태블릿-->>MQTT: 1. pub (task/option/select) {option_id}
MQTT-->>OC: 2. sub → DB 조회 (spot_action · 다음 장소 → 웨이포인트 라벨) → 큐
OC-->>MQTT: 3. pub (command) {action:"navigate_to", destination:"p2"}
MQTT-->>SPOT: 4. sub (command)
SPOT-->>MQTT: 4. pub (ack) {status:"ACCEPTED"}
MQTT-->>OC: 5. sub (ack)
Note over SPOT: 위치추정 확인 → 경로 계산 → 주행<br/>중간 경유지는 SPOT 이 알아서 지나간다
loop 1Hz
SPOT-->>MQTT: pub (state) {fsm:"NAVIGATING", current_waypoint_label:…}
MQTT-->>OC: sub (state)
end
alt 도착
SPOT-->>MQTT: 6. pub (ack) {status:"SUCCESS", location:"p2"}
MQTT-->>OC: 7. sub (ack)
else 자기 위치를 모름
SPOT-->>MQTT: 6. pub (ack) {status:"FAULT_NAV", code:"NOT_LOCALIZED"}
MQTT-->>OC: 7. sub (ack) → 운영자 호출
end
| # | 제안 | 왜 |
|---|---|---|
| 1 | 목적지는 이름 붙인 지점만 보낸다 | 자동 생성 경유지(waypoint_7)는 길이지 장소가 아닙니다. 목록은 waypoints 토픽(retained)에 있습니다 |
| 2 | 경로는 발행자가 정하지 않는다 | 어느 경유지를 거칠지는 SPOT 이 계산합니다. 최종 목적지만 주면 됩니다 |
| 3 | NOT_LOCALIZED 는 재시도하지 않는다 |
로봇이 자기 위치를 모르는 상태라 몇 번을 보내도 같은 실패입니다. 사람이 태그가 보이는 곳으로 옮겨야 풀립니다 |
| 4 | 그 외 FAULT_NAV 는 1회 재시도 후 다른 목적지로 재계획 |
사람이 길을 막고 있는 경우가 대부분이라 잠시 후면 풀립니다 |
| 5 | 이동 중 새 이동 명령은 BUSY 로 거절된다 |
앞 명령의 완료를 받고 다음을 보내주세요 |
속도 — 전시장 기본 0.15 m/s 로 고정입니다. 관객 사이를 다니므로 발행자가 올릴 수 없게 했습니다.
뒤로 걷지 않습니다 — 방향이 안 맞으면 회전해서 앞으로 갑니다. 관객 눈에 고장으로 보이고, 진행 방향을 카메라가 못 보기 때문입니다.
sequenceDiagram
participant 태블릿
participant MQTT
participant SPOT
participant OC as OC-SERVER
Note over MQTT,OC: 관리자 백오피스가 scenarios (retained) 구독<br/>→ 선택지의 scenario_id 후보를 채운다
Note over OC: 선택지에 설정된 spot_action · scenario_id 를 DB 에서 조회
태블릿-->>MQTT: 1. pub (option/select) {option_id}
MQTT-->>OC: 2. sub → 선택지에 걸린 scenario_id 를 DB 에서 꺼냄 → 큐
OC-->>MQTT: 3. pub (command) {action:"run_scenario", scenario_id:"guide"}
MQTT-->>SPOT: 4. sub (command)
SPOT-->>MQTT: 4. pub (ack) {status:"ACCEPTED"}
MQTT-->>OC: 5. sub (ack)
Note over SPOT: 어떤 동작들로 이루어졌는지는 SPOT 이 안다<br/>발행자는 이름만 보냈다
SPOT-->>MQTT: 6. pub (plan) {step_index:0, total:3, status:"SUCCESS"}
MQTT-->>OC: 7. sub (plan) → 진행률 갱신
SPOT-->>MQTT: pub (plan) {step_index:1, …}
MQTT-->>OC: sub (plan)
SPOT-->>MQTT: pub (plan) {step_index:2, …}
MQTT-->>OC: sub (plan)
SPOT-->>MQTT: 8. pub (ack) {status:"SUCCESS"}
MQTT-->>OC: 9. sub (ack)
| # | 제안 | 왜 |
|---|---|---|
| 1 | 시나리오 이름만 보낸다 | "세부 로직은 로봇에서 처리" 원칙을 지키는 방법입니다. 인사 동작·대기 시간 같은 건 발행자가 몰라도 됩니다 |
| 2 | 시나리오 목록은 scenarios 토픽(retained)에서 받는다 |
관리자 UI 에서 시나리오를 고치면 자동으로 반영됩니다. 태블릿·서버 코드를 고칠 필요가 없습니다 |
| 3 | 진행률은 plan 토픽으로 나간다 |
3단계 중 2단계라는 걸 태블릿에 보여줄 수 있습니다. 완료만 기다리면 그 사이가 깜깜합니다 |
| 4 | 시나리오 안의 낱개 동작은 ack 를 쏘지 않는다 |
보내지 않은 명령의 응답이 오면 혼란스럽습니다. 시나리오 전체에 대해 한 번만 옵니다 |
| 5 | 로봇이 못 하는 동작이 섞여 있으면 unsupported_steps 로 알린다 |
조용히 빼고 실행하면 완전히 수행된 줄 압니다 |
변수 치환 — 시나리오에 $spot 같은 자리가 있으면 variables 로 채웁니다.
무엇으로 채울지(태블릿에서 고른 목적지 등)는 발행하는 쪽이 정합니다.
sequenceDiagram
participant 태블릿
participant MQTT
participant SPOT
participant OC as OC-SERVER
태블릿-->>MQTT: 1. pub (option/select) {option_id}
MQTT-->>OC: 2. sub → DB 조회 → 큐
OC-->>MQTT: 3. pub (command) {action:"follow", mode:"start"}
MQTT-->>SPOT: 4. sub (command)
SPOT-->>MQTT: 4. pub (ack) {status:"ACCEPTED"}
MQTT-->>OC: 5. sub (ack)
Note over SPOT: 제일 가까운 사람을 잡고 따라간다<br/>좌우로 둘러보는 중 = 아직 못 찾음
alt 손님이 그냥 자리를 뜸
Note over SPOT: 25초 동안 안 보이면 스스로 종료
SPOT-->>MQTT: 6. pub (ack) {status:"SUCCESS", reason:"target_lost"}
else 태블릿에서 종료
태블릿-->>MQTT: pub (option/select) → OC
OC-->>MQTT: pub (command) {action:"follow", mode:"stop"}
MQTT-->>SPOT: sub (command)
SPOT-->>MQTT: 6. pub (ack) {status:"SUCCESS"}
end
MQTT-->>OC: 7. sub (ack)
Note over SPOT: 종료 후 자기 위치를 다시 잡는다<br/>추종은 맵 경로를 안 타서 위치가 흐려진다
| # | 제안 | 왜 |
|---|---|---|
| 1 | 대상은 시작 시점에 제일 가까운 사람 | 얼굴을 보지 않으므로 "누구"를 지정할 수 없습니다. 따라올 사람이 로봇 앞에 서면 됩니다 |
| 2 | 한 번 잡으면 다른 사람으로 바뀌지 않는다 | 관객이 앞을 스쳐도 유지합니다. 완전히 놓쳐야 다시 고릅니다 |
| 3 | 25초 동안 사람이 안 보이면 스스로 끝낸다 | 손님이 그냥 가버리는 게 전시에서 가장 흔합니다. 매번 종료 명령을 보내주기를 기대할 수 없습니다 |
| 4 | 한 번에 최대 5분 | 잊고 방치되는 것을 막습니다 |
| 5 | 종료 후 SPOT 이 스스로 위치를 다시 잡는다 | 추종은 맵 경로를 안 타서 끝나면 자기 위치가 흐려집니다. 이걸 안 하면 다음 이동 명령이 조용히 실패합니다 |
| 6 | 유지 거리 2m, 최대 0.2 m/s | 발행자가 바꿀 수 없게 했습니다. 관객에게 빠르게 접근하는 일이 없어야 합니다 |
관객이 보는 신호 — 좌우로 크게 둘러보면 "아직 못 찾음", 멈추고 따라오면 "잡았음"입니다. 동작은 이 하나뿐입니다. 여러 개를 두면 관객이 구분하지 못합니다.
태블릿을 누르지 않아도 로봇이 움직이는 유일한 경로. 관람객이 그 장소에 도착하는 것만으로 미리 정해둔 명령이 나갑니다.
sequenceDiagram
participant V as Vision
participant MQTT
participant OC as OC-SERVER
participant SPOT
V-->>MQTT: vision/position/person {좌표, zone_id}
MQTT-->>OC: sub (계속 들어온다)
Note over OC: zone → 장소 매핑<br/>**장소가 바뀐 순간만** 아래로 진행
Note over OC: 이 (사용자·장소·태스크/이벤트) 에 걸린 규칙을 찾는다<br/>보유 아이템 · 첫 방문 여부 · 쿨다운 검사
OC-->>MQTT: pub (command) {action, params}
MQTT-->>SPOT: sub (command)
SPOT-->>MQTT: ack {status:"ACCEPTED"}
SPOT-->>MQTT: ack {status:"SUCCESS"}
MQTT-->>OC: sub (ack)
Note over OC: 완료를 받으면 **규칙 안의 다음 액션**을 큐에 넣는다<br/>(로봇팔·반려로봇·Hub 로 이어질 수 있다)
| 무엇이 발화하나 | 장소 자체가 아니라 (사용자, 장소, 태스크/이벤트) 매핑이 정한다. 같은 "집"이라도 세션마다 다르다 |
| 안 나가는 경우 | 규칙이 요구하는 아이템이 없으면 missing_item, 그 장소에 디바이스가 매핑 안 돼 있으면 no device 로 건너뛴다 |
| 로봇이 아는 것 |
없다. 로봇에게는 평범한 robot/spot-01/command 로 보인다 |
마지막 줄이 요점입니다 — 로봇 쪽은 이 기능이 생겨도 바뀐 것이 없습니다.
sequenceDiagram
participant 운영자
participant SPOT
participant MQTT
participant OC as OC-SERVER
participant 태블릿
Note over SPOT: 이동 중 (command_id: cmd-0042)
운영자-->>SPOT: STOP (관리자 UI 또는 물리 버튼)
Note over SPOT: MQTT 를 거치지 않는 최단 경로로 즉시 정지
SPOT-->>MQTT: 1. pub (estop, retained) {active:true, reason:"soft_stop"}
MQTT-->>OC: 2. sub (estop)
MQTT-->>태블릿: 3. sub (estop) → 화면에 정지 표시
SPOT-->>MQTT: 4. pub (ack) {command_id:"cmd-0042", status:"ABORTED"}
MQTT-->>OC: 5. sub (ack)
Note over OC,태블릿: 명령 발행 중단
운영자-->>SPOT: RESUME
SPOT-->>MQTT: 6. pub (estop, retained) {active:false}
MQTT-->>OC: 7. sub (estop)
MQTT-->>태블릿: 8. sub (estop) → 정지 표시 해제
| # | 제안 | 왜 |
|---|---|---|
| 1 | 정지는 MQTT 를 거치지 않는다 | 브로커가 죽어도 멈춰야 합니다. MQTT 로는 "멈췄다"는 사실만 알립니다 |
| 2 | 정지는 무엇보다 우선한다 |
BUSY 여도 받습니다. 다른 명령이 돌고 있어도 즉시 멈춥니다 |
| 3 | 기본 정지는 전원을 끄는 게 아니다 | 선 채로 멈춥니다. 바로 재개할 수 있습니다. 전원 차단은 별도 버튼입니다 |
| 4 | 진행 중이던 명령은 ABORTED 로 종료 보고한다 |
그 명령의 결과를 영원히 기다리지 않게 |
| 5 | estop.active=true 동안 명령 발행을 멈춘다 |
보내봐야 거부되거나, 더 나쁘게는 사람이 개입 중인데 다시 움직입니다 |
| 6 | 복구는 사람이 한다 | 자동 복구를 넣지 않았습니다. 왜 멈췄는지 사람이 확인해야 합니다 |
| 7 |
estop 은 retained 로 발행한다 |
태블릿·서버가 나중에 켜져도 지금 정지 상태임을 즉시 압니다 |
정지 트리거
| 트리거 | 누가 | 결과 | 복구 |
|---|---|---|---|
| STOP | 운영자 | 즉시 멈춤, 선 채로 | RESUME |
| STOP + SIT | 운영자 | 멈추고 앉음 | RESUME |
| 하드 E-Stop | 운영자 | 모터 전원 차단 | RESUME |
| 명령 만료 | 자동 | 조종자가 죽으면 3초 뒤 정지 | 연결 복구 후 재명령 |
| 데드맨 | 자동 | 통신 두절 30초 뒤 앉고 전원 차단 | RESUME |
전시 중 관리자가 로봇을 직접 몰아야 하는 상황이 생깁니다 — 장애물 제거, 위치 조정 등. 로봇은 한 번에 한 명만 몰 수 있어서, 관리자가 가져가는 동안 발행된 명령은 실패합니다.
sequenceDiagram
participant 관리자 as 관리자 노트북
participant SPOT
participant MQTT
participant OC as OC-SERVER
participant 태블릿
Note over MQTT,태블릿: 평상시 — state: commands_accepted=true
관리자-->>SPOT: 제어권 회수 (현장에서 직접 조작하려고)
SPOT-->>MQTT: 1. pub (state, retained) {commands_accepted:false, lease_owner:"operator"}
MQTT-->>OC: 2. sub (state)
MQTT-->>태블릿: 3. sub (state) → "점검 중" 표시
SPOT-->>MQTT: 4. pub (ack) {status:"FAULT_LEASE"}
MQTT-->>OC: 5. sub (ack)
Note over OC,태블릿: 명령 발행 중단하고 대기
관리자-->>SPOT: 제어권 반납 (버튼을 눌러야 함 — 자동 반납 없음)
SPOT-->>MQTT: 6. pub (state, retained) {commands_accepted:true, lease_owner:"orchestration"}
MQTT-->>OC: 7. sub (state)
MQTT-->>태블릿: 8. sub (state) → 정상 표시
| # | 제안 | 왜 |
|---|---|---|
| 1 | 현장 관리자가 발행자보다 우선한다 | 눈으로 보고 있는 사람이 판단할 수 있어야 합니다 |
| 2 |
state 에 commands_accepted 를 넣는다. 새 토픽은 만들지 않는다 |
이미 구독하는 state(1Hz, retained)에 불리언 하나면 충분합니다. 서버가 lease_owned 를 해석할 필요 없이 "지금 명령이 먹나" 를 바로 알 수 있습니다 |
| 3 |
commands_accepted:false 동안 발행을 멈춘다 |
보내면 전부 FAULT_LEASE 로 실패합니다 |
| 4 | 진행 중이던 명령은 FAULT_LEASE 로 종료 보고한다 |
그 명령의 결과를 영원히 기다리지 않게 |
| 5 | 자동 반납은 없다. 관리자가 직접 반납해야 한다 | 타이머로 자동 반납하면, 관리자가 로봇 옆에서 조치하는 중에 제어권이 넘어가 사람 옆에서 로봇이 움직입니다 |
commands_accepted가false가 되는 경우 — 관리자 제어권 회수, 비상정지 중, 배터리 부족. 이유는state의 다른 필드(lease_owner,estop_state,battery_pct)로 구분할 수 있습니다.
관리자가 반납을 잊으면 전시가 멈춥니다(로봇은 서 있는데 명령이 전부 거부). 관리자 UI 상단에 제어권 보유가 항상 표시되고, 오래 쥐고 있으면 경고가 뜹니다.
시나리오를 가리지 않고 적용됩니다.
SPOT 은 명령을 하나씩만 실행합니다. 실행 중 새 명령은 BUSY 로 거절합니다 (STOP 제외).
제안 — 발행하는 쪽이 순서를 관리해주세요. 앞 명령의 완료 응답을 받은 뒤 다음을 보내는 방식이 가장 단순합니다.
태블릿과 OC 서버가 둘 다 발행할 수 있다면, 서로 모르는 채로 동시에 보내면 뒤엣것이
BUSY로 거절됩니다. 누가 순서를 관리할지 정해야 합니다 (아래 협의 사항 1번).
| 수준 | SPOT 동작 | 대응 제안 |
|---|---|---|
| 35% 이하 | 상태에 표시 | 긴 시나리오를 새로 시작하지 않기 |
| 30% 미만 | 전원 인가가 거부될 수 있음 | 충전 안내 |
| 25% 이하 | 새 이동 명령 거부 | 운영자 호출 |
3분 동안 명령이 없으면 SPOT 이 스스로 앉습니다. 다음 명령에 자동으로 다시 일어섭니다. 서 있는 것만으로 배터리가 빠르게 닳기 때문입니다. 따로 할 일은 없습니다.
state 토픽에 connection:"offline" 이 뜹니다. SPOT 이 발행하는 게 아니라 브로커가
대신 발행합니다(MQTT LWT). 브로커가 알아채는 데 최대 60초 걸리므로 timestamp 를
같이 보고 판단해주세요.
| # | 항목 | 지금 | 물어보고 싶은 것 |
|---|---|---|---|
| 1 | 동시 발행 정리 | 태블릿·OC 서버 둘 다 robot/+/command 쓰기 권한 보유 (브로커 ACL 확인) |
SPOT 은 한 번에 하나만 실행하고, 실행 중 새 명령은 BUSY 로 거절합니다. 둘이 서로 모르는 채로 보내면 뒤엣것이 거절됩니다. 누가 순서를 관리할지 정해야 합니다 |
| 2 | 시나리오 목록 발행 주체 | 관리자 UI 가 scenarios 토픽(retained)으로 발행 |
서버가 시나리오를 만들거나 관리할 계획이 있다면 발행 주체를 옮겨야 합니다. 지금 계획을 알려주세요 |
안 해본 것을 했다고 적으면 그걸 전제로 개발하시게 되므로 나눠 적었습니다.
| 항목 | 상태 |
|---|---|
| 지점 이동 완주 | ✅ 2026-08-07, MQTT 경로로 웨이포인트 7개 통과 |
| 시나리오 실행 | ✅ 3스텝 전부 성공, session_id 그대로 되돌아옴 |
| 사람 추종 시작·정지 | ✅ |
| 추종 중 STOP | ✅ 1초 안에 정지 |
| 1Hz 상태 발행 | ✅ |
| 목적지 목록(retained) | ✅ |
state.commands_accepted (5절 제안) |
⬜ 제안 단계 — 미구현 |
| 충전 위치 복귀 | ⬜ 미검증 |
| 로봇팔 연동 전체 흐름 | ⬜ 미시험 |
- Google ADK 검토 (프레임워크·모델 비교)
- 페르소나 + 상황 카드 모델 (2차 시나리오 구동 방식)
- Mac Studio 로컬 LLM + Claude Opus 하이브리드 라우팅 전략
- 개발 일정·할 일 점검표 (단계별 진행 점검)
- 로봇 Adapter 개발 온보딩 (HA·MQTT 계정 등록, 토픽 적용, 테스트 송수신, 상태 확인)
- LG ThinQ 가전 연동 (HA 통합 · REST 데이터 취득 · 제어)
- 장소 도착 자동화 (태스크/이벤트/장소 규칙 → SPOT·로봇팔·반려로봇·Hub 자동 명령)
- 엔딩 화면 데이터 출처 점검 (차량 3필드 · 세션 종료 엔딩 5화면)