← Work

Case study

런타임에 꽂히고 빠지는 디바이스 — Component Manager 설계

2024.02 — 2025.12 · 소형 무인 지상 차량(SUGV) Component Manager 개발

요약

SUGV 플랫폼은 운용 중에 센서·디바이스가 연결되고 해제된다(hot-plug). ROS2 런타임에서 이를 안전하게 처리하기 위해 Dynamic Device Pool 구조의 컴포넌트 매니저를 설계·개발했다. 이기종 디바이스의 초기화·종료 절차를 표준화하고, Generic Template 인터페이스로 디바이스별 중복 코드를 23% 줄였다.

Component Manager 구조

문제

설계 결정

1. Pool 단위 관리 — Dynamic Device Pool

디바이스를 개별 객체로 흩어 관리하지 않고 슬롯을 가진 Pool로 관리한다. 연결 이벤트가 오면 빈 슬롯에 등록하고 lifecycle을 시작, 해제 이벤트가 오면 종료 절차를 밟고 슬롯을 반납한다. 시스템 관점에서는 “지금 어떤 디바이스가 어떤 상태로 몇 개 붙어 있나”가 Pool 하나로 관측된다.

2. Lifecycle 추상화 — 이기종을 하나의 절차로

디바이스 종류마다 다른 초기화·종료를 공통 lifecycle(등록 → 초기화 → 활성 → 종료 → 해제)로 추상화했다. 새 디바이스는 lifecycle의 각 단계만 구현하면 Pool·이벤트·복구 로직을 그대로 얻는다.

3. Generic Template 인터페이스 — 중복 코드 23% 감소

디바이스별 서비스 인터페이스가 타입만 다르고 구조가 같았다. C++ Generic Template 기반으로 인터페이스 구조를 설계해 디바이스별 중복 코드를 23% 줄였다. 새 디바이스를 붙일 때마다 반복되는 코드를 줄이는 게 목적이었다.

4. Polling → First-connection Cache

초기 구현은 디바이스 상태를 주기적으로 폴링했다. 안정 상태에서는 같은 응답을 반복해서 받을 뿐인데 호출 비용은 계속 나간다. 첫 연결 시점에 인터페이스 정보를 캐시하고, 이후에는 변경 이벤트가 있을 때만 갱신하는 방식으로 바꿔 안정 상태의 반복 호출을 제거했다.

트레이드오프: 캐시가 실제 상태와 어긋날 위험 ↔ 폴링 부하. 연결·해제가 이벤트로 이미 관측되는 구조라서, 이벤트를 신뢰하고 캐시를 택했다.

5. Timeout 기반 Recovery

디바이스 응답이 timeout을 넘으면 장애로 판정하고 recovery/reconnect 절차를 밟는다. 장애 디바이스는 해당 슬롯 안에서 격리·복구되고, 나머지 Pool은 영향받지 않는다.

결과

Pool이 디바이스 수의 변화를, lifecycle이 종류의 변화를, template이 타입의 변화를 각각 흡수하는 구조라서, 디바이스가 늘어나도 매니저 코드는 바뀌지 않는다.