659.4 TF2 라이브러리의 아키텍처 개요

1. TF2 아키텍처의 설계 목표

TF2(Transform Library 2)의 아키텍처는 다음과 같은 설계 목표를 달성하기 위해 구성되었다.

  1. 분산 발행-구독 모델: 좌표 변환 정보를 중앙 집중식 서버 없이 분산 방식으로 관리한다.
  2. 시간 인식(Time-Aware) 변환: 모든 변환에 타임스탬프를 부착하여 시간대별 변환 이력을 관리한다.
  3. 미들웨어 독립성: 핵심 변환 로직을 ROS2 미들웨어에 대한 의존성 없이 구현하여, 순수 C++ 환경에서도 독립적으로 사용할 수 있도록 한다.
  4. 확장 가능한 타입 변환: 사용자 정의 데이터 타입에 대한 좌표 변환을 플러그인 방식으로 추가할 수 있도록 한다.
  5. 스레드 안전성: 멀티스레드 환경에서의 동시 접근을 안전하게 처리한다.

2. 계층적 아키텍처 구조

TF2는 명확한 계층 구조(layered architecture)를 따르며, 하위 계층에서 상위 계층으로의 의존성만 허용된다.

2.1 계층 1: tf2 코어 라이브러리

최하위 계층인 tf2 코어 라이브러리는 좌표 변환의 핵심 로직을 구현한다. 이 계층은 ROS2에 대한 의존성이 전혀 없으며, 순수 C++ 라이브러리로 구성된다.

tf2 코어의 핵심 구성 요소는 다음과 같다.

구성 요소역할
BufferCore변환 데이터의 저장, 조회, 보간을 담당하는 핵심 클래스
TimeCache단일 프레임 쌍에 대한 시간대별 변환 이력을 관리
TransformStorage개별 변환 데이터(타임스탬프, 쿼터니언, 병진 벡터)의 저장 구조체

BufferCore는 내부적으로 변환 트리를 그래프 자료 구조로 관리하며, 임의의 두 프레임 간 변환을 요청받으면 트리 탐색을 통해 최적 경로를 찾고, 해당 경로 상의 변환들을 합성하여 결과를 반환한다.

2.2 계층 2: tf2_ros ROS2 통합 계층

tf2_rostf2 코어 라이브러리를 ROS2 통신 인프라와 연결하는 중간 계층이다. ROS2의 토픽 발행-구독 메커니즘을 통해 변환 데이터의 분산 관리를 실현한다.

tf2_ros의 주요 구성 요소는 다음과 같다.

구성 요소역할
TransformBroadcaster동적 변환을 /tf 토픽으로 발행
StaticTransformBroadcaster정적 변환을 /tf_static 토픽으로 발행
TransformListener/tf/tf_static 토픽을 구독하여 BufferCore에 변환 데이터를 저장
BufferBufferCore를 상속하고, ROS2 노드와의 인터페이스를 제공
MessageFilter수신된 메시지의 좌표 변환 가용성을 확인한 후 콜백을 호출

2.3 계층 3: 타입 변환 패키지

최상위 계층에는 특정 메시지 타입이나 외부 라이브러리의 데이터 타입에 대한 좌표 변환 기능을 제공하는 패키지들이 위치한다.

패키지역할
tf2_geometry_msgsgeometry_msgs 메시지 타입의 좌표 변환
tf2_sensor_msgssensor_msgs::PointCloud2의 좌표 변환
tf2_eigenEigen 라이브러리 타입과의 변환 인터페이스
tf2_kdlKDL(Kinematics and Dynamics Library) 타입과의 변환 인터페이스
tf2_bulletBullet Physics 라이브러리 타입과의 변환 인터페이스

3. 데이터 흐름 아키텍처

TF2의 데이터 흐름은 발행(publishing)과 조회(lookup)의 두 가지 경로로 구분된다.

3.1 발행 경로 (Publishing Path)

변환 데이터의 발행 경로는 다음과 같다.

  1. 변환 생성: 센서 드라이버, 오도메트리 노드, 위치 추정 노드 등이 자신이 담당하는 좌표 프레임 간의 변환을 계산한다.
  2. 메시지 구성: 계산된 변환 데이터를 geometry_msgs/TransformStamped 메시지로 구성한다. 이 메시지에는 타임스탬프, 부모 프레임 ID, 자식 프레임 ID, 변환(병진 + 회전)이 포함된다.
  3. 토픽 발행: TransformBroadcaster(동적 변환) 또는 StaticTransformBroadcaster(정적 변환)를 통해 /tf 또는 /tf_static 토픽으로 메시지를 발행한다.

3.2 수신 및 저장 경로 (Reception and Storage Path)

