19.6. 다중 인스턴스(Multi-instance) 발행 및 구독 심화
이전 단원들까지 우리가 피와 땀으로 구축했던 퍼블리셔와 구독자 통신 아키텍처는 오직 ’단일(Single) 인스턴스’라는 매우 제한적이고 순진한 전제 조건하에 설계되었다. 즉, sensor_test_data라는 이름의 우체통(Topic)이 마을에 단 1개만 존재하고, 1명의 우체부(Publisher)가 그곳에 편지를 넣으면, 1명의 수신자(Subscriber)가 편지를 꺼내 가는 가장 이상적이고 평화로운 1:1 또는 1:N의 데이터 통신 모델이었다.
하지만 산업용 초정밀 드론이나 상업용 픽스호크 비행 제어기(FC)의 하드웨어 현실 세계는 그렇게 낭만적이지 않다. 기체의 치명적인 비행 생존성(Redundancy)을 확보하기 위해, 마더보드에는 똑같은 구실을 하는 센서들이 다중으로 중복 장착된다.
기판 위에 SPI 통신을 하는 초정밀 Invensense 가속도계 센서, I2C로 통신하는 외부 지자기 센서 콤보 가속도계 센서, 그리고 예비용 Bosch 가속도계 센서까지 물리적으로 완전히 똑같은 종류의 데이터를 생산하는 센서 칩스터 데몬이 동시에 3개 이상 병렬로 돌아가며 텔레메트리를 미친 듯이 쏟아내는 상황이 발생한다.
이때 이 3개의 서로 다른 C++ 퍼블리셔 데몬들이 멍청하게 vehicle_acceleration이라는 단 1개의 공용 VFS 우체통(Topic)에 동시에 다 같이 몰려가 orb_publish 데이터 덮어쓰기(memcpy) 융단폭격을 가한다면 시스템은 어떻게 될까?
최고 성능의 SPI 센서 데이터가 기록되자마자 1ms도 안 되어 최하급 예비 센서 데이터가 그 위를 덮어 써버리는 최악의 데이터 오염 레이스 컨디션(Race Condition)이 터지고, 구독자 모듈은 이 뒤죽박죽 섞인 끔찍한 센서 노이즈 쓰레기를 읽어 들여 기체는 이륙 직후 그 자리에서 전복되어 추락하고 말 것이다.
1. ORB Multi-instance(다중 인스턴스): 물리적 센서의 완벽한 논리적 분할
이러한 다중 중복 센서 생태계의 파괴적인 충돌을 커널 레벨에서 우아하게 통제하기 위해, PX4 uORB 미들웨어는 **‘다중 인스턴스(Multi-instance)’**라는 궁극의 네임스페이스 분할 아키텍처를 도입했다.
이 개념은 쉽게 말해 vehicle_acceleration이라는 토픽의 이름을 바꾸거나 메시지 구조체를 3개로 복제하여 하드코딩하는 멍청한 짓을 하지 않는다. 토픽의 고유 ID와 구조체 스키마는 전역적으로 단 1개로 완벽히 유지하되, 커널 VFS가 내부적으로 이 토픽 밑에 instance 0, instance 1, instance 2라는 **완전히 독립된 번호표가 붙은 물리적 서브 파이프라인(Sub-pipeline 링 버퍼)**들을 동적으로 무한정 분기가지(Branch) 쳐서 생성해 내는 기술이다.
- 제1 메인 SPI 가속도계 스레드는
vehicle_acceleration의 Instance 0 파이프라인을 커널로부터 할당받아 독점적이고 안전하게 데이터를 때려 넣는다. - 제2 보조 I2C 가속도계 스레드는 Instance 1 파이프라인을 얻어내어 간섭 없이 퍼블리싱한다.
- 하단에서 데이터를 받아먹어야 하는 항법 제어 EKF 모듈 데몬은 자기가 원하는 입맛에 맞춰 “나는 최고급 데이터인 Instance 0만 구독해서 먹겠다“라고 명시적으로 핀셋 구독(Subscribe)을 때리거나, “나는 불안하니까 0번, 1번, 2번 파이프를 전부 독립적으로 구독해서 소프트웨어적으로 센서 보팅(Voting) 융합을 하겠다“는 무결점 통제권을 확보할 수 있게 된다.
이 거대하고 정교한 다중 생태계를 구축하기 위해, 이어지는 19.6.1 단원부터 퍼블리셔 데몬이 어떻게 이 인스턴스 번호표를 커널로부터 실시간 할당받아 쥐어짜 내는지(orb_advertise_multi), 그리고 구독자는 어떻게 이 쪼개진 N개의 파이프라인을 식별하여(orb_group_count) 타겟을 찾아 추적 구독하는지에 대한 치열한 미들웨어 하단 마이크로 컨트롤 로직을 해부할 것이다.