659.60 변환 행렬의 합성 (Composition)

1. 개요

로봇 시스템에서는 복수의 좌표 프레임(coordinate frame) 간의 관계를 연쇄적으로 결합하여 최종적인 기하학적 변환을 산출해야 하는 경우가 빈번하다. 변환 행렬의 합성(composition)이란, 두 개 이상의 동차 변환 행렬(homogeneous transformation matrix)을 순차적으로 곱하여 중간 좌표 프레임을 거치는 변환을 하나의 단일 변환으로 축약하는 연산을 의미한다. 이 합성 연산은 TF2 좌표 변환 트리(transform tree)에서 임의의 두 프레임 간 변환을 계산하는 핵심 메커니즘이다.

2. 동차 변환 행렬의 합성 원리

2.1 순차 합성의 수학적 정의

프레임 A에서 프레임 B로의 동차 변환 행렬을 {}^{A}T_{B}로 표기하고, 프레임 B에서 프레임 C로의 동차 변환 행렬을 {}^{B}T_{C}로 표기하면, 프레임 A에서 프레임 C로의 합성 변환은 다음과 같이 행렬 곱으로 표현된다.

{}^{A}T_{C} = {}^{A}T_{B} \cdot {}^{B}T_{C}

여기서 각 동차 변환 행렬은 4 \times 4 행렬이며, 다음과 같은 구조를 갖는다.

{}^{A}T_{B} = \begin{bmatrix} {}^{A}R_{B} & {}^{A}\mathbf{t}_{B} \\ \mathbf{0}^{\top} & 1 \end{bmatrix}

{}^{A}R_{B} \in SO(3)3 \times 3 회전 행렬(rotation matrix)이며, {}^{A}\mathbf{t}_{B} \in \mathbb{R}^{3}는 병진 벡터(translation vector)이다.

2.2 합성 결과의 성분 분해

두 동차 변환 행렬 {}^{A}T_{B}{}^{B}T_{C}를 곱하면, 결과 행렬 {}^{A}T_{C}의 회전 성분과 병진 성분은 다음과 같이 분해된다.

{}^{A}R_{C} = {}^{A}R_{B} \cdot {}^{B}R_{C}

{}^{A}\mathbf{t}_{C} = {}^{A}R_{B} \cdot {}^{B}\mathbf{t}_{C} + {}^{A}\mathbf{t}_{B}

회전 성분은 두 회전 행렬의 곱으로 합성되며, 이는 순차적인 회전의 결합을 나타낸다. 병진 성분은 단순한 벡터 덧셈이 아니라, 첫 번째 변환의 회전 행렬이 두 번째 변환의 병진 벡터에 적용된 후 첫 번째 변환의 병진 벡터와 합산되는 구조이다. 이는 병진이 적용되는 좌표계가 회전에 의해 변환되었기 때문이다.

2.3 다중 프레임 연쇄 합성

n개의 좌표 프레임 F_0, F_1, \ldots, F_{n}이 순차적으로 연결되어 있을 때, 프레임 F_0에서 프레임 F_{n}으로의 합성 변환은 다음과 같다.

{}^{F_0}T_{F_n} = {}^{F_0}T_{F_1} \cdot {}^{F_1}T_{F_2} \cdots {}^{F_{n-1}}T_{F_n} = \prod_{i=0}^{n-1} {}^{F_i}T_{F_{i+1}}

이 연쇄 곱(chain product)은 TF2에서 변환 트리의 경로를 따라 자동으로 수행되는 연산의 수학적 기반이다.

3. 합성 연산의 대수적 성질

3.1 결합법칙 (Associativity)

동차 변환 행렬의 합성은 결합법칙(associativity)을 만족한다.

({}^{A}T_{B} \cdot {}^{B}T_{C}) \cdot {}^{C}T_{D} = {}^{A}T_{B} \cdot ({}^{B}T_{C} \cdot {}^{C}T_{D})

따라서 연쇄 합성의 중간 과정에서 어떤 순서로 괄호를 묶어 계산하더라도 최종 결과는 동일하다. 이 성질은 TF2가 트리 구조의 임의 경로에서 변환을 합성할 때 계산 순서의 유연성을 보장한다.

3.2 비교환성 (Non-Commutativity)

동차 변환 행렬의 합성은 일반적으로 교환법칙(commutativity)을 만족하지 않는다.

{}^{A}T_{B} \cdot {}^{B}T_{C} \neq {}^{B}T_{C} \cdot {}^{A}T_{B}

