# tf2 관련 오류 사례 및 해결책

#### tf2 버퍼(Time Cache) 누락으로 인한 Transform Lookup 실패

ROS2 tf2는 특정 시점의 변환(transform)을 저장해 두는 버퍼 구조를 통해, 과거 혹은 미래 시점의 변환을 요청할 수 있도록 설계되었다. 하지만 변환을 방송(broadcast)해 주는 노드와 변환을 사용하는 노드의 시간 동기화가 제대로 이뤄지지 않으면, 특정 시점에 해당하는 변환이 tf2 버퍼 안에 존재하지 않아 Lookup이 실패할 수 있다. 이를 대표적으로 “Lookup would require extrapolation into the past/future”와 같은 오류 메시지로 확인할 수 있다.

* **원인**
  * 메시지가 노드에 늦게 도착해서, 변환이 필요한 시점의 데이터가 이미 버퍼에서 제거된 경우
  * 발행 주기와 구독 주기의 불일치로 tf2 버퍼가 제대로 쌓이지 않는 경우
  * 시스템 시간(clock) 설정 오류 또는 시뮬레이터(예: Gazebo) 시간 동기 미흡
* **해결책**
  1. ROS2 파라미터 조정
     * tf2에 저장되는 변환의 최대 시간 범위(cache\_duration)와 같은 파라미터를 확인한다.
     * rclcpp 노드에서 ’use\_sim\_time’ 파라미터 활성화 여부를 점검한다. 시뮬레이터를 사용할 때에는 반드시 시뮬레이터의 시간에 동기화해야 한다.
  2. 타임스탬프 정렬
     * 메시지를 발행하는 쪽에서 정확한 $t\_{stamp}$를 지정했는지 점검한다.
     * 트랜스폼 발행 주기가 실제 사용 측에서 요구하는 해상도와 맞는지 확인한다.
  3. 시스템 시간 점검
     * `chrony` 또는 `ntpd` 등을 이용해 메인 컴퓨터와 서브 컴퓨터 간 시간 동기화를 확인한다.
     * 시뮬레이터와 호스트 컴퓨터가 동일한 clock을 사용 중인지 점검한다.

#### Parent-Child 프레임 충돌

tf2에서는 기본적으로 한 프레임이 다른 프레임을 부모(parent) 프레임으로 참조하도록 트리 구조를 만든다. 그러나 일부 로봇 환경에서는 동일한 프레임 이름을 여러 노드에서 중복 사용하거나, 서로 다른 부모 프레임이 한 자식 프레임을 동시에 가리키도록 설정되어 충돌이 발생하기도 한다.

* **원인**
  * URDF(Xacro 포함)에서 잘못된 링크 이름으로 인해 tf2 트리에 중복 프레임 생성
  * launch 파일에서 동일한 프레임에 서로 다른 부모를 할당
  * tf2 브로드캐스터 여러 개가 중복된 변환을 동시에 발행
* **해결책**
  1. 프레임 명칭 일관성 유지
     * URDF나 SDF에서 사용 중인 링크 이름, 조인트 이름을 점검하고, launch 파일에서 각각 대응하는 frame\_id가 일치하는지 확인한다.
     * namespace를 적극 활용하거나, 프레임 이름 앞에 로봇 이름 등의 접두사(prefix)를 붙여 식별 가능하게 만든다.
  2. 협의된 트리 구조 수립
     * 로봇 전체 tf2 트리 구조를 mermaid 등을 이용해 시각화하여, 최종 구조를 합의한 뒤 코드에 반영하는 편이 좋다.

