28.3.2.2. FlightTaskAuto 상속 트리의 자율 비행 알고리즘
수동 비행 트리의 최상위 관리자가 조종기의 스틱을 바라보고 있다면, 자율 비행 제어의 중간 관리자인 2세대 클래스 FlightTaskAuto는 철저하게 조종사를 무시하고 오직 QGroundControl에서 업로드된 웨이포인트(Waypoint) 미션과 네비게이터(Navigator) 모듈만을 쳐다보며 작동한다.
자동 복귀(RTL), 미션 비행(Mission), 오프보드 제어(Offboard API) 등 인간의 개입 없이 드론이 자체적으로 하늘의 점들을 찍어나가야 하는 모든 모드들은 이 거대한 FlightTaskAuto 상속 트리 아래에 뿌리를 내리고 있다.
1. 조종기 스틱의 완벽한 배제 (Stick Override)
이 클래스로 제어권이 넘어오는 순간, 부모 클래스(FlightTask)가 캐싱해 두었던 조종기 스틱 변수(_sticks)는 철저하게 무시당한다(물론, 긴급 디스암(Disarm)이나 모드 강제 전환 스위치는 예외적으로 FMM 윗단 구조에서 살아남는다).
대신 FlightTaskAuto 트리는 ’현재 위치에서 목적지 좌표로 가기 위해 모터를 몇 퍼센트로 돌려야 하는가?’라는 오직 위치 기반의 유도(Guidance) 수학에만 100% 리소스를 쏟아붓는다. 철저한 시스템적 단절을 통해, 조종사가 실수로 조종기를 쳐서 자율 비행 궤적이 틀어지는 어처구니없는 참사를 아키텍처 레벨에서 차단한다.
2. 네비게이터(Navigator) 데몬과의 통신 프로토콜
FlightTaskAuto 계열 클래스들의 척추 역할을 하는 데이터는 흔히 ’미션 아이템’이라 불리는 uORB 토픽, 즉 position_setpoint_triplet이다.
상단 통합 관제 모듈인 Navigator 데몬은 드론 플라이트 컨트롤러(FC)의 SD 카드에 저장된 미션 라인들을 읽어들여 하나씩 FMM 쪽으로 내려주는데, 흥미롭게도 단일 좌표가 아니라 항상 ‘트리플릿(Triplet: 세 개의 세트)’ 포맷으로 뿌려준다.
previous: 드론이 방금 지나쳐 온 과거의 웨이포인트current: 지금 당장 드론이 필사적으로 쫓아가야 할 현재의 목표 웨이포인트next:current를 찍고 난 직후 부드럽게 턴을 이어나가기 위해 미리 알려주는 다음 번 목표 웨이포인트
FlightTaskAuto 기저 클래스는 updateInitialize() 단계에서 이 트리플릿 uORB 토픽을 집어삼켜 전처리 버퍼에 캐싱한다. 왜 굳이 세 개를 한꺼번에 주는 것일까? 이는 3세대 자식 클래스들이 구사하는 비행 유도(Guidance) 알고리즘의 매끄러움(Smoothness)을 극대화하기 위해서다.
3. 유도 알고리즘(Guidance Logic)을 향한 산파 역할
FlightTaskAuto 자체는 구체적인 곡선 궤적을 스스로 그리지 않는다. 대신 3세대 자식 클래스들(예: 선형 추종 FlightTaskAutoLine, 매끄러운 커브 FlightTaskAutoMapper 등)이 수학 공식을 미친 듯이 전개할 수 있도록, 위성 지구 좌표(Lat/Lon WGS84)로 들어온 트리플릿 웨이포인트들을 EKF2 기준의 **직교 로컬 좌표계(NED: North-East-Down 미터 단위)**로 미리 투영 변환(Projection) 시켜주는 귀찮은 산파 역할을 도맡는다.
// FlightTaskAuto의 내부 트리플릿 치환 전처리 의사(Pseudo) 코드
void FlightTaskAuto::_updateInternalWaypoints() {
// 1. 위경도 글로벌 좌표를 로컬 직교 X, Y 미터 좌표로 맵핑 변환
_target_prev = _mapGlobalToLocal(_triplet_msg.previous.lat, _triplet_msg.previous.lon);
_target_curr = _mapGlobalToLocal(_triplet_msg.current.lat, _triplet_msg.current.lon);
_target_next = _mapGlobalToLocal(_triplet_msg.next.lat, _triplet_msg.next.lon);
// 2. 고도(Altitude) 기준점의 표준화치환
// (이후 3세대 클래스들은 이 _target_curr 벡터만 보고 미적분을 돌린다)
}
이러한 분업 덕분에 3세대의 자식 클래스 설계자(대학원생이나 새로운 알고리즘 연구원)는 지구가 둥글기 때문에 발생하는 곡률 보정이나 구면 삼각법(Spherical Trigonometry) 따위는 1도 알 필요 없이, 오직 X, Y, Z로 잘 썰어져 나온 유클리드 기하학 도마 위에서 자신의 L1 유도 알고리즘(L1 Guidance Algorithm)이나 베지어 곡선(Bézier Curve) 추종 로직을 자유롭게 코딩할 수 있게 된다.