AMRAgent·MCUAgent 상세 — 장치 전송과 상태 보고
기준:
1398d109c391c4044cae26d0e9aea4d3f08d9670. 지정 커밋의 추적 파일을 직접 확인한 정적 구조 분석이며, 현재 HEAD·후속 TaskManager·SKIX 구현을 포함하지 않는다.
AMRAgent: typed Binder와 AMR 프로토콜
기준 루트 R/는 apps/AMRAgent/java/com/sk/airbot/amragent/다. AMRAgent는 단순 Binder 중계보다 넓다. 명령 객체·송신 예약·수신 디코딩·장치 상태·callback을 함께 소유한다. Android.mk가 Java/AIDL을 BUILD_PACKAGE로 빌드한다.
| 내부 구성 | 책임 | 근거 |
|---|---|---|
| AMRAgent | 서비스 시작, IAMRControl Stub, 네트워크 변화 수신 | R/AMRAgent.java:188, :266, :718 |
| AMRCmdDispatcher | AMRCommand HandlerThread, 지연·반복 명령과 command 생성 | R/AMRCmdDispatcher.java:170–199, :834 이후 |
| command/ | 매핑·주행·도킹·지도·상태·센서·보정·OTA별 명령 객체 | R/command/ |
| RecvThread | socket 수신 loop, frame·명령 종류 해석, timeout, 상태 Bundle | R/RecvThread.java:146–472 |
| AMRState | 매핑·주행·공장 모드 등의 장치 상태 | R/AMRState.java |
| CallbackHandler | 등록된 IAMRControlCallback에 report 전달 | CallbackHandler.java:34–78 (아래 소스 색인 참조) |
| SockSender·통신 보조 | 실제 AMR transport와 명령 전송 | 같은 모듈의 socket 관련 클래스 |
정상 호출 경로
DeviceAgent AMRService / AMR 기능 wrapper
→ IAMRControl.opMapping / opDriving / opSetTargetPosition …
→ AMRAgent typed 메서드의 인자 검사
→ AMRCmdDispatcher 메시지 예약
→ command 객체 send → socket 전송
→ RecvThread 수신·상태 디코딩
→ CallbackHandler.notifyAll
→ DeviceAgent MainService의 reportCmd 처리
sendModuleCommand(Bundle)는 이 커밋에서 result=false와 -1을 반환한다. 다른 Agent의 Bundle method 분기를 AMRAgent에 그대로 적용하면 잘못된 설명이다. 실제 이동·매핑은 typed op* AIDL 메서드다.
근거: R/AMRAgent.java:300–325, :328 이후, R/AMRCmdDispatcher.java, R/RecvThread.java.
스레드·상태·복구 경계
서비스 시작에서 socket과 RecvThread를 준비하고 dispatcher HandlerThread를 생성한다. 명령을 예약하는 스레드, 수신 thread, Binder callback은 역할이 다르다. 지연 메시지를 넣었다는 사실만으로 상대 AMR이 실행을 완료했다고 볼 수 없다.
RecvThread는 수신 종류에 따라 map·position·battery·docking·sensor 등의 상태를 구성한다. timeout 보고와 dispatcher의 재조회·monitor 처리가 별도로 있다. 기기 연결·재연결·누락 report가 DeviceAgent의 현재 상태와 맞는지는 실제 로그가 필요하다. AMR 하위 firmware·모터 제어 루프는 이 Android 소스 바깥이다.
변경 시 함께 볼 곳
새 AMR 기능은 AIDL 선언, AMRAgent typed 메서드, command codec, RecvThread decoder, callback Bundle, DeviceAgent 소비부를 함께 확인해야 한다. 장치 프로토콜과 앱 상태 계약 양쪽이 바뀌는 경계다.
MCUAgent: 별도 serial 제어 앱
기준 루트 M/는 apps/MCUAgent/java/com/sk/airbot/mcuagent/다. 이 모듈은 IMCUControl Service와 Manager·Protocol·Comm을 가진다. 단, DeviceAgent의 connectServices에서는 MCUAgent bind가 주석이고 현재 주요 MCU 접근은 DeviceAgent의 vendor HAL 경로다.
| 구성 | 구현 |
|---|---|
| MCUAgent | IMCUControl Stub의 sendModuleCommand → Manager.executeMethod; onBind에서 Stub 반환 |
| Manager | method/action 해석, 팬 등 기능·Protocol 상태 접근, 주기 Handler |
| comm/Comm | SerialPort stream, 송신 packet 작성, 수신 frame 반영 |
| Protocol | MCU 송수신 packet과 현재 값 상태 |
근거: M/MCUAgent.java:58–94, :136–153, M/Manager.java:29–64, :75–150, M/comm/Comm.java:24–78, :109–191.
호출·수신 흐름
IMCUControl → Manager.executeMethod → Protocol로 제어 값을 설정하고, Comm thread가 makeSendPackeck() 결과를 stream에 쓴다. 읽은 frame은 setMasterReceiveCurrent()로 반영한다. Manager는 Handler 주기로 Comm을 구동한다.
MCUAgent의 private executeMethod에는 시험 callback 코드가 있지만, serial 수신 전체가 외부 IMCUControlCallback으로 연결된다고 확인하지 않았다. 실제 fan 제어 완료 증거는 수신 frame·장치 상태까지 확인해야 한다.
두 MCU 경로의 관계
- 이 모듈: MCUAgent → SerialPort.
- DeviceAgent 실제 연결: MCUComm·Protocol → IDeviceManager HAL callback.
같은 제품 기능을 설명한다고 두 경로를 직렬로 연결하지 않는다. libs/serial_port 존재만으로 DeviceAgent가 반드시 MCUAgent를 통해 제어한다고 추정해서도 안 된다.
Open Questions
AMR socket 실제 연결, MCU serial 장치와 ABI, firmware version과 protocol 일치, timeout 이후 복구, callback 누락·재시작 정합성은 미검증이다. 이 문서에서는 transport 연결선을 확인했으며 물리 제어 성공을 주장하지 않는다.
확대 구조도와 연결별 근거
Connections
전체 목차 · 앱 구성 · DeviceAgent 내부 · IPC · 실행 흐름 · 플랫폼·빌드 · 근거·확인 범위