{% @mermaid/diagram content="graph LR;
world --> base\_link;
base\_link --> camera\_link;
base\_link --> lidar\_link;
..." %}

* 예를 들어, 위처럼 월드 좌표계(world) 아래에 로봇 기본 프레임(base\_link), 그리고 base\_link 아래에 센서들을 배치하는 규칙으로 일관되게 운영한다.

1. 중복 브로드캐스터 조정
   * 똑같은 변환을 발행해도 상관없는 경우(예: TF Static Transform Publisher)라면, 중복 발행 대신 하나만 유지한다.
   * 다른 패키지에서 이미 동일 프레임 쌍 변환을 발행 중인지, 또는 launch 단계에서 중복 로드가 일어나고 있지는 않은지 점검한다.

#### Static Transform Publisher의 미사용 또는 누락

tf2\_static\_transform\_broadcaster를 사용하면 변하지 않는 변환(예: 카메라 프레임과 로봇 본체 프레임의 고정 오프셋)을 간편히 등록할 수 있다. 하지만 이를 누락하면 별도의 tf2 브로드캐스터 노드에서 해당 변환 정보를 지속적으로 발행하지 않는 이상, 시스템 전체 tf2 트리에 필요한 정적 변환이 없는 상태가 된다.

**원인**:

* launch 파일에서 static\_transform\_publisher 노드를 등록하지 않음
* 여러 개의 정적 변환을 추가해야 하는데, 일부만 broadcast하도록 설정
* URDF나 SDF 모델 상에는 기재되어 있으나, 실제 tf2 노드로는 발행하지 않음

**해결책**:

정적 변환 발행 확인:

* 실제 실행 중에 아래와 같이 static\_transform\_publisher 실행 여부 및 파라미터를 확인한다.
* 쉘에서 다음 명령을 통해 정적 변환이 정상적으로 발행되는지 점검한다.

```
ros2 run tf2_ros static_transform_publisher 0 0 0 0 0 0 base_link camera_link
```

정적 변환 합치기:

* 서로 다른 여러 정적 변환 발행 과정을 하나의 노드로 모을 수 있다면, launch 파일에서 각각 나눠 실행하는 대신 한 번에 등록하는 것이 관리에 용이하다.

```
ros2 run tf2_ros static_transform_publisher \
  1.0 0 0 0 0 0 base_link lidar_link \
  0 0 0 0 0 0 base_link camera_link
```

정적 변환 필요성 재점검:

* 변하지 않는 링크 간 관계는 URDF나 SDF 상에만 기재해 두면 된다고 착각할 수 있으나, 실제 ROS2 시스템에서 tf2로 사용하려면 해당 관계를 tf2 메시지로 반드시 발행해야 한다.
* URDF로부터 자동으로 tf2를 발행해주는 robot\_state\_publisher 사용 시에도, URDF 내 조인트가 고정형(fixed)으로 정의되었는지 점검해야 한다.

#### Robot State Publisher 미작동으로 인한 프레임 누락

ROS2 로봇 시스템에서 URDF(Xacro 포함)를 이용해 로봇의 조인트, 링크 정보를 기술해 두었다면, 일반적으로 `robot_state_publisher` 노드를 실행하여 URDF 상의 모든 링크와 조인트 관계를 tf2 트리에 자동으로 반영한다. 만약 이 노드가 실행되지 않거나, URDF 경로 설정이 잘못되면 중요한 로봇 프레임이 tf2 트리에 등록되지 않게 된다.

**원인**:

* launch 파일에서 `robot_state_publisher` 노드를 빼먹고 실행하지 않음
* 잘못된 URDF 경로, 혹은 URDF 파싱 실패(Xacro 매크로 문법 에러 등)
* URDF 내 일부 조인트가 누락되어 로봇 전신이 아니라 일부만 tf2 트리에 반영됨

**해결책**:

URDF/Xacro 파일 점검:

* Xacro 매크로 문법 오류가 없는지, `xacro check` 등의 유효성 검사를 수행한다.
* URDF(Xacro)에서 모든 링크와 조인트가 의도대로 정의되어 있는지 확인한다.

robot\_state\_publisher 노드 실행:

* 다음과 같이 명령을 통해 직접 실행해 보고 tf2 트리에 정상 반영되는지 확인한다.

```
ros2 run robot_state_publisher robot_state_publisher --ros-args -p use_sim_time:=true
```

* launch 파일 상에 URDF 경로, Xacro 변환 명령 등을 명시적으로 기재한다.

조인트 타입 확인:

* 회전/슬라이더 등의 조인트(joint)이 실제로 ‘fixed’가 아닌데도 불구하고, 잘못 ‘fixed’로 정의되어 있으면 움직임이 반영되지 않을 수 있다.
* 반대로 ‘fixed’ 조인트가 실은 가동형 조인트로 정의되어 있으면 tf2 트리에 이상치가 발생할 수 있으므로, URDF 상에서 조인트 타입을 재검토한다.

#### frame\_id와 child\_frame\_id 혼동

tf2 메시지(예: `geometry_msgs/msg/TransformStamped`)에서 `header.frame_id`와 `child_frame_id`가 바뀌어 쓰이거나, 로봇의 기본 프레임(base\_link)와 센서 프레임(`camera_link` 등)이 뒤집혀 등록되는 경우가 발생한다. 이는 의도치 않은 프레임 구조를 만들거나, 역변환을 잘못 적용하게 만든다.

**원인**:

* 소스 코드에서 transform을 보낼 때 순서(부모 → 자식)를 헷갈려 기재
* 코드 재활용 과정에서 frame 이름을 매크로로 처리했으나, 올바른 인자를 주지 않음
* 특정 노드가 제공하는 tf2 transform 메시지의 관례와 사용자 설정이 충돌

**해결책**:

소스 코드 점검:

* 아래와 같이 transform 브로드캐스터를 구성할 때, 반드시 `parent = header.frame_id`, `child = child_frame_id`를 지키는지 확인한다.

```cpp
geometry_msgs::msg::TransformStamped transform_stamped;
transform_stamped.header.stamp = now();
transform_stamped.header.frame_id = "base_link";     // 부모
transform_stamped.child_frame_id = "camera_link";    // 자식
...
broadcaster_->sendTransform(transform_stamped);
```

프레임 트리 시각화:

* RViz2, `tf2_tools`, `rqt_tf_tree` 등을 통해 현재 tf2 트리 구조를 확인한다.
* 자식-부모 관계가 뒤집힌 링크가 있는지, 또는 base\_link 아래에 부모가 생기는 기이한 구조가 있는지 점검한다.

정확한 명명 규칙:

* 일반적으로 “부모 프레임 → 자식 프레임” 구성을 유지하기 위해, 센서는 로봇 본체(base\_link) 또는 로봇 부품(prismatic\_link 등)에 종속된 구조로 잡는다.
* 기체(드론), 유사 바퀴 로봇 등에서 부득이하게 “기준 프레임” 자체가 자주 바뀔 경우, 미리 tf2 트리 다이어그램을 설계해 두고 혼동을 방지한다.

#### tf2 Transform 브로드캐스트 시 좌표계 변환 행렬 오류

tf2는 내부적으로 $4 \times 4$ 동차좌표계 행렬(homogeneous transformation matrix)로 변환을 관리한다. 브로드캐스터가 변환을 발행할 때, 회전 행렬이나 병진 벡터에 오류가 있으면 로봇 모델과 실제 장치의 상대 위치가 심각하게 어긋날 수 있다.

**원인**:

* 회전 행렬 $\mathbf{R}$ 구성 시, yaw, pitch, roll 순서를 잘못 적용
* 쿼터니언(Quaternion) 계산 시 노멀라이즈(normalize)를 누락하여 tf2 측에서 에러 발생
* 병진 벡터 $\mathbf{t} = (x, y, z)$를 본래 의도와 다르게 축을 바꿔 입력

**해결책**:

정확한 회전 변환 확인:

* 변환을 구성할 때 Euler 각($\alpha, \beta, \gamma$)을 사용한다면, 순서가 Z-Y-X인지, X-Y-Z인지, 또는 Z-Y-Z인지를 꼭 확인한다.
* ROS 표준(RPY: Roll-Pitch-Yaw)은 일반적으로 X(roll), Y(pitch), Z(yaw) 순서로 적용하지만, 사용자 코드 또는 특정 라이브러리가 다른 순서를 쓰는지 점검한다.
* 예시: “Z-Y-X” 순서로 회전을 구성하는 경우, 최종 회전 행렬은 다음과 같이 표현될 수 있다.

$$
\mathbf{R}(\gamma, \beta, \alpha) =  \mathbf{R}\_z(\gamma) \mathbf{R}\_y(\beta) \mathbf{R}\_x(\alpha)
$$

쿼터니언 계산 주의:

* ROS2 TF 브로드캐스터에서 주로 쿼터니언을 사용해 회전을 표현하므로, Euler → Quaternion 변환 시 정확한 함수를 사용한다.
* RPY → Quaternion 변환 함수 호출 후, 쿼터니언이 정상화(normalize)되는지 확인한다.

좌표 축 정의 일관성:

* ROS 기본 좌표계(우측좌표계)에서 x 축은 전진, y 축은 왼쪽, z 축은 위쪽을 의미한다.
* 다른 소프트웨어(예: OpenCV, 게임엔진 등)와의 혼합 사용 시, 축 방향이 다를 수 있으므로 변환 매트릭스에서 축 변환을 주의 깊게 처리한다.

#### tf2 프레임 확장 시 누락 발생 (멀티 로봇 환경)

여러 대의 로봇을 운용하거나, 멀리 떨어진 분산 센서 시스템을 사용할 경우, 각기 다른 tf2 트리를 합쳐야 할 때 누락이나 중복이 발생할 수 있다. 특히, 동일한 ‘world’ 프레임을 기준으로 삼으면서도 실제 위치가 달라 충돌하는 사례가 생긴다.

**원인**:

* 각각의 로봇 시스템이 자체적으로 ‘world’라는 프레임을 쓰고, 병합 과정에서 혼동
* 네트워크 지연이나 QoS 설정이 달라 특정 로봇 tf2만 수신되지 않는 상황
* 로봇 A에서 로봇 B를 가리키는 변환(상대 좌표계)이 누락되어, 로봇 B를 찾을 수 없는 문제

**해결책**:

프레임 네임스페이스 구분:

* 멀티 로봇 운용 시, 로봇별 접두사(prefix)를 둔다. 예: `robot1/base_link`, `robot2/base_link` 등
* world 프레임도 `world1`, `world2`처럼 로컬 범위를 명시하거나, 하나의 절대적 월드 프레임을 공유할 경우 각 로봇의 초기 좌표를 확실히 설정한다.

QoS 설정 및 네트워크 점검:

* 멀리 떨어진 로봇 간 통신에서는 QoS를 Reliable로 바꾸거나, ROS2 DDS에서 multicast 설정을 확인한다.
* TF 트리 병합에 필요한 transform을 발행하는 노드가 제대로 동작 중인지, 토픽명(tf\_static 등)이 충돌하지 않는지 확인한다.

상호 참조 프레임 생성""

* 로봇 A와 로봇 B 간 위치 관계를 알 수 있도록, A에서 B로 가는 transform(또는 그 반대)을 정의해야 한다. 이를 static transform publisher로 등록하거나, SLAM/Localization 알고리즘의 결과로 실시간 업데이트할 수 있다.

#### tf2 Static / Dynamic Transform 혼합 시 시점 불일치

시스템에 정적(static) 변환과 동적(dynamic) 변환을 동시에 적용할 때, 시점(time stamp)이 일치하지 않아 예기치 않은 트랜스폼 에러가 발생할 수 있다. 보통 정적 변환은 시간에 구애받지 않고 유지되지만, 동적 변환은 지속적으로 업데이트되기 때문에, 과거 시점 혹은 미래 시점에 대한 쿼리를 처리할 때 누락이 생길 수 있다.

**원인**:

* 정적 변환 노드(tf2\_static\_transform\_broadcaster)와 동적 변환 노드(tf2\_ros::TransformBroadcaster)를 혼용하면서, 버퍼에 저장된 특정 시점의 변환이 존재하지 않음
* 동적 변환 주기가 너무 길거나(혹은 너무 짧거나) 시뮬레이션 시간과 실제 시간 사이에 편차가 커짐
* 초기에 정적 변환을 발행하는 타이밍과 동적 변환 노드가 시작되는 타이밍이 맞지 않아, 쿼리 시점에 부모나 자식 프레임 중 하나가 누락

**해결책**:

1. 초기화 순서 통제
   * launch 파일에서 정적 변환 발행 노드가 충분히 먼저 실행되도록 순서를 조정한다.
   * 필요한 경우, “lifecycle” 또는 “구동 스크립트”를 사용해 미리 정적 변환이 준비된 이후 동적 노드를 구동한다.
2. 동적 변환 주기 재설정
   * 동적 변환이 너무 잦으면, tf2 버퍼가 과도하게 커져 예기치 않은 지연이 발생할 수 있으므로 적절한 주기로 발행한다.
   * 반대로 너무 낮은 주기로 발행하면 과거 시점 조회가 불가능해지는 경우가 있으니, 사용 시나리오에 맞게 조정한다.
3. 시뮬레이션/실시간 모드 구분
   * `use_sim_time` 파라미터가 켜져 있을 때, 시뮬레이션 시간과 실제 시간이 일치하지 않는지 확인한다.
   * 시뮬레이터(예: Gazebo, Ignition)와 통신 시 지연이 큰 경우, 필수 변환이 늦게 도착하여 tf2 쿼리가 실패하지 않는지 모니터링한다.

#### TF 레이트(Rate) 불일치로 발생하는 지연 문제

ROS2 tf2는 변환을 버퍼링(buffer)하고, LookupTransform 함수나 tf2\_listener를 통해 특정 시점의 변환을 제공한다. 이때 서로 다른 레이트(rate)로 변환이 발행될 경우, 버퍼가 올바르게 갱신되지 않아 간헐적 지연이 발생할 수 있다.

**원인**:

* 로봇 조인트 상태(모터 인코더) 데이터를 빠른 주기로 변환에 반영하려 하는데, 브로드캐스터가 낮은 주기로만 실행 중
* 센서 A와 센서 B가 서로 다른 레이트로 tf2를 발행하며, 동기화 지점이 맞물리지 않음
* CPU 리소스 부족 등으로 인해 변환 발행 스레드가 뒤처지면서 타이밍 오프셋 발생

**해결책**:

1. 발행 주기 표준화
   * 센서나 모터 드라이버에서 주기적으로 읽어온 데이터의 주기가 100Hz라면, tf2 브로드캐스터 역시 비슷한 주기로 갱신하게 조정한다.
   * tf2가 필요 이상으로 높은 주기로 발행되고 있을 때, 시스템 리소스를 무의미하게 소모하지 않도록 조정한다.
2. 정확한 시간 동기
   * 멀티 보드(멀티 컴퓨터) 환경에서 ROS2 DDS가 서로 다른 주파수로 발행할 때, 시간 동기가 제대로 되어 있는지 확인한다.
   * QoS에 대한 Reliability 설정과 함께, NTP/Chrony 등 외부 시간 동기화도 점검한다.
3. tf2 호출 측에서 Timeout 설정
   * 특정 시점의 tf2를 요청하는데 시간 초과가 잦다면, tf2 Listener 함수 호출 시 타임아웃(timeout)을 충분히 길게 잡거나, 재시도를 허용하는 로직을 추가한다.
   * 단, 비정상적으로 긴 타임아웃은 오히려 시스템 응답성을 떨어뜨릴 수 있으므로 주의한다.

#### tf2 Transform 프레임 간 무한 루프(Cycle) 생성

tf2 트리는 방향성을 가진 비순환 그래프(DAG) 형태여야 한다. 그러나 설정 실수로 인해 부모 프레임과 자식 프레임이 서로를 참조하는 순환(cycle)이 생기면, tf2 측에서 지속적으로 에러를 발생시키거나 변환 구성이 꼬일 수 있다.

**원인**:

* Launch 파일이나 소스 코드에서 A → B, B → A 형태로 서로 다른 노드가 동시에 변환을 발행
* URDF 상의 링크 정의가 잘못되어, 상위 링크와 하위 링크가 여러 갈래로 이어지는 구조
* 멀티 로봇 환경에서, 로봇 A의 ‘world’ 프레임과 로봇 B의 ‘world’ 프레임을 서로 부모-자식 관계로 연결

**해결책**:

1. tf2 트리 시각화
   * `rqt_tf_tree` 또는 `tf2_tools/view_frames` 등의 도구로 tf 트리를 시각화하면, 사이클이 존재할 경우 경고가 표시되거나, 정상적 트리 구조가 보이지 않는다.
   * 의도치 않은 링크가 서로 연결되어 있는 부분을 찾아낸 뒤 수정한다.
2. 단일 기준 프레임 설정
   * 로봇 한 대에서는 일반적으로 ‘base\_link’ 혹은 ‘odom’ → ‘base\_link’가 최상위 부모가 되도록 하고, 그 밑으로 각 센서를 매단다.
   * 멀티 로봇 환경에서도 ‘world’ 프레임 하나를 절대적 기준으로 삼고, 각 로봇은 `robotN/base_link` 식으로만 이어지도록 한다.
3. 코드 중복 제거
   * 동일한 변환을 중복해서 브로드캐스트하지 않도록, 변환 발행 코드를 하나로 모은다.
   * static\_transform\_publisher를 여러 번 띄우지 않도록 주의하고, 필요한 경우 하나의 명령으로 여러 변환을 묶어 발행한다.

#### tf2 Debugging 도구 활용

ROS2 생태계에서는 tf2 트리를 진단하고 모니터링할 수 있는 여러 도구를 제공한다. 문제 상황을 재현하거나, 현재 tf 트리 상태를 시각화·분석하는 과정에서 매우 유용하다.

**rqt\_tf\_tree**:

* ROS2 GUI 플러그인 형태로, 현재 활성화된 tf2 노드들이 어떤 구조로 연결되어 있는지 트리 형태로 보여준다.
* loop(사이클), 중복 프레임, 누락된 링크 등을 한눈에 파악 가능하다.

**tf2\_tools**:

* `view_frames` 명령 등을 통해 pdf/png 형태의 tf2 트리 다이어그램을 생성할 수 있다.

```
ros2 run tf2_tools view_frames
```

* tf2 버퍼 내부에 기록된 모든 프레임 정보와 해당 변환의 latched 시점 등이 시각화된다.
* 순환(cycle)이 있으면 경고 메시지를 출력해 준다.

**tf2\_monitor**:

* 트랜스폼 발행 상태를 실시간으로 모니터링하며, 누락되거나 오래된(tf\_age가 큰) 변환을 탐지할 수 있다.

```
ros2 run tf2_tools tf2_monitor
```

* 지연(delay), 최근 업데이트 시각 등의 정보를 출력하여, 특정 프레임이 늦게 들어오거나 전혀 들어오지 않는 상황을 분석하는 데 사용한다.

**RViz2**:

* RViz2에서 “TF” 디스플레이를 활성화하면, 실제 3D 공간 상에서 현재 tf 트리의 상대 위치와 방향을 실시간으로 확인할 수 있다.
* 특정 센서 프레임과 로봇 프레임이 맞물리지 않거나, 자이로/IMU/카메라 등의 축이 어긋나면 육안으로 쉽게 알 수 있다.

#### 시뮬레이터/Gazebo 환경에서의 tf2 문제

Gazebo(또는 Ignition, Webots 등)에서 ROS2 인터페이스를 사용하면, 시뮬레이션 시간(clock)이 실제 호스트 시간과 다를 수 있다. 이로 인해 tf2 타임스탬프가 어긋나거나, 버퍼 누락 문제가 자주 발생한다.

**use\_sim\_time 파라미터 확인**:

* 시뮬레이션 환경에서는 일반적으로 `use_sim_time := true`로 설정해야 Gazebo가 제공하는 시뮬레이션 시간과 ROS2 노드가 동기화된다.
* 만약 이를 깜빡하고 설정하지 않으면, tf2 노드는 호스트(실제) 시간을 쓰게 되어 transform 조회 시 “no transform for that time” 오류가 잦아진다.

**상황별 기준 프레임**:

* 시뮬레이터에서 “world” 프레임이 자주 사용되는데, 이 프레임이 실제 로봇의 “odom”이나 “map” 프레임과 어떤 관계인지 분명히 정해둬야 한다.
* 여러 로봇이 동시에 등장하는 시뮬레이션이면, 각 로봇별로 분리된 base\_link 계층이 존재하므로, tf2 트리가 얽히지 않도록 주의한다.

**시뮬레이션 중 State Publisher 연동**:

* Gazebo 플러그인(예: gazebo\_ros2\_control 등)을 사용하면 자동으로 조인트 상태가 로컬 토픽에 발행되고, 이 정보를 `robot_state_publisher`가 받아 tf2에 반영한다.
* 플러그인 설정 파일이나 SDF 내 로봇 모델 정보가 누락되면, 일부 조인트가 tf2에 등록되지 않는 상황이 생긴다.

#### IMU/SLAM 등 외부 알고리즘 연동 시 tf2 오류

로봇 위치 추정, 관성측정장치(IMU) 계산, SLAM 알고리즘 등은 tf2와 밀접하게 연동된다. SLAM 노드는 “map → odom → base\_link” 체계를 생성하거나, IMU는 “base\_link → imu\_link” 변환을 제공하기 때문이다. 이때 변환 설정이 잘못되면, 로봇의 추정 위치가 심각하게 어긋난다.

**IMU 축 정의**:

* 일반적으로 IMU 센서는 x 축이 전방, y 축이 좌측, z 축이 상방으로 정렬되어 있는지 확인한다.
* 센서가 실제 로봇에 설치된 방향과 다를 경우, IMU 출력을 tf2에서 올바르게 회전해서 사용해야 한다.

**SLAM 프레임 구성**:

* ROS2 SLAM 노드(예: slam\_toolbox, cartographer\_ros2 등)는 보통 “map” → “odom” 변환을 발행한다.
* 사용자가 만든 odometry 노드가 “odom” → “base\_link” 변환을 발행한다.
* 결과적으로 “map → odom → base\_link”라는 2단 변환 계층이 형성되는데, 이를 뒤집어서 “odom → map” 등을 발행하면 충돌이 생길 수 있다.

**AMCL, Navigation2 연동**:

* 2D LIDAR 기반 Localization인 AMCL 노드도 “map” → “odom” 변환을 업데이트한다.
* Navigation2에서 “odom” → “base\_link”를 관리하는 로직(혹은 로봇 자체의 odometry 소프트웨어)과 충돌이 없는지 주의 깊게 살핀다.

위와 같은 tf2 관련 오류 사례를 면밀히 살펴보고, 각 문제의 원인과 해결책을 적절히 적용하면 ROS2 개발 과정에서 발생하는 다수의 좌표계 및 변환 충돌 문제를 상당 부분 해소할 수 있다.
