10.24 쿼터니언의 부호 모호성과 해결 방법
1. 부호 모호성의 본질
쿼터니언 \mathbf{q}와 -\mathbf{q}가 같은 3차원 회전을 나타낸다. 이 부호 이중성은 S^3가 SO(3)을 이중 피복한다는 위상학적 사실의 직접적 결과이며, 쿼터니언을 사용하는 모든 응용에서 주의 깊게 처리되어야 한다.
\mathbf{R}(\mathbf{q}) = \mathbf{R}(-\mathbf{q})
이 모호성을 무시하면 보간, 평균, 비교 등의 연산에서 예상치 못한 결과가 발생한다.
2. 부호 모호성이 문제가 되는 경우
2.1 회전 보간
두 쿼터니언 \mathbf{q}_1과 \mathbf{q}_2 사이를 보간할 때, 부호 선택에 따라 짧은 경로 또는 긴 경로가 선택될 수 있다.
2.1.1 짧은 경로
\mathbf{q}_1과 \mathbf{q}_2가 4차원 공간에서 가까이 있으면 직접 보간이 짧은 경로를 따른다.
2.1.2 긴 경로
\mathbf{q}_1과 \mathbf{q}_2가 대척점에 가까우면(예: \mathbf{q}_2 \approx -\mathbf{q}_1) 직접 보간이 긴 경로를 따른다. 이는 시각적으로 의도와 다른 회전을 만든다.
2.2 자세 비교
두 쿼터니언이 같은 회전을 나타내는지 확인할 때, 단순 성분 비교가 실패할 수 있다.
\mathbf{q} \neq -\mathbf{q} \text{ (성분 비교)}
그러나 둘 다 같은 회전을 나타낸다.
2.3 자세 평균
여러 쿼터니언의 평균을 계산할 때, 부호가 일관되지 않으면 평균이 의미 없는 결과(예: 0에 가까운 값)가 될 수 있다.
2.4 자세 잔차
자세 추정에서 잔차를 쿼터니언으로 표현할 때, 부호 일관성이 필요하다.
2.5 시간 시퀀스
자세 시퀀스에서 연속적 쿼터니언이 부호 점프를 겪으면, 보간이나 미분이 비매끄럽게 된다.
3. 부호 모호성 해결 방법
3.1 방법 1: 표준 형태 정규화
가장 단순한 방법은 모든 쿼터니언을 표준 형태로 정규화하는 것이다.
3.1.1 q_w \geq 0 규약
스칼라 부분이 양수가 되도록 부호를 조정한다.
if q.w < 0:
q = -q
이는 쿼터니언이 4차원 단위 구면의 “상반구“에 속하도록 한다.
3.1.2 한계
q_w = 0인 경우(180도 회전)에는 여전히 모호성이 남는다. 이 경우 벡터 부분의 다른 기준(예: q_x \geq 0)을 사용하여 추가 정규화한다.
3.2 방법 2: 이웃 값과의 연속성
시간 시퀀스에서는 이전 쿼터니언과 가까운 부호를 선택한다.
function correct_sign(q_prev, q_new):
if dot(q_prev, q_new) < 0:
return -q_new
else:
return q_new
이 방법은 연속적인 쿼터니언이 4차원 공간에서 점프 없이 매끄럽게 변하도록 보장한다.
3.3 방법 3: 내적 기반 보정
두 쿼터니언을 비교할 때 내적의 부호를 사용한다.
function close(q1, q2, epsilon):
return abs(dot(q1, q2)) > 1 - epsilon
내적의 절댓값이 사용되므로 부호 이중성이 자동으로 처리된다.
4. 보간에서의 부호 처리
4.1 SLERP에서의 부호 보정
SLERP 알고리즘의 첫 단계에서 부호 보정이 필요하다.
function slerp(q1, q2, t):
cos_omega = dot(q1, q2)
if cos_omega < 0:
q2 = -q2
cos_omega = -cos_omega
# ... 나머지 SLERP 계산
이렇게 하면 보간이 항상 짧은 경로를 따른다.
4.2 NLERP에서의 부호 처리
NLERP도 같은 보정이 필요하다.
function nlerp(q1, q2, t):
if dot(q1, q2) < 0:
q2 = -q2
result = (1 - t) * q1 + t * q2
return normalize(result)
5. 평균 계산에서의 부호 처리
5.1 단순 평균
여러 쿼터니언의 단순 평균은 부호 일관성이 필요하다.
function average(quaternions):
# 첫 쿼터니언을 기준으로 부호 보정
q_ref = quaternions[0]
sum_q = Quaternion(0, 0, 0, 0)
for q in quaternions:
if dot(q_ref, q) < 0:
sum_q += -q
else:
sum_q += q
return normalize(sum_q / len(quaternions))
이 방법은 작은 회전 차이가 있는 자세들에 대해 잘 작동한다.
5.2 고유값 기반 평균
더 정확한 쿼터니언 평균은 고유값 분해를 사용한다. N개의 쿼터니언에 대해 4 \times 4 대칭 행렬을 구성한다.
\mathbf{M} = \sum_{i=1}^N \mathbf{q}_i\mathbf{q}_i^T
평균은 \mathbf{M}의 가장 큰 고유값에 해당하는 고유 벡터이다. 이 방법은 부호 이중성을 자동으로 처리한다.
6. 자세 비교에서의 부호 처리
6.1 방법 1: 내적의 절댓값
두 쿼터니언이 같은 회전을 나타내는지 확인한다.
\text{same rotation if } \lvert\mathbf{q}_1\cdot\mathbf{q}_2\rvert \approx 1
6.2 방법 2: 회전 행렬 비교
두 쿼터니언을 회전 행렬로 변환한 후 비교한다. 회전 행렬은 유일하므로 모호성이 없다.
R1 = quaternion_to_matrix(q1)
R2 = quaternion_to_matrix(q2)
return matrix_close(R1, R2)
6.3 방법 3: 차이 회전의 크기
차이 회전의 각도가 0에 가까우면 같은 회전이다.
diff = q1.inverse() * q2
angle = 2 * atan2(norm(diff.v), abs(diff.w))
return angle < epsilon
abs(diff.w)를 사용하여 부호 이중성을 처리한다.
7. 시간 시퀀스에서의 부호 처리
7.1 부호 추적
자세 시퀀스를 처리할 때 각 새 쿼터니언의 부호를 이전 쿼터니언과 일관되도록 보정한다.
function process_sequence(quaternions):
result = [quaternions[0]]
for i in range(1, len(quaternions)):
q_new = quaternions[i]
if dot(result[-1], q_new) < 0:
q_new = -q_new
result.append(q_new)
return result
이 방법은 시각적으로 매끄러운 자세 시퀀스를 보장한다.
7.2 부호 점프의 검출
자동화된 시스템에서 부호 점프를 검출할 수 있다.
function detect_sign_jump(q1, q2):
return dot(q1, q2) < 0
점프가 감지되면 부호 보정이 필요함을 알려준다.
8. 자세 추정에서의 부호 처리
8.1 쿼터니언 기반 칼만 필터
칼만 필터에서 자세 갱신 시 부호 일관성이 필요하다. 새 측정값이 이전 추정과 부호가 반대일 수 있으므로 내적 검사가 필수이다.
8.2 오류 상태 칼만 필터
ESKF에서 오차 상태는 작은 회전 벡터로 표현된다. 이는 항상 \mathbf{q} 근처에 있으므로 부호 이중성 문제가 거의 발생하지 않는다. 그러나 큰 갱신에서는 주의가 필요하다.
9. 쿼터니언 미분에서의 부호 처리
쿼터니언이 시간에 따라 변할 때, 부호 점프가 발생하지 않아야 한다. 부호 점프가 있으면 미분이 비매끄럽게 된다.
9.1 부호 정규화 후 미분
미분 계산 전에 쿼터니언을 부호 정규화한다. 이는 일관된 미분을 보장한다.
10. 라이브러리의 부호 처리
10.1 Eigen
Eigen의 쿼터니언 클래스는 자동으로 부호 정규화를 수행하지 않는다. 사용자가 필요 시 수행해야 한다.
10.2 ROS의 tf2
tf2는 일부 연산(예: 보간)에서 부호 보정을 자동으로 수행한다.
10.3 SciPy
SciPy의 Rotation 클래스는 쿼터니언 입력을 내부적으로 표준 형태로 변환한다.
11. 코드 구현의 권장 사항
11.1 입력 검증
쿼터니언을 입력받을 때 노름이 1인지, 부호가 표준 형태인지 확인한다.
function validate_quaternion(q):
assert abs(norm(q) - 1) < epsilon
if q.w < 0:
q = -q
return q
11.2 함수의 일관성
쿼터니언을 입력/출력으로 사용하는 함수는 부호 처리에 대한 관례를 명시적으로 지정한다.
11.3 테스트
부호 이중성을 고려한 테스트를 작성한다. \mathbf{q}와 -\mathbf{q}에 대해 같은 결과가 나와야 한다.
12. 부호 모호성의 회피 전략
12.1 내부 표현의 변경
일부 응용에서는 부호 모호성을 피하기 위해 내부 표현을 변경한다.
- 축-각도: 부호 모호성 없음(180도 회전 이중성만 있음)
- 회전 행렬: 부호 모호성 없음
- 오일러 각: 부호 모호성 없음(단, 짐벌 락 있음)
12.2 표준 규약의 강제
시스템 전체에서 쿼터니언의 표준 형태(예: q_w \geq 0)를 강제한다. 모든 함수가 이 규약을 따르면 모호성이 감소한다.
12.3 문서화
라이브러리와 API에서 쿼터니언의 부호 처리 관례를 명확히 문서화한다.
13. 부호 이중성의 유용한 측면
부호 이중성은 단점처럼 보이지만 일부 유용한 성질이 있다.
13.1 연속성 향상
시간 시퀀스에서 부호 점프를 허용하면 쿼터니언 공간이 더 매끄럽게 연결된다. 이는 회전 미분과 적분에서 유용할 수 있다.
13.2 대칭성
부호 이중성은 쿼터니언 공간의 대칭성을 나타내며, 군 이론적 분석에서 유용하다.
13.3 보간의 선택
짧은 경로와 긴 경로를 선택할 수 있는 유연성을 제공한다. 일부 응용(예: 한 바퀴 이상의 회전이 필요한 경우)에서는 긴 경로가 유용할 수 있다.
14. 결론
쿼터니언의 부호 모호성은 S^3에서 SO(3)으로의 이중 피복 사상의 필연적 결과이다. 이를 제거할 수는 없지만, 표준 형태 정규화, 내적 기반 보정, 시간 연속성 추적 등의 방법으로 일관되게 처리할 수 있다. 쿼터니언을 사용하는 모든 응용에서 부호 처리에 대한 명확한 정책을 수립하고 일관되게 적용하는 것이 중요하다.
15. 참고 문헌
- Kuipers, J. B. (1999). Quaternions and Rotation Sequences. Princeton University Press.
- Sola, J. (2017). “Quaternion Kinematics for the Error-State Kalman Filter.” arXiv:1711.02508.
- Diebel, J. (2006). “Representing Attitude: Euler Angles, Unit Quaternions, and Rotation Vectors.” Stanford University Technical Report.
- Markley, F. L., Cheng, Y., Crassidis, J. L., & Oshman, Y. (2007). “Averaging Quaternions.” Journal of Guidance, Control, and Dynamics, 30(4), 1193–1197.
- Shoemake, K. (1985). “Animating Rotation with Quaternion Curves.” SIGGRAPH Computer Graphics, 19(3), 245–254.
version: 1.0