상태: 초안 (2026-10-18), 실측. 숫자는 노트북(Apple M1 Max, macOS 26.5)의 Python 3.9.6·numpy 2.0.2 로 직접 계산했습니다. 시간은 7회 반복의 중앙값(첫 회 버림)이고, 수치해의 시간은 성공한 풀이 300개의 중앙값입니다. 원자료와 코드: 작업 디렉터리
measure/robot-arm-basics/의arm.py,m04_ik.py,out/m04_ik.json. 예제 팔은 3편의 가상 설계이며 하드웨어 실측은 없습니다. 참고 자료는 2026-10-18 에 열람했습니다. 작성 규칙: 실측 데이터가 기본이고, 못 잰 것은 「미실측」, 확인하지 못한 것은 「미확인」으로 표시합니다.
목차
1. 직관: 컵을 잡는 팔의 모양은 여러 가지
책상 위 컵을 잡을 때 팔꿈치를 옆으로 벌릴 수도, 몸에 붙일 수도 있습니다. 손의 위치와 방향은 같은데 팔의 모양이 다릅니다. 반대로 책상 끝 너머의 컵은 어떤 모양으로도 잡을 수 없습니다. 역기구학(inverse kinematics, IK)의 세 가지 사정이 여기 다 들어 있습니다.
- 해가 여러 개일 수 있다.
- 해가 없을 수 있다.
- 해가 있어도 어떤 자세 근처에서는 관절을 아주 크게 움직여야 라켓이 조금 움직인다(특이점).
탁구 로봇에서 역기구학은 매 타구마다, 그리고 예측이 고쳐질 때마다 다시 풀립니다. 빠르고, 항상 끝나고, 이전 자세에서 갑자기 튀지 않는 해를 내야 합니다.
2. 그림: 같은 목표, 두 해
3. 계산
3.1 2링크 팔: 코사인 법칙
어깨에서 목표까지의 거리를 r 이라 하면, 링크 두 개와 r 이 삼각형을 이룹니다. 코사인 법칙으로 팔꿈치 각이 나옵니다.
def ik2(x, y, elbow=+1):
c = (x*x + y*y - L1*L1 - L2*L2) / (2*L1*L2)
if abs(c) > 1:
return None # 닿지 않는 목표
q2 = elbow * acos(c) # +: 팔꿈치 아래, -: 팔꿈치 위
q1 = atan2(y, x) - atan2(L2*sin(q2), L1 + L2*cos(q2))
return q1, q2
acos 가 ± 두 값을 주므로 해가 둘입니다. |c| > 1 이면 삼각형이 만들어지지 않으므로 해가 없습니다. 판정이 한 줄이라는 점이 해석해의 큰 장점입니다.
3.2 6축 팔: 손목을 떼어 내기
3편의 예제 팔은 손목 세 축이 한 점에서 만납니다. 그래서 6개 미지수를 두 단계로 나눌 수 있습니다.
- 위치 3개. 라켓 자세에서 손목 중심 p_c = p − d6·R[:, 2] 를 구합니다. 1번 관절은 p_c 를 위에서 본 방향 atan2(y_c, x_c) 이거나 그 반대(+π)입니다. 그러면 2·3번 관절은 3.1 절의 2링크 문제가 되어 팔꿈치 위·아래 두 해가 나옵니다.
- 방향 3개. 1·2·3번 관절이 정해지면 R₀₃ 를 알 수 있고, 손목이 맡을 나머지 회전은 R₃₆ = R₀₃ᵀ·R 입니다. 이 손목 구조는 ZYZ 오일러 각과 같은 꼴이라 θ5 = atan2(±√(r13² + r23²), r33) 로 두 해(손목 뒤집기)가 나옵니다.
2 × 2 × 2 = 8개 해입니다. θ5 = 0 이면 4번과 6번 축이 일직선이 되어 θ4 + θ6 만 정해집니다. 이것이 손목 특이점입니다.
3.3 수치해: 뉴턴법과 감쇠 최소제곱
손목이 한 점에서 만나지 않는 팔이나 7축 이상의 팔은 닫힌 해가 없거나 너무 복잡합니다. 그때는 정기구학과 야코비안(5편)만으로 반복해서 풉니다. 자세 오차 e(위치 3 + 방향 3)를 줄이는 관절 변화 Δq 를 구하는 방법이 세 가지 있습니다.
유사역행렬(뉴턴-랩슨): Δq = J⁺ e
감쇠 최소제곱(DLS): Δq = Jᵀ (J Jᵀ + λ² I)⁻¹ e ‖J Δq − e‖² + λ²‖Δq‖² 를 최소화
야코비안 전치: Δq = α Jᵀ e, α = ⟨e, J Jᵀ e⟩ / ‖J Jᵀ e‖²
Modern Robotics 6.2.1 절이 뉴턴-랩슨을, Buss 의 튜토리얼이 세 방법을 함께 정리합니다. DLS 는 Levenberg–Marquardt 라고도 부릅니다. 특이값으로 보면 DLS 는 각 방향의 이득을 σ/(σ² + λ²) 로 바꿉니다. σ 가 λ 보다 크면 유사역행렬과 같고, σ 가 0 으로 가면 이득도 0 으로 갑니다. 특이점 근처에서 관절이 폭주하지 않게 하는 장치입니다.
for it in range(max_iter):
e = pose_error(fk_dh(q), T_goal) # 위치 오차 3 + 축-각 방향 오차 3
if norm(e[:3]) < 1e-5 and norm(e[3:]) < 1e-4: # 0.01 mm, 0.006°
return q, True
J = jacobian(q)
dq = J.T @ np.linalg.solve(J @ J.T + lam**2 * np.eye(6), e)
q = q + dq
3.4 2축 직교 갠트리: 역기구학이 덧셈인 구조
라켓을 2축 직교 갠트리(가로 x, 세로 z)에 달고 그 끝에 요·피치 2축 손목을 두면 역기구학은 다음이 전부입니다.
손목 요 ψ = atan2(n_x, n_y) (n 은 원하는 라켓 법선)
손목 피치 φ = atan2(n_z, √(n_x² + n_y²))
손목 중심 = 라켓 중심 − d · n
갠트리 x = 손목 중심 x, 갠트리 z = 손목 중심 z
해가 하나뿐이고, 갠트리 축의 야코비안은 상수(단위 행렬)라 특이점이 없습니다. 라켓 속도도 자세와 상관없이 축 속도 그대로 나옵니다. 대신 손목 중심이 갠트리 평면 위에 있어야 하므로 라켓 중심의 y(탁구대 길이 방향)는 「갠트리 평면 + d·n_y」 로 묶입니다. 즉 타격점이 거의 한 평면에 고정됩니다. Koç 외 2018 은 이런 고정 가상 타격 평면이 궤적을 제한해 반환율을 떨어뜨린다고 보고했습니다(실기에서 고정 평면 약 10~40%, 타격 시각·위치를 함께 최적화한 방식 약 40~60%). 그래서 Google 의 시스템처럼 갠트리 위에 6축 팔을 올려 둘의 장점을 함께 쓰는 설계가 나옵니다.
4. 실측
4.1 해석해: 정확도와 시간
| 문제 | 표본 | 최대 위치 오차 | 최대 방향 오차 | 한 번 시간 |
|---|---|---|---|---|
| 2링크 평면(두 해) | 목표 100,000개 | 6.9×10⁻¹⁶ m | - | 0.59 µs |
| 6축 손목 분리(8개 해) | 자세 10,000개 | 1.1×10⁻¹⁵ m | 9.4×10⁻¹⁴ rad | 58 µs |
| 2축 갠트리 + 2축 손목 | - | (정의상 정확) | - | 0.61 µs |
6축 자세 10,000개 모두에서 8개 해가 나왔고, 8개 모두를 정기구학에 넣어 원래 자세가 다시 나오는지 확인했습니다. 무작위 관절 각으로 만든 자세라 처음 관절 각도 항상 8개 해 가운데 하나로 돌아왔습니다(차이 최대 6.7×10⁻¹² rad).
4.2 수치해: 방법별 성공률과 시간
무작위 관절 각으로 목표 자세 300개를 만들고, 두 가지 출발점에서 풀었습니다. 「근처」는 정답 관절 각에 표준편차 0.3 rad 잡음을 더한 출발점, 「준비 자세」는 모든 목표에 같은 고정 자세입니다. 최대 200번 반복, 성공 기준은 위치 0.01 mm·방향 10⁻⁴ rad 입니다.
| 방법 | 출발 | 성공률 | 반복 중앙/95% | 시간 중앙 | 한 걸음 최대(중앙) |
|---|---|---|---|---|---|
| 유사역행렬 | 근처 | 99.7% | 4 / 23 | 0.77 ms | 0.92 rad |
| 유사역행렬 | 준비 자세 | 99.3% | 16 / 45 | 2.5 ms | 61 rad |
| 유사역행렬 + 걸음 0.3 rad 제한 | 준비 자세 | 99.7% | 23 / 41 | 3.8 ms | 0.3 rad |
| DLS λ=0.01 | 준비 자세 | 95.7% | 16 / 41 | 2.3 ms | 16 rad |
| DLS λ=0.05 | 준비 자세 | 86.7% | 16 / 87 | 2.6 ms | 8.6 rad |
| DLS λ=0.1 | 준비 자세 | 80.0% | 23 / 146 | 3.5 ms | 5.5 rad |
| DLS λ=0.01 + 걸음 제한 | 준비 자세 | 97.7% | 24 / 46 | 3.5 ms | 0.3 rad |
| 야코비안 전치 | 준비 자세 | 1.3% | 130 / 184 | 17 ms | 1.3 rad |
예상과 다른 결과가 둘 있었습니다.
- 감쇠를 크게 할수록 성공률이 떨어졌습니다. λ 가 크면 특이점에서 안전한 대신 정상 자세에서도 걸음이 줄어 200번 안에 0.01 mm 까지 가지 못한 경우가 늘었습니다. 위치(m)와 방향(rad)을 한 벡터에 섞어 같은 λ 를 쓰는 것도 원인일 것으로 봅니다(추정). Buss 도 λ 는 특이점에서 버틸 만큼 크고 수렴이 느려지지 않을 만큼 작아야 한다고만 적고 값은 주지 않습니다.
- 유사역행렬은 대부분 결국 수렴하지만, 가는 길에 한 걸음 61 rad 를 뛰기도 했습니다. 계산 안에서는 문제가 없지만, 이 중간값을 그대로 모터에 보내면 사고입니다. 실제로는 걸음 크기를 제한하거나(표의 「걸음 제한」), 수렴한 마지막 해만 궤적 생성기(8편)에 넘깁니다.
야코비안 전치는 계산이 가장 싸지만 수렴이 너무 느려 200번 안에 거의 끝나지 않았습니다. 해석해(58 µs)는 준비 자세에서 출발한 수치해(2.3 ms 이상)보다 약 40배, 정답 근처에서 출발한 수치해(0.7 ms)보다도 12배 빨랐습니다. 수치해는 출발점에 따라 8개 해 가운데 어느 해로 갈지 모른다는 점도 기억해야 합니다. 로봇에서는 지금 관절 각에서 출발해 가까운 해로 가게 하고, 해석해가 있으면 8개 가운데 지금 자세에 가장 가까운 해를 고릅니다.
4.3 특이점 근처의 한 걸음
자세 오차(위치 1 mm 쯤, 방향 0.01 rad 쯤)를 고치려는 한 걸음의 크기를 자세별로 비교했습니다.
| 자세 | 최소 특이값 σ_min | 조건수 | 유사역행렬 걸음 | DLS λ=0.05 걸음 | DLS 걸음 뒤 남은 오차 |
|---|---|---|---|---|---|
| 보통 자세 | 0.055 | 35 | 0.042 rad | 0.030 rad | 0.0009 |
| 손목 θ5 = 0.01 rad | 0.0020 | 977 | 1.77 rad | 0.034 rad | 0.0036 |
| 손목 θ5 = 0.001 rad | 0.0002 | 9,768 | 17.6 rad | 0.034 rad | 0.0036 |
| 팔꿈치 거의 폄(θ3 = π/2 + 0.001) | 0.00015 | 13,041 | 12.9 rad | 0.023 rad | 0.0019 |
특이점 근처에서 유사역행렬은 오차 0.01 을 고치려고 관절을 두세 바퀴 돌리라고 합니다. DLS 는 걸음을 0.03 rad 로 묶는 대신 오차의 일부(위 표의 남은 오차)를 포기합니다. 「정확히 맞추기」와 「얌전히 움직이기」를 맞바꾸는 것이고, 실제 로봇은 거의 항상 후자를 고릅니다.
4.4 닿지 않는 목표
2링크 팔(닿는 한계 0.75 m)에 0.85 m 떨어진 목표를 주고 50번 반복했습니다. 가능한 가장 가까운 거리는 0.10 m 입니다.
| 방법 | 마지막 거리 | 가장 가까웠던 거리 | 최대 걸음 | 마지막 다섯 걸음 |
|---|---|---|---|---|
| 유사역행렬 | 0.139 m | 0.100 m | 33.7 rad | 1.2, 2.6, 1.6, 1.3, 1.4 rad(계속 출렁임) |
| DLS λ=0.05 | 0.145 m | 0.104 m | 1.10 rad | 매번 1.05 rad(제자리 왕복) |
| DLS λ=0.2 | 0.100 m | 0.100 m | 0.36 rad | 10⁻¹⁰ rad(멈춤) |
해가 없으면 유사역행렬은 끝없이 출렁이고, 작은 λ 의 DLS 도 같은 두 자세 사이를 오갑니다. λ 를 키우면 「가장 가까운 자세」에 얌전히 멈춥니다. Buss 는 이 상황에서 오차 벡터의 크기를 링크 길이의 절반쯤으로 잘라 주면 작은 λ 로도 진동이 줄어든다고 적었습니다. 탁구 로봇에서는 이것이 「공이 작업 공간 밖으로 온다」는 흔한 상황이므로, 해가 없음을 먼저 판정하는 해석해가 특히 값집니다.
5. 한계
- 관절 각 한계(예: ±170°)와 자기 충돌을 역기구학 안에서 다루지 않았습니다. 5편에서 해를 고를 때만 관절 한계를 걸었습니다.
- DLS 의 λ 를 고정값으로만 비교했습니다. σ_min 에 따라 λ 를 바꾸는 방법과 위치·방향 오차의 단위를 맞추는 가중치는 재지 않았습니다(미실측).
- 수치해의 시간은 파이썬에서 매 반복 정기구학과 야코비안을 다시 계산하는 비용이 대부분입니다. C++ 구현의 시간은 미실측입니다.
6. 정리
- 2링크는 코사인 법칙, 6축 구형 손목 팔은 손목 분리로 닫힌 해를 얻습니다. 해석해는 해의 개수와 「해 없음」을 한 번에 알려 줍니다.
- 수치해는 어느 팔에나 쓰지만, 출발점에 따라 다른 해로 가고 중간에 큰 걸음을 낼 수 있습니다. 걸음 제한과 감쇠가 필요합니다.
- 특이점 근처에서 DLS 는 정확도를 조금 내주고 관절 폭주를 막습니다. 닿지 않는 목표에서는 충분히 큰 λ 가 가장 가까운 자세에 멈춥니다.
- 갠트리의 역기구학은 덧셈이고 특이점이 없지만, 타격점이 한 평면에 묶입니다.
티티 한마디. 같은 공을 치는 팔 모양이 여덟 가지나 있어요. 그중에서 지금 자세에 제일 가까운 걸 고르는 게 요령이고, 닿지 않는 공이면 억지로 쫓지 말고 제일 가까운 데서 멈춰야 해요!
참고
모든 자료는 2026-10-18 에 열람했습니다.
- Lynch, Park, Modern Robotics, 2017, 공개 프리프린트, 6장(6.1 해석적 IK, 6.2.1 Newton–Raphson).
- Buss, S. R., Introduction to Inverse Kinematics with Jacobian Transpose, Pseudoinverse and Damped Least Squares methods(PDF 표기 2009-10-07), 3~6절.
- Koç, Maeda, Peters, Online optimal trajectory generation for robot table tennis, RAS 105 (2018), 저자 공개본, 그림 2·11.
- D'Ambrosio 외, arXiv:2408.03906, II-A 절.