21.7.1.2. 다중 인스턴스 센서 데이터의 선택적 구독
현대의 픽스호크 비행 제어기 보드(Pixhawk 4, 5X, 6X 등)들은 하드웨어의 신뢰성을 극대화하기 위해 똑같은 종류의 자이로/가속도 센서 칩셋(IMU)을 물리적으로 2개, 혹은 3개씩(Triple Redundancy) 달아두는 경우가 많다.
비행 중에 1번 센서 칩이 타버리거나 데이터가 얼어붙더라도, 2번과 3번 센서가 살아있다면 즉각적으로 스위칭하여 드론을 무사히 착륙시키기 위함이다.
그렇다면 uORB 게시판의 입장에서 생각해 보자. sensor_gyro라는 토픽 이름은 오직 하나인데, 물리적으로 구별되는 3개의 자이로 센서 드라이버 모듈이 동시에 데이터를 뿜어내고 있다면 데이터는 과연 어떻게 구별되어 배달될까?
1. 인스턴스(Instance): 토픽의 ‘호수 번호’
이 다중 센서 입력을 처리하기 위해 PX4의 uORB 시스템은 동일한 토픽 이름 밑에 ‘인스턴스(Instance)’ 라는 호수(Index) 개념을 도입했다.
sensor_gyro(Instance 0): 첫 번째 IMU 칩셋(예: ICM-20689)에서 올라오는 데이터sensor_gyro(Instance 1): 두 번째 IMU 칩셋(예: BMI055)에서 올라오는 데이터sensor_gyro(Instance 2): 세 번째 IMU 칩셋(예: ISM330DLC)에서 올라오는 데이터
센서 드라이버 모듈이 처음 uORB에 데이터를 출판(Advertise)할 때, 커널은 이들에게 0번, 1번, 2번 등 고유한 인스턴스 번호를 발급해 준다. 이제 같은 sensor_gyro 전단지라도 우측 상단에 작게 ‘0번 출판사 발행’, ‘1번 출판사 발행’ 이라는 꼬리표가 붙게 된 것이다.
2. 다중 인스턴스 래퍼 클래스: uORB::SubscriptionMultiArray
구독자(제어 모듈) 입장에서 이 3쌍둥이 센서를 모두 읽어와 모니터링해야(비교 대조) 한다면, 똑같은 Subscription 객체를 하드코딩으로 3개나 만들어야 할까?
PX4는 이를 위해 배열 형태의 다중 인스턴스 전용 래퍼 클래스를 제공한다.
#include <uORB/SubscriptionMultiArray.hpp>
class SensorVoter {
private:
// 최대 3개의 자이로 센서를 동시에 추적하는 멀티 구독자 객체 (인덱스 자동 관리)
uORB::SubscriptionMultiArray<sensor_gyro_s, 3> _gyro_subs{ORB_ID(sensor_gyro)};
};
이 객체를 사용하면 Run() 함수 안에서 가볍게 for 문을 돌리며 살아있는 센서들의 데이터를 우아하게 수집할 수 있다.
void SensorVoter::Run() {
// 3개의 센서를 훑으며, 각각 업데이트된 데이터가 있는지 확인
for (int i = 0; i < 3; i++) {
sensor_gyro_s gyro_data;
if (_gyro_subs[i].update(&gyro_data)) {
// i 번째 인스턴스(센서)에서 새로 올라온 값
printf("Sensor %d Z-axis: %f\n", i, gyro_data.z);
}
}
}
하지만 만약 당신이 3개의 센서를 모두 검사하는 투표(Voter) 모듈의 개발자가 아니라, 누군가 이미 최적의 센서라고 골라놓은 특정 번호(예: “지금은 1번 센서가 최고존엄이야!”)의 데이터만 집중적으로 파헤치고 싶은 거라면 어떻게 할까?
수많은 토픽 묶음 속에서 어떻게 정확히 “1번 센서 데이터만 내게 줘!” 라고 C++ 래퍼를 튜닝할 수 있는지, 그 단일 인스턴스 필터링 팁을 다음 장(21.7.1.2.1)에서 정리해 보자.