28.3.1.2. 공통 uORB 데이터 구독(Subscription) 및 캐싱(Caching) 멤버 구조
객체 지향 설계에서 부모 클래스의 미덕은 ’공유 가능한 국부 재산’을 하위 상속자들에게 얼마나 깔끔하게 물려주느냐에 달려 있다.
FlightTask 기저 클래스는 자식들이 공통적으로 매번 긁어와야 하는 미들웨어(uORB) 통신 채널과 그 데이터를 담아둘 캐시(Cache) 메모리를 자신의 protected 멤버 영역에 거대한 데이터 구조체 인프라로 미리 세팅해 둔다.
1. uORB 구독자(Subscription) 계층의 은닉
미세한 드론 제어를 수행하려면 고도, GPS, 배터리, 조종기 스틱, 비전 센서 등 수십 가지의 센서 토픽 정보가 필요하다. 만약 새로 만든 자식 비행 모드 클래스마다 이 토픽들을 일일이 orb_subscribe()로 열고 닫는다면 코드는 수백 줄의 보일러플레이트(Boilerplate)로 도배될 것이다.
- 공통
_sub_멤버 변수:
FlightTask.hpp헤더 파일을 열어보면, 클래스 상단에uORB::Subscription객체들이 십여 개 이상 선언되어 있는 것을 볼 수 있다.
(예:_sub_vehicle_local_position,_sub_vehicle_attitude,_sub_manual_control_switches등) - 구독 데몬의 중앙화:
부모 클래스의 생성자(Constructor)와updateInitialize()함수가 이 수많은 구독 객체들의 생명주기와 데이터 폴링(Polling)을 책임지고 중앙 다중화기(Multiplexer)처럼 처리해 준다. 자식 클래스는 OS 레벨의 메시지 큐(Message Queue)나 파일 디스크립터(File Descriptor)를 전혀 건드릴 필요가 없다.
2. 정제된 상태 캐싱(Caching) 구조체 변수들
uORB 레이어에서 갓 올라온 날것(Raw)의 메시지들은 Timestamp나 찌꺼기 플래그들이 섞여 있어 순수 수학 연산에 곧바로 대입하기엔 지저분하다. FlightTask는 이 날것의 데이터를 가져와서, 오직 미적분 수식에 즉각 대입할 수 있는 순수한 수학적 벡터(Eigen Vector)나 실수형 변수로 다듬어서 캐싱(Caching) 구조체 안에 이쁘게 담아놓는다.
// FlightTask.hpp의 protected 멤버 변수 발췌 예시
protected:
matrix::Vector3f _position {NAN, NAN, NAN}; // 현재 측위된 3차원 절대 좌표
matrix::Vector3f _velocity {NAN, NAN, NAN}; // 현재 x, y, z축 속도
float _yaw {NAN}; // 현재 기체의 헤딩(Heading) 각도
float _deltatime {0.0f}; // 루프 간의 정밀 dt 변수
_position,_velocity,_yaw트리오:
어떤 비행 모드든 (심지어 수동 모드조차도 제어 안정화를 위해) 현재 기체가 어디 떠있고 어느 방향으로 날아가는지는 필수적으로 알아야 한다. 이 가장 중요한 삼대장 상태 변수들은 EKF2 위치 추정기가 방출한 복잡한 쿼터니언(Quaternion)과 로컬 프레임 데이터를 부모 클래스가 미리 해석하여, 직관적인 3차원 유클리드 벡터(Eigen::Vector3f) 형태로 가공해protected영역에 상시 대령해 놓는다.- NaN (Not a Number) 처리의 철학:
변수들의 초기값을 보면0.0f가 아니라NAN으로 채워져 있는 것을 엿볼 수 있다. 만약 센서가 고장 나서 위치 토픽의 업데이트가 끊기면, 부모 루틴은 이 변수를 즉시NAN으로 덮어버린다. 자식 클래스의 PID 연산식에NAN값이 흘러 들어가면 수식 전체가 즉시NAN붕괴를 일으키며 연산이 중단되는데, 이는 잘못된 0.0f 데이터(원점)를 믿고 오작동하는 것보다 “모르겠으면 차라리 에러를 뿜고 멈춰라(Fail-fast)“라는 드론 제어 공학의 안전 철학이 변수 초기화 단계에서부터 묻어나는 대목이다.
이처럼 강력한 공통 캐싱 멤버 구조 덕택에, 대학원생 프로그래머는 헤더 파일에 uORB 인클루드 한 줄 추가할 필요 없이, 오직 _position(2) - _target_z 같은 직관적이고 순수한 제어 수식 코딩만으로 강력한 비행 궤적 알고리즘을 완성할 수 있는 엄청난 생산성의 축복을 누리게 된다.