상태: 초안 (2026-10-18), 실측. 숫자는 노트북(Apple M1 Max, macOS 26.5)의 Python 3.9.6·numpy 2.0.2 로 직접 계산했습니다. 시간은 7회 반복의 중앙값(첫 회 버림)입니다. 원자료와 코드: 작업 디렉터리
measure/robot-arm-basics/의arm.py,m03_fk.py,out/m03_fk.json. 예제 팔은 가상의 설계이며 실제 로봇에서 잰 값은 없습니다(하드웨어 미실측). 참고 자료는 2026-10-18 에 열람했습니다. 작성 규칙: 실측 데이터가 기본이고, 못 잰 것은 「미실측」, 확인하지 못한 것은 「미확인」으로 표시합니다.
목차
1. 직관: 쉬운 방향부터
팔의 관절 각을 모두 알면 라켓이 어디에 있는지는 하나로 정해집니다. 어깨에서 팔꿈치까지 자를 대고, 팔꿈치에서 손목까지 다시 자를 대는 일을 반복하면 됩니다. 이것이 정기구학(forward kinematics)입니다. 답이 항상 하나이고 계산이 짧습니다.
반대 방향, 즉 「라켓을 저기에 저 각도로 두려면 관절을 몇 도로 해야 하나」는 답이 여럿이거나 없을 수 있어 훨씬 어렵습니다. 그것이 4편의 역기구학입니다. 정기구학을 먼저 정확하게 세워 두어야 역기구학의 답을 검산할 수 있습니다.
2. 그림: 이 시리즈의 예제 팔
예제 팔은 사람 팔과 비슷한 구조입니다.
- 1번 관절은 수직축을 도는 어깨 요, 2·3번은 같은 방향으로 나란한 어깨 피치와 팔꿈치 피치입니다. 이 셋이 라켓의 위치를 맡습니다.
- 4·5·6번은 세 축이 한 점에서 만나는 구형 손목(spherical wrist)입니다. 이 셋이 라켓의 방향을 맡습니다. 세 축이 만나는 점을 손목 중심이라 부릅니다.
- 길이는 d1 = 0.30, a2 = 0.40, d4 = 0.35, d6 = 0.15 m 입니다. d6 은 손목 중심에서 라켓 면 중심까지입니다. 팔을 쭉 펴면 어깨에서 손목 중심까지 0.75 m 입니다.
오픈하드웨어로는 이 구조 대신 2축 직교 갠트리 위에 2~3축 손목을 올리는 설계도 유력한 후보입니다. Google DeepMind 의 시스템도 6축 산업용 팔을 2축 선형 갠트리 위에 올렸습니다(arXiv:2408.03906 II-A 절). 갠트리는 정기구학과 역기구학이 거의 덧셈뿐이라 4편에서 장점을 따로 계산합니다.
3. 계산
3.1 2링크 평면 팔
링크 길이 L1, L2, 관절 각 q1, q2 인 평면 팔의 끝점은 다음과 같습니다.
x = L1·cos q1 + L2·cos(q1 + q2)
y = L1·sin q1 + L2·sin(q1 + q2)
이 식은 4편의 역기구학, 5편의 야코비안, 9편의 동역학에서 모두 출발점이 됩니다. 예제 팔의 2·3번 관절이 만드는 평면 문제가 바로 이것입니다.
3.2 DH 파라미터
관절이 여섯 개면 좌표계를 여섯 번 이어 붙여야 합니다. DH(Denavit–Hartenberg) 관례는 링크마다 숫자 네 개만으로 다음 좌표계를 정의합니다.
| 기호 | 뜻 |
|---|---|
| θ_i | z 축을 도는 각(회전 관절이면 이것이 관절 변수) |
| d_i | z 축 방향 이동 |
| a_i | 새 x 축 방향 이동(링크 길이) |
| α_i | 새 x 축을 도는 각(다음 관절 축의 비틀림) |
이 글은 「z 축으로 θ 돌고 d 가고, x 축으로 a 가고 α 돈다」는 순서(흔히 표준 DH 라 부름)를 씁니다. 교과서에 따라 순서와 첨자를 달리 쓰는 수정 DH 도 있습니다. Modern Robotics 의 부록 C 는 α_{i−1}, a_{i−1}, d_i, φ_i 순서로 정의합니다. 같은 팔이라도 관례가 다르면 표의 숫자가 달라지므로, 표를 남에게 받으면 관례부터 확인해야 합니다.
def dh_T(a, alpha, d, th): # 표준 DH: Rz(θ)·Tz(d)·Tx(a)·Rx(α)
ct, st, ca, sa = cos(th), sin(th), cos(alpha), sin(alpha)
return np.array([[ct, -st*ca, st*sa, a*ct],
[st, ct*ca, -ct*sa, a*st],
[0, sa, ca, d ],
[0, 0, 0, 1.0 ]])
def fk_dh(q):
T = np.eye(4)
for (a, alpha, d), qi in zip(DH, q):
T = T @ dh_T(a, alpha, d, qi)
return T # 라켓 좌표계 {E} 를 로봇 바닥 {B} 에서 본 4×4
3.3 지수 곱(PoE)
DH 는 링크마다 좌표계를 정해야 하고, 그 정하는 규칙이 까다롭습니다. 지수 곱(product of exponentials, PoE) 공식은 좌표계를 두 개만 씁니다. 바닥 좌표계와, 모든 관절이 0 일 때의 라켓 자세 M 입니다. 그리고 관절 하나하나를 「어떤 축을 중심으로 도는 나선 운동(screw motion)」으로 봅니다.
T(q) = e^[S1]q1 · e^[S2]q2 · … · e^[S6]q6 · M
S_i = (ω_i, v_i), ω_i = 관절 축 방향 단위 벡터, v_i = −ω_i × p_i (p_i 는 축 위의 아무 점)
모든 S_i 와 M 은 영 자세 한 장만 보고 적을 수 있습니다. Modern Robotics 4장의 공간 형식 PoE 식(4.14)이 이것이고, 같은 책은 링크 좌표계가 필요 없다는 점을 장점으로 듭니다. 지수 행렬은 로드리게스 식으로 닫힌 꼴이 있습니다.
def exp6(S, th):
w, v = S[:3], S[3:]
W = skew(w)
R = np.eye(3) + sin(th)*W + (1 - cos(th))*W@W
G = np.eye(3)*th + (1 - cos(th))*W + (th - sin(th))*W@W
T = np.eye(4); T[:3, :3] = R; T[:3, 3] = G @ v
return T
이 시리즈의 코드는 S_i 와 M 을 손으로 적지 않고, DH 표로 영 자세의 좌표계를 계산한 뒤 각 관절의 z 축과 원점에서 뽑았습니다. 그러면 두 방법이 같은 팔을 나타내는지 바로 검산할 수 있습니다.
3.4 구형 손목과 손목 중심
손목 세 축이 한 점에서 만나면 좋은 일이 생깁니다. 4·5·6번 관절이 아무리 돌아도 손목 중심의 위치는 변하지 않습니다. 손목 중심은 1·2·3번 관절만으로 정해지고, 라켓 자세에서 손목 중심을 거꾸로 구하는 것도 간단합니다.
손목 중심 = 라켓 중심 − d6 · (라켓 법선 방향, 곧 R 의 셋째 열)
4편은 이 성질로 6축 역기구학을 「위치 3개」와 「방향 3개」로 쪼개어 닫힌 식으로 풉니다.
4. 실측
4.1 DH 와 PoE 는 같은 답을 내는가
관절 각을 −π 에서 π 사이에서 무작위로 10,000번 뽑아 두 함수의 4×4 결과를 원소별로 비교했습니다.
| 항목 | 값 |
|---|---|
| 최대 원소 차 | 5.6×10⁻¹⁶ |
| 영 자세 M(위치) | (0.40, 0, −0.20) m, 라켓 법선은 아래(−z) |
차이는 float64 의 반올림 수준입니다. 영 자세에서 라켓이 바닥보다 아래(−0.20 m)에 있는 것은 팔꿈치 각 0 이 아래팔을 수직으로 내린 자세이기 때문입니다. 실제 로봇에서는 이 「0 의 뜻」을 엔코더 영점과 맞추는 일이 보정의 첫 단계입니다(4.3 절).
4.2 계산 시간
| 계산 | 한 번(µs) |
|---|---|
| 2링크 평면 닫힌 식(순수 파이썬) | 0.41 |
| 6축 DH(numpy 4×4 곱 6번) | 15.2 |
| 6축 PoE(numpy, 지수 행렬 6개) | 71.7 |
| 6축 야코비안(5편, DH 좌표계에서) | 102.6 |
PoE 가 DH 보다 약 4.7배 느렸습니다. 관절마다 사인·코사인 외에 3×3 행렬 곱과 덧셈을 여러 번 하기 때문입니다. 1 kHz 제어 주기는 1,000 µs 이므로 파이썬에서도 둘 다 충분히 빠릅니다. 마이크로컨트롤러로 옮길 때는 DH 처럼 미리 전개한 식이 유리할 것으로 봅니다(미실측).
4.3 작은 오차는 라켓 끝에서 얼마가 되나
정기구학이 정확해도 팔의 실제 치수와 엔코더가 틀리면 소용없습니다. 오차 네 가지를 넣고 무작위 자세 5,000개에서 라켓 중심 위치와 라켓 법선 방향이 얼마나 어긋나는지 쟀습니다.
| 오차 원인 | 위치 오차 중앙/95% | 법선 방향 오차 중앙/95% |
|---|---|---|
| 링크 길이 ±1 mm(균등, 관절마다 따로) | 0.98 / 1.94 mm | 0° |
| 관절 영점 ±0.1° | 0.62 / 1.43 mm | 0.09 / 0.19° |
| 엔코더 12비트(4,096 칸/회전) 양자화 | 0.27 / 0.65 mm | 0.04 / 0.08° |
| 엔코더 14비트(16,384 칸/회전) 양자화 | 0.07 / 0.16 mm | 0.01 / 0.02° |
- 링크 길이 오차는 위치만 바꾸고 방향은 바꾸지 않습니다. 길이는 각을 바꾸지 않기 때문입니다.
- 관절 영점 0.1° 는 위치로는 1 mm 안팎이지만 방향으로는 0.1~0.2° 입니다. 7편에서 라켓 법선이 1° 기울면 공의 착지점이 중앙값 6 cm 빗나간다고 잽니다. 영점 오차만으로 1 cm 안팎을 잃는 셈입니다.
- 14비트 엔코더면 양자화는 무시할 만합니다. 12비트도 위치는 충분하지만 방향 0.04° 가 누적 오차의 한 몫이 됩니다.
5. 한계
- 관절과 링크를 강체로 보았습니다. 벨트·감속기의 백래시와 탄성, 휘는 링크는 정기구학 밖의 오차이고 재지 않았습니다(미실측).
- 오차를 서로 독립인 균등 분포로 넣었습니다. 실제 보정 오차는 서로 얽혀 있어 크기가 다를 수 있습니다.
- Craig 와 Siciliano 외의 교과서가 어떤 DH 관례를 쓰는지는 본문을 열지 못해 확인하지 못했습니다(미확인).
6. 정리
- 정기구학은 관절 각에서 라켓 자세로 가는 쉬운 방향이고, 4·5·9편 모든 계산의 검산 도구입니다.
- DH 는 링크마다 숫자 네 개, PoE 는 영 자세 한 장과 관절 축 여섯 개로 같은 팔을 나타냅니다. 두 방법은 10⁻¹⁶ 수준으로 일치했습니다.
- 구형 손목은 손목 중심을 고정해 역기구학을 쪼갤 수 있게 해 줍니다.
- 하드웨어 관점에서는 엔코더 분해능보다 관절 영점 보정이 라켓 방향 오차에 더 크게 남습니다.
티티 한마디. 자를 여섯 번 대면 라켓 위치가 나와요. 그런데 자의 0 점이 0.1° 만 틀려도 공은 1 cm 쯤 다른 데로 가니까, 영점 맞추기를 꼭 먼저 해요!
참고
모든 자료는 2026-10-18 에 열람했습니다.
- Lynch, Park, Modern Robotics, 2017, 공개 프리프린트, 4장 정기구학(4.1 PoE, 식 4.14), 부록 C(DH 파라미터).
- D'Ambrosio 외, Achieving Human Level Competitive Robot Table Tennis, arXiv:2408.03906, II-A 절(팔과 갠트리 구성).
- Craig, Introduction to Robotics: Mechanics and Control 4판(Pearson), Siciliano 외, Robotics: Modelling, Planning and Control(Springer 2009): 출판사 장 목록만 확인, 본문 미확인.