이는 3차원 공간에서 회전 연산 자체가 비교환적이기 때문이다. 예를 들어, x축 주위 90° 회전 후 y축 주위 90° 회전의 결과는, y축 주위 90° 회전 후 x축 주위 90° 회전의 결과와 다르다. 따라서 변환 합성 시 곱셈 순서를 반드시 준수해야 하며, 이는 로봇 공학에서 좌표 변환 구현 시 빈번하게 발생하는 오류의 원인이 된다.

3.3 역원의 존재 (Existence of Inverse)

모든 정규(proper) 동차 변환 행렬은 역행렬이 존재하며, 이는 SE(3) 군(group)의 구조적 성질이다.

{}^{A}T_{B} \cdot {}^{B}T_{A} = I_{4 \times 4}

여기서 {}^{B}T_{A} = ({}^{A}T_{B})^{-1}이다. 역변환의 효율적 계산 방법은 별도의 절에서 다룬다.

3.4 SE(3) 군 구조

동차 변환 행렬의 합성은 특수 유클리드 군 SE(3)(Special Euclidean group in 3D)의 군 연산에 해당한다. SE(3)는 다음의 군 공리를 만족한다.

공리성질
폐쇄성 (Closure)SE(3) 원소의 곱은 다시 SE(3)에 속한다
결합법칙 (Associativity)(T_1 \cdot T_2) \cdot T_3 = T_1 \cdot (T_2 \cdot T_3)
항등원 (Identity)I_{4 \times 4} \in SE(3)
역원 (Inverse)모든 T \in SE(3)에 대해 T^{-1} \in SE(3)

이러한 군 구조는 좌표 변환의 합성이 항상 유효한 강체 변환(rigid body transformation)을 산출함을 수학적으로 보장한다.

4. TF2에서의 변환 합성 메커니즘

4.1 변환 트리를 통한 자동 합성

TF2는 변환 트리(transform tree) 구조를 활용하여 변환 합성을 자동으로 수행한다. lookupTransform() 함수를 호출하면, TF2는 지정된 소스 프레임(source frame)에서 대상 프레임(target frame)까지의 경로를 트리에서 탐색하고, 경로상의 모든 중간 변환을 순차적으로 합성하여 최종 변환을 반환한다.

예를 들어, 변환 트리가 다음과 같이 구성되어 있다고 하자.

map → odom → base_link → sensor_link

이때 lookupTransform("map", "sensor_link", time)를 호출하면, TF2는 내부적으로 다음 합성을 수행한다.

{}^{\text{map}}T_{\text{sensor\_link}} = {}^{\text{map}}T_{\text{odom}} \cdot {}^{\text{odom}}T_{\text{base\_link}} \cdot {}^{\text{base\_link}}T_{\text{sensor\_link}}

4.2 rclcpp에서의 수동 합성

TF2의 자동 합성 메커니즘 외에도, 개발자는 tf2::Transform 객체를 사용하여 변환을 수동으로 합성할 수 있다.

#include <tf2/LinearMath/Transform.h>

tf2::Transform T_A_B;  // 프레임 A에서 B로의 변환
tf2::Transform T_B_C;  // 프레임 B에서 C로의 변환

// 회전과 병진 설정
T_A_B.setOrigin(tf2::Vector3(1.0, 0.0, 0.0));
T_A_B.setRotation(tf2::Quaternion(0.0, 0.0, 0.707, 0.707));

T_B_C.setOrigin(tf2::Vector3(0.0, 2.0, 0.0));
T_B_C.setRotation(tf2::Quaternion(0.0, 0.0, 0.0, 1.0));

// 변환 합성: T_A_C = T_A_B * T_B_C
tf2::Transform T_A_C = T_A_B * T_B_C;

tf2::Transformoperator*는 내부적으로 쿼터니언 곱셈과 병진 벡터의 회전 적용 및 합산을 수행하며, 이는 동차 변환 행렬의 합성과 수학적으로 동치이다.

4.3 rclpy에서의 수동 합성

Python 환경에서는 tf_transformations 또는 numpy를 사용하여 변환을 합성할 수 있다.

import numpy as np
from tf_transformations import (
    quaternion_matrix,
    translation_matrix,
    concatenate_matrices
)

# 프레임 A에서 B로의 변환 행렬 구성
T_A_B = np.dot(
    translation_matrix([1.0, 0.0, 0.0]),
    quaternion_matrix([0.0, 0.0, 0.707, 0.707])
)