변환 데이터의 수신 경로는 다음과 같다.

  1. 토픽 구독: TransformListener/tf/tf_static 토픽을 구독한다.
  2. 데이터 저장: 수신된 변환 데이터가 BufferCore의 내부 자료 구조에 저장된다. 동적 변환은 시간대별로 TimeCache에 저장되며, 정적 변환은 StaticCache에 저장된다.
  3. 트리 갱신: 새로운 프레임 쌍이 발견되면 변환 트리에 해당 프레임 노드와 엣지가 추가된다.

3.3 조회 경로 (Lookup Path)

변환 데이터의 조회 경로는 다음과 같다.

  1. 조회 요청: 애플리케이션 코드가 Buffer::lookupTransform(target_frame, source_frame, time)을 호출한다.
  2. 경로 탐색: BufferCore가 변환 트리에서 source_frame에서 target_frame까지의 경로를 탐색한다.
  3. 시간 보간: 요청된 시간에 정확히 일치하는 변환이 없는 경우, 전후 시간의 변환 데이터를 이용하여 보간(interpolation)을 수행한다. 병진 성분은 선형 보간(LERP), 회전 성분은 구면 선형 보간(SLERP)이 적용된다.
  4. 변환 합성: 경로 상의 모든 변환을 순차적으로 합성(composition)하여 최종 변환을 계산한다.
  5. 결과 반환: 계산된 변환을 geometry_msgs/TransformStamped 형태로 반환한다.

4. BufferCore의 내부 자료 구조

BufferCore는 변환 트리를 효율적으로 관리하기 위해 다음과 같은 내부 자료 구조를 사용한다.

4.1 프레임 매핑 테이블

각 프레임 이름(문자열)에 대해 고유한 정수 ID를 할당하는 매핑 테이블을 유지한다. 이를 통해 문자열 비교 대신 정수 비교를 사용하여 프레임 탐색 성능을 향상시킨다.

4.2 시간 캐시 (TimeCache)

각 프레임 쌍에 대해 하나의 TimeCache 인스턴스가 할당된다. TimeCache는 시간순으로 정렬된 변환 데이터의 이중 연결 리스트(doubly linked list)를 관리하며, 지정된 캐시 기간(cache duration)보다 오래된 데이터를 자동으로 제거한다. 기본 캐시 기간은 10초이다.

4.3 그래프 구조

변환 트리는 방향성 비순환 그래프(DAG, Directed Acyclic Graph)로 관리된다. 각 프레임은 그래프의 노드이며, 프레임 간의 변환은 엣지에 해당한다. 트리 제약 조건에 의해 각 노드는 최대 하나의 부모 노드만 가질 수 있으므로, 임의의 두 노드 간 경로는 유일하게 결정된다.

5. 스레드 안전성 설계

TF2는 멀티스레드 환경에서의 동시 접근을 지원하기 위해 내부적으로 뮤텍스(mutex) 기반의 동기화 메커니즘을 사용한다. BufferCore의 읽기 연산(조회)과 쓰기 연산(저장)은 읽기-쓰기 잠금(read-write lock)을 통해 동기화되며, 다수의 스레드가 동시에 변환을 조회하는 것은 허용되지만, 쓰기 연산 중에는 배타적 접근이 보장된다.

tf2_ros::Buffer 클래스는 BufferCore의 스레드 안전성을 상속하며, 추가적으로 ROS2의 콜백 그룹(callback group)과 Executor를 통한 콜백 스케줄링과의 호환성을 제공한다.

6. 확장성 설계: 타입 변환 프레임워크

TF2는 C++ 템플릿과 함수 오버로딩을 활용하여 확장 가능한 타입 변환 프레임워크를 제공한다. 새로운 데이터 타입에 대한 좌표 변환을 추가하려면, 해당 타입에 대해 tf2::doTransform() 함수를 특수화(specialization)하면 된다.

namespace tf2 {
template <>
void doTransform(
    const MyCustomType& data_in,
    MyCustomType& data_out,
    const geometry_msgs::msg::TransformStamped& transform);
}

이러한 확장 메커니즘을 통해, 사용자 정의 메시지 타입이나 외부 라이브러리의 데이터 타입에 대해서도 TF2의 좌표 변환 인프라를 활용할 수 있다.


참고 문헌 및 출처:

  • Foote, T., “tf: The transform library,” 2013 IEEE Conference on Technologies for Practical Robot Applications (TePRA), pp. 1-6, 2013.
  • Open Robotics, “tf2 — ROS 2 Documentation,” ROS 2 Jazzy Jalisco, 2024. https://docs.ros.org/en/jazzy/Concepts/About-Tf2.html
  • Open Robotics, “tf2 API Reference,” ROS 2 Jazzy Jalisco, 2024.
  • Open Robotics, “tf2_ros API Reference,” ROS 2 Jazzy Jalisco, 2024.