# 프레임 B에서 C로의 변환 행렬 구성
T_B_C = np.dot(
    translation_matrix([0.0, 2.0, 0.0]),
    quaternion_matrix([0.0, 0.0, 0.0, 1.0])
)

# 변환 합성: T_A_C = T_A_B @ T_B_C
T_A_C = T_A_B @ T_B_C

numpy의 행렬 곱 연산자 @를 사용하면 4 \times 4 동차 변환 행렬의 합성을 직관적으로 수행할 수 있다.

5. 쿼터니언 기반 합성

5.1 쿼터니언을 이용한 회전 합성

TF2 내부에서는 회전을 쿼터니언(quaternion)으로 표현하며, 회전의 합성은 쿼터니언 곱셈(quaternion multiplication)으로 수행된다. 두 회전 q_1q_2의 합성은 다음과 같다.

q_{\text{composed}} = q_1 \otimes q_2

쿼터니언 곱셈은 Hamilton 곱(Hamilton product)으로 정의되며, q_1 = (w_1, x_1, y_1, z_1), q_2 = (w_2, x_2, y_2, z_2)일 때 다음과 같이 계산된다.

q_1 \otimes q_2 = \begin{pmatrix} w_1 w_2 - x_1 x_2 - y_1 y_2 - z_1 z_2 \\ w_1 x_2 + x_1 w_2 + y_1 z_2 - z_1 y_2 \\ w_1 y_2 - x_1 z_2 + y_1 w_2 + z_1 x_2 \\ w_1 z_2 + x_1 y_2 - y_1 x_2 + z_1 w_2 \end{pmatrix}

5.2 쿼터니언 합성과 행렬 합성의 동치성

쿼터니언 곱 q_1 \otimes q_2와 회전 행렬 곱 R_1 \cdot R_2는 동일한 회전을 나타낸다.

R(q_1 \otimes q_2) = R(q_1) \cdot R(q_2)

여기서 R(q)는 쿼터니언 q에 대응하는 3 \times 3 회전 행렬이다. 쿼터니언 기반 합성은 3 \times 3 행렬 곱셈(27회 곱셈, 18회 덧셈)에 비해 계산 비용(16회 곱셈, 12회 덧셈)이 낮으며, 짐벌 락(gimbal lock) 문제를 회피할 수 있다는 이점이 있다.

5.3 병진과 회전의 통합 합성

전체 변환(회전 + 병진)의 쿼터니언 기반 합성은 다음과 같이 수행된다.

\mathbf{t}_{\text{composed}} = R(q_1) \cdot \mathbf{t}_2 + \mathbf{t}_1

q_{\text{composed}} = q_1 \otimes q_2

여기서 \mathbf{t}_1, \mathbf{t}_2는 각각 첫 번째와 두 번째 변환의 병진 벡터이다. TF2의 tf2::Transform 클래스는 내부적으로 이 방식을 사용하여 변환 합성을 수행한다.

6. 합성 연산의 수치적 고려사항

6.1 수치 오차의 누적

부동소수점(floating-point) 연산의 특성상, 다수의 변환을 연쇄적으로 합성하면 수치 오차가 누적될 수 있다. 특히 회전 행렬의 경우, 반복적인 곱셈을 통해 직교성(orthogonality) 조건 R^{\top}R = I와 행렬식 조건 \det(R) = 1이 점진적으로 위반될 수 있다.

6.2 재정규화 (Renormalization)

수치 오차 누적을 방지하기 위하여, 쿼터니언의 경우 주기적인 정규화(normalization)가 필요하다.

\hat{q} = \frac{q}{\|q\|}

회전 행렬의 경우에는 그람-슈미트 직교화(Gram-Schmidt orthogonalization) 또는 SVD(Singular Value Decomposition) 기반의 최근접 직교 행렬 투영(nearest orthogonal matrix projection)을 통해 직교성을 복원할 수 있다.

R_{\text{corrected}} = U V^{\top}, \quad \text{where } R = U \Sigma V^{\top}

6.3 연쇄 길이에 따른 오차 분석

변환 트리에서 루트 프레임(root frame)으로부터 말단 프레임(leaf frame)까지의 경로가 길어질수록 합성에 관여하는 행렬 곱의 횟수가 증가하며, 이에 비례하여 수치 오차가 누적된다. 따라서 프레임 트리 설계 시 불필요하게 깊은 계층 구조를 피하고, 핵심 프레임 간의 경로 길이를 최소화하는 것이 권장된다.

7. 합성 연산의 응용 사례

7.1 매니퓰레이터의 순기구학

다관절 로봇 매니퓰레이터(serial manipulator)의 순기구학(forward kinematics)은 변환 행렬 합성의 전형적인 응용이다. n개의 관절(joint)을 갖는 매니퓰레이터의 말단 장치(end-effector) 자세는 다음과 같이 계산된다.

{}^{0}T_{n} = {}^{0}T_{1}(q_1) \cdot {}^{1}T_{2}(q_2) \cdots {}^{n-1}T_{n}(q_n)

여기서 q_ii번째 관절의 관절 변수(joint variable)이며, 각 {}^{i-1}T_{i}(q_i)는 Denavit-Hartenberg(DH) 파라미터 또는 Product of Exponentials(PoE) 공식에 의해 정의된다.

7.2 센서 데이터의 좌표 변환

센서에서 취득한 데이터를 로봇 기준 좌표계(base frame) 또는 세계 좌표계(world frame)로 변환하려면, 센서 프레임에서 목표 프레임까지의 변환을 합성해야 한다. 예를 들어, LiDAR 센서에서 취득한 포인트 클라우드(point cloud)를 세계 좌표계로 변환하려면 다음 합성이 필요하다.

{}^{\text{map}}T_{\text{lidar}} = {}^{\text{map}}T_{\text{odom}} \cdot {}^{\text{odom}}T_{\text{base\_link}} \cdot {}^{\text{base\_link}}T_{\text{lidar}}

7.3 다중 로봇 간 상대 변환

다중 로봇 시스템에서 로봇 A의 센서 데이터를 로봇 B의 좌표계에서 해석하려면, 공통 참조 프레임(예: map)을 경유한 변환 합성이 필요하다.

{}^{B_{\text{base}}}T_{A_{\text{sensor}}} = ({}^{\text{map}}T_{B_{\text{base}}})^{-1} \cdot {}^{\text{map}}T_{A_{\text{base}}} \cdot {}^{A_{\text{base}}}T_{A_{\text{sensor}}}

8. 합성 순서에 관한 주의사항

8.1 사전 곱셈과 사후 곱셈

변환의 합성 순서에는 두 가지 해석이 존재한다.

  • 사전 곱셈(Pre-multiplication): 고정 좌표계(fixed frame)에서의 변환이 왼쪽에 곱해지는 방식이다. 전역 좌표계(global frame) 기준의 변환에 해당하며, T_{\text{new}} = T_{\text{global}} \cdot T_{\text{current}}로 표현된다.

  • 사후 곱셈(Post-multiplication): 현재 좌표계(current frame)에서의 변환이 오른쪽에 곱해지는 방식이다. 로컬 좌표계(local frame) 기준의 변환에 해당하며, T_{\text{new}} = T_{\text{current}} \cdot T_{\text{local}}로 표현된다.

TF2에서 lookupTransform()이 반환하는 변환은 항상 부모-자식 관계의 순방향 합성이며, 트리 경로를 따라 자동으로 올바른 곱셈 순서가 적용된다.

8.2 일반적 오류 유형

변환 합성에서 빈번하게 발생하는 오류는 다음과 같다.

  1. 곱셈 순서 오류: T_{AB} \cdot T_{BC}T_{BC} \cdot T_{AB}로 잘못 계산하는 경우
  2. 프레임 불일치: 인접하지 않은 프레임의 변환을 직접 곱하는 경우 (예: T_{AB} \cdot T_{CD}에서 B \neq C)
  3. 역변환 누락: 트리에서 역방향 이동 시 역변환을 적용하지 않는 경우

이러한 오류는 TF2의 자동 합성 메커니즘을 활용하면 원천적으로 방지할 수 있다.

9. 참고 문헌

  • R. M. Murray, Z. Li, and S. S. Sastry, A Mathematical Introduction to Robotic Manipulation, CRC Press, 1994.
  • B. Siciliano, L. Sciavicco, L. Villani, and G. Oriolo, Robotics: Modelling, Planning and Control, Springer, 2009.
  • J. J. Craig, Introduction to Robotics: Mechanics and Control, 4th ed., Pearson, 2018.
  • Open Robotics, “tf2 Documentation,” ROS 2 Documentation, https://docs.ros.org/en/rolling/Concepts/Intermediate/About-Tf2.html
  • T. Foote, “tf: The transform library,” in Proc. IEEE Conf. Technologies for Practical Robot Applications (TePRA), 2013, pp. 1–6.

버전: 2026-03-26