제3부 동역학
3.2 뉴턴-오일러 재귀 알고리즘(RNEA)
3.2.1 이 장에서 배우는 것 / 선수 지식 / 특히 중요한 독자
이 장은 직렬 개연쇄(open chain) 로봇의 역동역학, 즉 관절 위치·속도·가속도에서 관절 토크를 구하는 뉴턴-오일러 재귀 알고리즘(recursive Newton-Euler algorithm, RNEA)을 다룬다. 링크의 속도와 가속도를 기저에서 끝으로 전달하는 전방 순환, 링크가 받는 렌치를 끝에서 기저로 전달해 관절 토크를 얻는 후방 순환, 중력을 기저 가속도로 처리하는 방법, 연산량이 관절 수에 선형으로 늘어나는 이유, RNEA 호출로 질량행렬 $M(q)$·바이어스 힘 $h(q,\dot q)$·중력항 $g(q)$·팁 렌치 대응 토크·관절 반력을 얻는 방법을 구현하고 확인한다. 링크 하나의 동역학은 3.1, 같은 식을 에너지에서 얻는 라그랑주 정식화는 3.3, 운동방정식의 성질은 3.4, 질량행렬과 순동역학의 효율적 알고리즘(CRBA·ABA)은 3.5, 라이브러리와 도함수는 3.6, 식별 회귀는 3.7, 계산 토크 제어는 12.5, 구속된 폐연쇄는 3.11, 부유 기저는 3.13와 이어진다.
배우는 것:
- 전방 순환 — $V_i=\mathrm{Ad}_{T_{i,i-1}}V_{i-1}+A_i\dot q_i$, 가속도 점화식과 $\mathrm{ad}$ 항의 유도, 중력의 기저 가속도 처리.
- 후방 순환 — $F_i=\mathrm{Ad}^{T}F_{i+1}+G_i\dot V_i-\mathrm{ad}_{V_i}^{T}G_iV_i$, $\tau_i=F_i^{T}A_i$, 관절이 전달하는 여섯 성분 가운데 토크 하나.
- 3차원 벡터 형태와의 동등성 — 고전적 재귀 식과 공간 형태가 같은 값을 낸다.
- 연산량 — 링크당 일정한 연산 $O(n)$, $M(q)$를 RNEA 열로 구성하면 $O(n^{2})$.
- RNEA의 사용 — $M$·$h$·$g$·$J^{T}F_{tip}$·관절 반력, 라이브러리 대조.
선수 지식: 1.10(트위스트·렌치·수반 표현), 2.4(PoE 순기구학), 2.8(물체 야코비안), 3.1(공간 관성·뉴턴-오일러 방정식).
특히 중요한 독자: 역동역학·계산 토크·중력 보상을 구현하는 제어 엔지니어, 동역학 라이브러리를 사용하거나 비교하는 개발자, 관절 반력으로 베어링·구조 하중을 검토하는 기구 설계자.
출처 방침. 기준 시점은 2026-11-05이다. 직접 읽은 자료: Lynch·Park, Modern Robotics(사전 인쇄본 2017-05판) 8.3절(뉴턴-오일러 역동역학: 유도와 알고리즘), 8.4절 앞부분(운동 에너지와 질량행렬의 합 $M=\sum J_{ib}^{T}G_iJ_{ib}$, 행렬 형태의 재귀)을 텍스트로 읽었다. MuJoCo 문서(계산 개관의 $M(q),\,c(q,v)$ 변수 표와
mj_inverse의 계산 순서)를 읽었다. 이 장의 식은 이 서술을 따르되 3차원 벡터 형태 재귀·라이브러리 5종과의 비교로 다시 확인했다. 서지만 확인한 것(Crossref로 실재를 확인했고 본문은 읽지 못했다): Orin·McGhee·Vukobratović·Hartoch(1979), Luh·Walker·Paul(1980), Hollerbach(1980), Walker·Orin(1982), Featherstone(2008), Carpentier 외(2019, Pinocchio), Todorov 외(2012, MuJoCo), Corke·Haviland(2021, Robotics Toolbox). 문헌에 적힌 연산량 차수와 곱셈 횟수는 읽지 않았으므로 이 장은 자기 구현의 횟수만 보고한다. 확인하지 못한 것: KDL·RBDL 등 이 장이 실행하지 않은 라이브러리. 링크 치수·질량은 모두 이 장이 정한 예시이며 어떤 제품의 제원이 아니다. 수치는 모두 이 장의 순수 파이썬 계산이다.
3.2.2 개념 — 두 번의 순환으로 관절 토크를 계산한다
결론부터 적으면 다음과 같다. 직렬 개연쇄의 링크 $i$의 운동은 앞선 링크 $i-1$의 운동에 관절 $i$의 운동을 더한 것이므로, 속도와 가속도는 기저에서 끝으로 순서대로 정해진다(전방 순환). 각 링크가 가속하려면 총 렌치가 링크의 관성 렌치와 같아야 하며(3.1), 링크 $i$가 받는 렌치는 관절 $i$가 전달하는 렌치에서 관절 $i+1$을 통해 다음 링크에 전달하는 렌치를 뺀 것이다. 따라서 링크 $n$에서 시작해 끝에서 기저로 렌치를 전달하면 모든 관절 렌치가 정해진다(후방 순환). 1자유도 관절은 여섯 성분 가운데 관절 축 방향 성분 하나만 구동기가 공급하고 나머지 다섯은 구조가 제공하므로 관절 토크는 $\tau_i=F_i^{T}A_i$이다. 링크당 연산이 일정하므로 전체가 $O(n)$이다. 중력은 기저가 $-g$로 가속한다고 두어 같은 순환에 넣는다. 결과는 행렬 $M(q)$를 만들지 않고도 $\tau=M(q)\ddot q+h(q,\dot q)$를 정확히 낸다.
이 장의 계산 결과를 미리 적으면 다음과 같다. ① 평면 2R의 닫힌 식(Modern Robotics 식 (8.9))과 RNEA가 $7.1\times10^{-15}$ N·m 안에서 같다. ② 3차원 벡터 재귀와 공간 형태가 $n=2\sim7$의 임의 사슬에서 $1.1\times10^{-13}$ 이하로 일치하고, 질량행렬 열 구성 $M\ddot q+h$가 RNEA와 $5.7\times10^{-14}$ 이하로 같으며 $M$이 대칭·양의 정부호이고 운동 에너지가 링크 에너지 합과 같다. ③ 팁 렌치 토크가 $J_b^{T}F_{tip}$와 $1.8\times10^{-15}$로 일치하고 중력만 있을 때 관절 1의 반력이 총중량과 $1.8\times10^{-13}$로 같다. ④ 곱셈 횟수가 링크당 $357$으로 일정하여 RNEA가 $357n$, $M(q)$ 열 구성이 $357n^{2}$이다. ⑤ Pinocchio·MuJoCo·modern_robotics·Robotics Toolbox와 $6.8\times10^{-13}$ 이하(modern_robotics 순동역학 왕복은 $2.3\times10^{-12}$)에서 같다. ⑥ 예제 6R 팔의 궤적에서 토크를 관성·속도곱·중력 항으로 분해하면 관절 2의 중력항 최댓값이 전체 최댓값의 $86\,\%$이다.
3.2.3 원리
3.2.3.1 사슬의 정의와 표기
기저를 프레임 $\{0\}$, 링크 $i$에 고정된 프레임을 $\{i\}$($i=1,\dots,n$)로 둔다. $\{i\}$는 관절 $i$의 프레임이며 질량 중심일 필요는 없다(Modern Robotics는 질량 중심에 두고, 이 장은 3.1의 일반 프레임 공간 관성 $G_i$를 사용하므로 URDF의 링크 프레임을 그대로 사용할 수 있다). $q=0$일 때 $\{i-1\}$의 $\{i\}$ 기준 자세를 $M_{i,i-1}$, 관절 $i$의 스크루 축(프레임 $\{i\}$ 성분, 성분 순서 $(\omega,v)$)을 $A_i$로 두면 자세는 다음이다.
$$T_{i,i-1}(q_i)=e^{-[A_i]q_i}M_{i,i-1}.$$
회전 관절은 $A_i=(\hat\omega,\ -\hat\omega\times r)$($r$은 축 위의 점), 직동 관절은 $A_i=(0,\hat v)$이다. 링크의 질량 특성은 프레임 $\{i\}$ 기준 공간 관성 $G_i$(3.1.3.6)이다. 입력은 $q,\dot q,\ddot q$, 기저 프레임 성분의 중력 벡터 $g$(중력항 $g(q)$와는 인자로 구분한다), 말단이 환경에 가하는 렌치 $F_{tip}$(프레임 $\{n\}$ 성분)이다.
3.2.3.2 전방 순환 — 속도와 가속도
링크 $i$의 트위스트는 링크 $i-1$의 트위스트를 $\{i\}$로 옮긴 것에 관절 속도 항을 더한 것이다. 기저는 정지($V_0=0$)로 두고 중력은 기저 가속도 $\dot V_0=(\dot\omega_0,\dot v_0)=(0,\,-g)$로 넣는다.
$$V_i=\mathrm{Ad}_{T_{i,i-1}}V_{i-1}+A_i\dot q_i,\qquad \dot V_i=\mathrm{Ad}_{T_{i,i-1}}\dot V_{i-1}+\mathrm{ad}_{V_i}(A_i)\,\dot q_i+A_i\ddot q_i.$$
가속도 식의 둘째 항은 $\mathrm{Ad}_{T_{i,i-1}}$의 시간 미분에서 나온다. $T_{i,i-1}=e^{-[A_i]q_i}M_{i,i-1}$이므로 $\frac{d}{dt}\mathrm{Ad}_{T_{i,i-1}}=-\mathrm{ad}_{A_i\dot q_i}\mathrm{Ad}_{T_{i,i-1}}$이고, $\mathrm{Ad}_{T_{i,i-1}}V_{i-1}=V_i-A_i\dot q_i$, $\mathrm{ad}_{A_i\dot q_i}(A_i\dot q_i)=0$, $\mathrm{ad}_XY=-\mathrm{ad}_YX$를 적용하면 $\frac{d}{dt}(\mathrm{Ad}_{T_{i,i-1}}V_{i-1})=\mathrm{Ad}_{T_{i,i-1}}\dot V_{i-1}+\mathrm{ad}_{V_i}(A_i)\dot q_i$가 된다(Modern Robotics 8.3.1의 유도와 같다). 중력을 기저 가속도로 넣는 것은 균일한 중력장에서 관성 질량과 중력 질량이 같다는 사실에 근거하며, 이 장은 중력 토크를 네 라이브러리와 비교해 확인했다. 기저가 실제로 움직이는 모바일 매니퓰레이터에서는 $V_0,\dot V_0$에 기저의 운동을 넣어야 하며, 이 장의 구현은 중력 인자(병진 가속)만 입력으로 열어 두었고 기저의 속도·각속도는 입력으로 받지 않는다(7.24, 3.13).
3.2.3.3 후방 순환 — 렌치와 관절 토크
링크 $i$가 받는 총 렌치는 관절 $i$를 통해 전달되는 렌치 $F_i$에서 관절 $i+1$을 통해 링크 $i+1$로 전달되는 렌치를 $\{i\}$로 옮긴 것을 뺀 값이고, 이것이 3.1의 단일 강체 식과 같다. 따라서 다음이 성립한다.
$$F_i=\mathrm{Ad}_{T_{i+1,i}}^{T}F_{i+1}+G_i\dot V_i-\mathrm{ad}_{V_i}^{T}\left(G_iV_i\right),\qquad \tau_i=F_i^{T}A_i,\qquad F_{n+1}\equiv F_{tip}.$$
$\tau_i=F_i^{T}A_i$는 관절 $i$의 상대 운동이 $A_i\dot q_i$뿐이어서 관절이 하는 일률이 $F_i^{T}A_i\dot q_i=\tau_i\dot q_i$이기 때문이다. $F_i$의 나머지 다섯 성분은 베어링과 구조가 지탱하는 구속 렌치이며 RNEA의 부산물로 얻어진다. 이 값이 베어링·구조 하중 검토의 입력으로 사용된다(4.2).
3.2.3.4 3차원 벡터 형태와의 동등성
고전적 재귀(Luh·Walker·Paul 1980이 정식화한 것으로 알려진 형태)는 같은 내용을 3차원 벡터로 적는다. 회전 관절, 관절 축이 $\hat z$인 프레임에서 각속도·각가속도·원점의 가속도를 $\omega_i=R_i^{T}\omega_{i-1}+\dot q_i\hat z$, $\dot\omega_i=R_i^{T}\dot\omega_{i-1}+R_i^{T}\omega_{i-1}\times\dot q_i\hat z+\ddot q_i\hat z$, $\dot v_i=R_i^{T}\left(\dot\omega_{i-1}\times P_i+\omega_{i-1}\times(\omega_{i-1}\times P_i)+\dot v_{i-1}\right)$로 전달하고, 질량 중심 가속도 $\dot v_{c}=\dot v_i+\dot\omega_i\times c_i+\omega_i\times(\omega_i\times c_i)$에서 $F_c=m_i\dot v_c$, $N_c=I_{c}\dot\omega_i+\omega_i\times I_{c}\omega_i$를 얻고, 후방으로 $f_i=R_{i+1}f_{i+1}+F_c$, $n_i=N_c+R_{i+1}n_{i+1}+c_i\times F_c+P_{i+1}\times R_{i+1}f_{i+1}$, $\tau_i=n_i^{T}\hat z$이다. 이 장은 위 식을 통상적으로 알려진 형태로 구현했으며 Luh 외의 원문을 읽지 않았다. 공간 형태와의 일치를 풀이 예제 ①의 둘째 표에서 확인했다. 공간 형태는 식의 개수가 적고 직동 관절·스크루 관절에 같은 식이 적용된다. 벡터 형태는 3차원 연산만 사용하므로 산술이 적을 것으로 예상되나 이 장은 두 형태의 연산량을 비교하지 않았다 (확인 필요).
3.2.3.5 연산량
전방·후방 순환은 링크마다 같은 수의 연산(행렬-벡터 곱과 벡터 합)만 수행하므로 총량이 $O(n)$이다. 이 장의 구현은 희소성을 사용하지 않고 $6\times6$ 행렬을 그대로 곱하며, 링크 한 개에 $357$번의 스칼라 곱셈(행렬-벡터·행렬-행렬 곱의 곱셈만 센 값)이 든다. $M(q)$는 $q$ 고정 상태에서 $\dot q=0$, $g=0$, $\ddot q=e_j$로 RNEA를 호출한 결과가 $j$번째 열이므로 $n$번의 호출, 즉 $357n^{2}$번의 곱셈이다. 가속도가 $q$에 대해 선형이라는 성질($M\ddot q$) 때문에 열 구성이 정확하다. 더 효율적인 질량행렬 알고리즘(CRBA)과 순동역학(ABA)은 3.5에서 다룬다. 문헌에 보고된 연산량 비교(예: 라그랑주 정식화는 $O(n^{4})$으로 알려져 있다)는 Hollerbach(1980)의 주제이며 이 장은 그 논문을 읽지 못했다 (확인 필요).
3.2.3.6 RNEA로 얻는 양
$g(q)=\tau(q,0,0)$ — 중력 보상 토크. $h(q,\dot q)=\tau(q,\dot q,0)$ — 코리올리·원심·중력의 합. $C(q,\dot q)\dot q=\tau(q,\dot q,0)\big|_{g=0}$. 관성항 $M\ddot q=\tau(q,0,\ddot q)\big|_{g=0}$. 정적 팁 렌치에 대응하는 토크는 $\dot q=\ddot q=0$, $g=0$에서 $\tau=J_b^{T}F_{tip}$이다(2.12의 정역학과 같다). 이 분해는 RNEA의 출력이 $\ddot q$에 대해 선형, $\dot q$에 대해 이차 형식, $g$에 대해 선형이라는 구조에서 나오며, 이 장은 세 호출의 합이 한 번의 호출 결과 $\tau$와 $9.8\times10^{-15}$ N·m 이내로 같음을 확인했다(예제 6R 팔의 궤적 151점).
3.2.4 알고리즘
입력: M[i]=M_{i,i−1}, A[i], G[i] (i=1..n), q, q̇, q̈, g, F_tip
초기화: V₀ ← 0; V̇₀ ← (0, −g)
전방 i = 1..n: T_{i,i−1} ← exp(−[A_i] q_i) · M_{i,i−1}
V_i ← Ad_{T_{i,i−1}} V_{i−1} + A_i q̇_i
V̇_i ← Ad_{T_{i,i−1}} V̇_{i−1} + ad_{V_i}(A_i) q̇_i + A_i q̈_i
후방 i = n..1: F_i ← F′_{i+1} + G_i V̇_i − ad_{V_i}ᵀ (G_i V_i) (F′_{n+1} ← F_tip)
τ_i ← F_iᵀ A_i; F′_i ← Ad_{T_{i,i−1}}ᵀ F_i ({i−1} 프레임으로 옮긴다)
M(q) 열 j ← RNEA(q, 0, e_j, g=0); h ← RNEA(q, q̇, 0, g); g(q) ← RNEA(q, 0, 0, g)
3.2.5 풀이 예제 — 닫힌 식·벡터 재귀·정적 검사·연산량·6R 팔
결론부터 적으면 다음과 같다. ① 평면 2R 닫힌 식과 RNEA가 $7.1\times10^{-15}$로 일치하고 벡터 재귀·질량행렬 분해·에너지·대칭·양의 정부호가 $n=2\sim7$에서 모두 성립한다. ② 정적 팁 렌치와 총중량 반력이 일치한다. ③ 곱셈 횟수가 $357n$($n=64$에서 $22{,}848$)이고 $M$ 열 구성이 $357n^{2}$이다. ④ 예제 6R 팔의 관절 2는 중력항의 최댓값 $27.26$ N·m가 전체 토크 최댓값 $31.78$ N·m의 $86\,\%$이다. ⑤ 같은 팔의 관절 1은 전도 모멘트 최댓값 $32.07$ N·m가 구동 토크 최댓값 $15.15$ N·m의 $2.1$배이다. ⑥ 라이브러리와 $6.8\times10^{-13}$ 이하에서 일치한다.
구현. screw_exp·pose_mul·rnea·mass_matrix. 공간 관성·adjoint·ad와 행렬 연산은 3.1의 구현을 사용한다. 3차원 벡터 재귀(rnea_vec)·사슬 생성·곱셈 횟수 계수·도해는 스크립트에 있다.
| 항목 | 값 |
|---|---|
| 입력 1 | 평면 2R: 끝점 질량 $m_1=1.5$, $m_2=0.8$ kg, $L_1=0.5$, $L_2=0.4$ m, 중력 $-y$, 임의 상태 1000개(관절각 $U(-\pi,\pi)$, 속도 $U(-2,2)$ rad/s, 가속도 $U(-4,4)$ rad/s²; 시드 64) |
| 입력 2 | 임의 사슬: 수정 DH 매개변수($\alpha\in\{0,\pm\pi/2,U(-3,3)\}$, $a\sim U(0,0.4)$, $d\sim U(0,0.3)$, 오프셋 $U(-1,1)$), 링크마다 점질량 12개(질량 0.05~0.5 kg, 표준편차 50 mm)로 만든 물리적으로 가능한 관성, $n=2\sim7$, 각 100개 |
| 입력 3 | 정적 검사: 임의 6R 사슬 100개, $F_{tip}\sim U(-5,5)$ 여섯 성분 |
| 입력 4 | 곱셈 횟수: $n=2,4,8,16,32,64$ 임의 사슬, dot·mv·mm·cross의 스칼라 곱셈을 센다(스칼라×벡터·덧셈 제외) |
| 입력 5 | 예제 6R 팔: 수정 DH $(\alpha,a,d)$ = $(0,0,0.30)$, $(-\pi/2,0,0)$, $(0,0.40,0.10)$, $(-\pi/2,0.05,0.35)$, $(\pi/2,0,0)$, $(-\pi/2,0,0.10)$, 질량 $4,4,3,1.5,1,0.5$ kg, 링크는 반지름 40 mm 가는 원기둥(질량 중심은 다음 관절 프레임 쪽 중점, 링크 1·4는 지정값), 기저 $z$축이 위쪽 |
| 입력 6 | 팔 궤적: $q_i(t)=q_{0,i}+a_i\sin(2\pi t/1.5)$, $q_0=(0,-0.5,1,0,0.5,0)$ rad, $a=(0.8,0.6,0.6,1.0,0.8,1.2)$ rad(최대 각속도 $5.03$ rad/s, 최대 각가속도 $21.1$ rad/s²), 0.01 s 간격 151점 |
| 입력 7 | 라이브러리 대조: 임의 6R 50개×상태 4개, 직동 관절 포함 5관절 40개×4, 팁 렌치 50개, 예제 팔 151점(시드 641) |
def screw_exp(A, t):
"""exp([A] t) -> (R, p). 회전 |w|=1 또는 직동 w=0"""
w, v = A[:3], A[3:]
if not any(w):
return [[1.0 if i == j else 0.0 for j in range(3)]
for i in range(3)], [x * t for x in v]
K = hat(w)
K2 = mm(K, K)
s, c = sin(t), 1 - cos(t)
R = [[(i == j) + s * K[i][j] + c * K2[i][j]
for j in range(3)] for i in range(3)]
P = [[(i == j) * t + c * K[i][j] + (t - s) * K2[i][j]
for j in range(3)] for i in range(3)]
return R, mv(P, v)
def pose_mul(a, b):
return mm(a[0], b[0]), [x + y for x, y in
zip(mv(a[0], b[1]), a[1])]
def rnea(M, A, G, q, qd, qdd, g, Ftip=None):
"""M[i]: q=0에서 {i-1}의 {i} 기준 자세, A[i]: 관절 축,
G[i]: 공간 관성, g: 기저 프레임 중력 벡터,
Ftip: {n} 프레임의 팁 렌치. -> (tau, F)"""
n = len(q)
V, Vd, Ads = [], [], []
Vp, Vdp = [0.0] * 6, [0.0, 0.0, 0.0] + [-x for x in g]
for i in range(n):
E = screw_exp(A[i], -q[i])
R, p = pose_mul(E, M[i]) # T_{i,i-1}
Ad = adjoint(R, p)
Vi = [a + b * qd[i] for a, b in zip(mv(Ad, Vp), A[i])]
w = mv(ad(Vi), A[i])
Vdi = [a + b * qd[i] + c * qdd[i]
for a, b, c in zip(mv(Ad, Vdp), w, A[i])]
V.append(Vi); Vd.append(Vdi); Ads.append(Ad)
Vp, Vdp = Vi, Vdi
F = list(Ftip) if Ftip else [0.0] * 6
tau, Fs = [0.0] * n, [None] * n
for i in reversed(range(n)):
GV = mv(G[i], V[i])
gy = mv(tr(ad(V[i])), GV)
GVd = mv(G[i], Vd[i])
F = [f + a - b for f, a, b in zip(F, GVd, gy)]
Fs[i], tau[i] = F, dot(F, A[i])
F = mv(tr(Ads[i]), F) # {i-1}로 옮긴다
return tau, Fs
def mass_matrix(M, A, G, q):
n = len(q)
z = [0.0] * n
cols = []
for j in range(n):
e = [1.0 if k == j else 0.0 for k in range(n)]
cols.append(rnea(M, A, G, q, z, e, [0.0] * 3)[0])
return [[cols[j][i] for j in range(n)] for i in range(n)]
① 평면 2R 닫힌 식과 임의 사슬의 항등식.
| 검사 | 최대 절대 오차 |
|---|---|
| 평면 2R(끝점 질량 $m_1=1.5$, $m_2=0.8$ kg, $L_1=0.5$, $L_2=0.4$ m, 중력 $-y$) 닫힌 식 Modern Robotics (8.9) 대 RNEA, 임의 상태 1000개 | 7.1e-15 |
닫힌 식은 Modern Robotics 식 (8.9)이며 같은 사슬을 3차원 RNEA에 넣어 비교한 것이다. 두 값이 일치하므로 이 장의 부호·프레임 규약(성분 순서 $(\omega,v)$, 기저 가속도 $(0,-g)$)이 맞는다.
| 관절 수 $n$ | 벡터 재귀 대 공간 RNEA | $M\ddot q+h$ 대 RNEA | $M$의 비대칭 | $\tfrac12\dot q^{T}M\dot q$ 대 $\sum\tfrac12V_i^{T}G_iV_i$ | 촐레스키 최소 피벗 $\min\ell_{ii}^{2}$ |
|---|---|---|---|---|---|
| 2 | 5.3e-15 | 1.8e-15 | 0.0e+00 | 4.4e-16 | 8.29e-03 |
| 3 | 1.1e-14 | 7.1e-15 | 2.2e-16 | 1.8e-15 | 1.06e-02 |
| 4 | 1.4e-14 | 1.4e-14 | 8.9e-16 | 3.6e-15 | 8.45e-03 |
| 5 | 2.8e-14 | 2.8e-14 | 8.9e-16 | 3.6e-15 | 1.03e-02 |
| 6 | 3.6e-14 | 3.6e-14 | 2.7e-15 | 7.1e-15 | 8.38e-03 |
| 7 | 1.1e-13 | 5.7e-14 | 4.4e-15 | 2.8e-14 | 5.21e-03 |
세 번째 열은 RNEA 한 번의 결과와 RNEA 열로 만든 $M$과 $h$로 계산한 $M\ddot q+h$가 같음을 보이며 $\tau$가 $\ddot q$에 대해 아핀이라는 구조를 확인한다. $M$의 대칭 오차는 $4.4\times10^{-15}$ 이하이고 촐레스키 분해의 최소 피벗이 모든 $n$에서 양수이므로 양의 정부호이다. 운동 에너지 항등식은 3.1의 $\frac12V^{T}GV$와 이 장의 $M$이 같은 에너지를 준다는 것($M=\sum J_{ib}^{T}G_iJ_{ib}$와 같은 내용)을 확인한다.
② 정적 검사.
| 정적 검사 (임의 6R 사슬 100개, $\dot q=\ddot q=0$) | 최대 절대 오차 |
|---|---|
| 중력 없음, 팁 렌치 $F_{tip}$: RNEA $\tau$ 대 $J_b^{T}F_{tip}$ | 1.8e-15 |
| 중력만: 기저 프레임에서 본 관절 1 반력의 힘 성분 대 총중량 $(0,\ 0,\ \sum m_ig)$ | 1.8e-13 |
중력이 없을 때 팁 렌치 대응 토크가 $J_b^{T}F_{tip}$와 같다는 것은 RNEA가 정역학(2.12)을 포함한다는 뜻이다. 중력만 있을 때 관절 1이 전달하는 힘의 성분이 총중량과 같다는 것은 후방 순환의 렌치가 물리적 반력임을 보인다.
③ 곱셈 횟수.
| 관절 수 $n$ | RNEA 곱셈 횟수 | 곱셈 횟수 $/n$ | $M(q)$를 RNEA 열로 구성한 곱셈 횟수 | 곱셈 횟수 $/n^{2}$ |
|---|---|---|---|---|
| 2 | 714 | 357.0 | 1,428 | 357.0 |
| 4 | 1,428 | 357.0 | 5,712 | 357.0 |
| 8 | 2,856 | 357.0 | 22,848 | 357.0 |
| 16 | 5,712 | 357.0 | 91,392 | 357.0 |
| 32 | 11,424 | 357.0 | 365,568 | 357.0 |
| 64 | 22,848 | 357.0 | 1,462,272 | 357.0 |
링크당 곱셈이 $357$로 일정하므로 RNEA는 $n$에 정비례한다. $M(q)$를 RNEA 열로 구성하면 $n$배로 늘어난다. 이 값은 이 장의 희소성 없는 $6\times6$ 구현에서 센 것이며 라이브러리의 상수는 다르다. 곱셈 횟수가 정확히 $357n$인 것은 구조에서 나오는 결과이고 실행 시간을 측정한 것이 아니므로 실제 지연은 이 장이 보고하지 않는다.
④ 예제 6R 팔의 궤적 토크.
| 관절 | 질량 (kg) | $\max\lvert\tau\rvert$ (N·m) | 중력항 $g$ | 속도곱 $C\dot q$ | 관성항 $M\ddot q$ | 중력 제외 토크 $\lvert\tau-g\rvert$ |
|---|---|---|---|---|---|---|
| 1 | 4 | 15.15 | 0.00 | 6.32 | 15.15 | 15.15 |
| 2 | 4 | 31.78 | 27.26 | 11.10 | 18.31 | 18.31 |
| 3 | 3 | 12.41 | 16.46 | 8.10 | 13.47 | 14.90 |
| 4 | 1.5 | 0.84 | 0.91 | 0.52 | 0.35 | 0.53 |
| 5 | 1 | 1.85 | 1.11 | 1.19 | 0.36 | 1.48 |
| 6 | 0.5 | 0.02 | 0.00 | 0.01 | 0.02 | 0.02 |
관절 1(수직 축)은 중력 토크가 0이어서 토크가 모두 동적이다($15.15$ N·m). 관절 2는 중력항의 최댓값이 $27.26$ N·m로 전체 최댓값 $31.78$ N·m에 가깝다. 관절 3은 중력 제외 토크의 최댓값($14.90$ N·m)이 중력항의 최댓값($16.46$ N·m)과 같은 자릿수이다. 이 궤적(최대 $21$ rad/s²)에서 관절 1~3은 관성항의 최댓값이 속도곱항의 $1.6\sim2.4$배이다. 각 항의 최댓값은 서로 다른 시각에 나타나므로 합과 같지 않으며, 시각별로는 $\tau=g+C\dot q+M\ddot q$가 $9.8\times10^{-15}$ N·m 이내로 성립한다. 이 값은 입력 5·6의 가정에서만 유효하다.
⑤ 관절 반력.
| 관절 | $\max\lvert F_{i,z}\rvert$ (N·m, 구동 모멘트) | $\max\sqrt{F_{i,x}^{2}+F_{i,y}^{2}}$ (N·m, 전도 모멘트) | $\max\lvert f_{i,z}\rvert$ (N, 축 방향 힘) | $\max\sqrt{f_{i,x}^{2}+f_{i,y}^{2}}$ (N, 반경 방향 힘) |
|---|---|---|---|---|
| 1 | 15.15 | 32.07 | 170.8 | 52.7 |
| 2 | 31.78 | 15.24 | 38.0 | 134.8 |
| 3 | 12.41 | 14.92 | 40.2 | 97.9 |
| 4 | 0.84 | 2.91 | 52.8 | 38.7 |
| 5 | 1.85 | 1.15 | 14.3 | 33.3 |
| 6 | 0.02 | 0.30 | 9.8 | 9.3 |
후방 순환의 $F_i$에서 관절 축 방향 모멘트는 구동 토크이고 나머지 다섯 성분이 베어링·구조가 지탱하는 구속 렌치이다. 관절 1의 축 방향 힘 최댓값 $170.8$ N은 팔 총질량 $14$ kg의 중량 $137.3$ N보다 크며 차이는 가속에서 나온다. 관절 1의 전도 모멘트($32.07$ N·m)는 구동 토크($15.15$ N·m)의 $2.1$배이고 관절 2의 반경 방향 힘($134.8$ N)이 같은 관절의 축 방향 힘($38.0$ N)보다 크다. 따라서 이 예에서 베어링·구조 하중은 구동 토크보다 구속 렌치를 기준으로 검토해야 하고, 이 값들은 RNEA의 부산물로 추가 계산 없이 얻어진다. 수치는 입력 5·6의 가정에서만 유효하며 안전계수·피로(4.2)는 이 장이 다루지 않았다.
⑥ 라이브러리 대조(실행 2026-11-05). Pinocchio 4.1.0의 rnea·crba·nonLinearEffects·aba·data.f(관절 반력)와 rnea의 외력 인자, MuJoCo 3.17.0의 mj_inverse, modern_robotics 1.1.1의 InverseDynamics·MassMatrix·ForwardDynamics, Robotics Toolbox 1.5.0의 DHRobot.rne(수정 DH)를 같은 사슬·같은 상태에서 비교했다. 스크립트는 robotics/fig-src/3.2-libcheck.py, 출력은 robotics/fig-src/data/3.2-libcheck-output.txt에 있다.
| 비교 | 결과 |
|---|---|
임의 6R 사슬 50개×상태 4개: 이 장의 $\tau$ 대 Pinocchio rnea: 최대 차이 (N·m) | 5.0e-14 |
같은 입력: 관절 반력 $F_i$ 대 Pinocchio data.f(성분 순서 변환): 최대 차이 | 1.4e-13 |
같은 입력: $M(q)$(RNEA 열로 구성) 대 Pinocchio crba · $h$ 대 nonLinearEffects: 최대 차이 | 7.1e-15 · 4.3e-14 |
같은 입력: Pinocchio aba로 구한 $\ddot q$를 이 장의 RNEA에 넣어 되찾은 $\tau$: 최대 차이 | 5.7e-14 |
같은 입력: 이 장의 $\tau$ 대 MuJoCo mj_inverse(qfrc_inverse): 최대 차이 | 1.1e-13 |
같은 입력: 이 장의 $\tau$ 대 modern_robotics InverseDynamics · MassMatrix: 최대 차이 | 3.3e-13 · 3.4e-14 |
같은 입력: 팁 렌치를 준 $\tau$ 대 modern_robotics InverseDynamics(Ftip는 $\{n+1\}$ 프레임으로 변환): 최대 차이 | 3.4e-13 |
같은 입력: modern_robotics ForwardDynamics로 구한 $\ddot q$를 이 장의 RNEA에 넣어 되찾은 $\tau$: 최대 차이 | 2.3e-12 |
같은 입력(수정 DH 표현): 이 장의 $\tau$ 대 Robotics Toolbox DHRobot.rne: 최대 차이 | 5.7e-14 |
| 직동 관절을 가진 5관절 사슬 40개×4: Pinocchio · MuJoCo · modern_robotics 대비 최대 차이 | 4.5e-13 · 5.7e-13 · 6.8e-13 |
팁 렌치(임의 6R 50개): 이 장의 $\tau$ 대 Pinocchio rnea의 외력 fext(부호 반전): 최대 차이 | 3.2e-14 |
| 예제 6R 팔 궤적 151점: 이 장의 $\tau$ 대 Pinocchio · MuJoCo · modern_robotics 최대 차이 | 1.8e-14 · 2.5e-14 · 1.4e-14 |
모든 항목이 $6.8\times10^{-13}$ 이하(modern_robotics 순동역학 왕복 $2.3\times10^{-12}$)에서 같다. 순동역학 왕복의 오차가 큰 것은 질량행렬의 연립방정식을 푸는 과정의 반올림이 더해지기 때문으로 추정한다. 각 라이브러리의 입력은 서로 다른 관례로 만들어야 했다. Pinocchio는 관절 프레임에 링크가 붙고 성분 순서가 (선형, 각)이며, MuJoCo는 본체 프레임 위치·사원수와 fullinertia로, modern_robotics는 질량 중심 프레임의 $M_{i-1,i}$·공간 스크루 축·$G_i=\mathrm{diag}(I,mE)$로 변환했고 이 장의 팁 렌치(관절 프레임 $\{n\}$)는 질량 중심 프레임 $\{n+1\}$로 옮겨 입력했다. Pinocchio의 외력 인자는 몸에 가해지는 힘을 받으므로 이 장의 $F_{tip}$(말단이 환경에 가하는 렌치)의 부호를 반전해 넣어야 일치했다.
한계. 1자유도 관절의 직렬 개연쇄, 강체 링크, 균일 중력만 다룬다. 마찰·회전자 관성·기어비·유연성은 포함하지 않았다(3.8·3.9). 닫힌 폐연쇄(3.11)와 부유 기저(3.13), 분기 트리 사슬은 이 장의 구현에 없다. 실행 시간과 메모리는 측정하지 않았고 실시간 제어 주기 안에서의 계산 가능성은 확인하지 않았다.
견해: 실제 로봇의 역동역학은 직접 구현하기보다 검증된 라이브러리(3.6)를 사용하고, 임베디드 제어기나 학습·교육용 소형 구현처럼 라이브러리를 넣기 어려운 곳에서만 RNEA를 직접 구현하는 것이 합리적이라고 본다. 근거는 이 장에서 순수 파이썬 코어 55줄(공간 관성·행렬 연산은 3.1 구현 사용)이 네 라이브러리와 $6.8\times10^{-13}$ 이하(순동역학 왕복 제외)에서 일치해 알고리즘 자체는 짧고 검증 가능하지만, 입력 규약(프레임·성분 순서·외력 부호·관성 부호)이 라이브러리마다 달라 변환 오류가 오차의 주된 원인이 된다는 점이다. 라이브러리의 속도·안정성·기능은 3.6에서 비교하며 이 장은 실행 시간을 측정하지 않았다.
3.2.6 설계 트레이드오프 — 역동역학의 구현 방식
역동역학을 제어기에 넣는 방식은 다음 중에서 고른다.
- ① 수치 재귀(RNEA). 링크 개수에 선형이고 모델을 데이터(MDH·URDF)로 바꿀 수 있다. 식의 부호와 프레임 처리를 직접 구현해야 한다.
- ② 기호식 닫힌 형식. 라그랑주 정식화(3.3)로 $M$·$C$·$g$를 기호로 전개한다. 자유도가 작으면 식이 짧고 해석에 좋으나 자유도가 늘면 항이 급증한다.
- ③ 동역학 라이브러리·코드 생성. 검증된 구현을 사용하거나 모델에서 C 코드를 생성한다(3.6). 구현 오류가 적고 빠르나 의존성과 입력 규약 변환이 필요하다.
| 방식 | 연산량 | 모델 변경 | 구현 위험 | 적합한 경우 |
|---|---|---|---|---|
| ① RNEA 직접 구현 | 링크당 일정 | 데이터로 변경 | 부호·프레임 오류 | 임베디드·교육 |
| ② 기호식 | 자유도에 따라 급증 | 식을 다시 유도 | 전개 오류 | 3자유도 이하의 해석 |
| ③ 라이브러리·생성 | 최적화된 구현 | 모델 파일 | 입력 규약 변환 | 일반 개발 |
견해: 새 개발은 ③을 기본으로 하고, 해석이 목적이거나 자유도가 작은 기구는 ②를 사용하며, 라이브러리가 없는 환경에서만 ①을 구현하는 것이 맞다고 본다. 근거는 이 장에서 ①의 구현이 알고리즘상 단순하지만 규약 변환이 오류의 주원인이었고 ③의 구현과 일치가 확인되었다는 점이다. ②의 연산량 증가는 3.3에서 계산으로 확인한다. 세 방식의 실행 시간·정확도 비교는 이 장이 수행하지 않았다.
3.2.7 응용 축 비교
| 응용 축 | RNEA가 맡는 일 | 요구 | 관련 장 |
|---|---|---|---|
| 산업·제조 | 계산 토크·중력 보상·피드포워드 토크 | 제어 주기 안의 계산, 부하 모델 정확도 | 12.5, 5.2 |
| 물류·이동 | 모바일 매니퓰레이터에서 기저 운동을 $V_0,\dot V_0$에 넣은 팔 토크(이 장은 병진 가속만 구현) | 기저 운동의 입력 | 7.24 |
| 도로 주행 | 해당하는 고유 요구 없음 | — | — |
| 서비스 | 해당하는 고유 요구 없음 | — | — |
| 의료·헬스케어 | 원리 수준에서 해당하는 고유 요구를 확인하지 못했다 | — | — |
| 휴머노이드·범용 | 부유 기저로 확장한 전신 역동역학 | 6자유도 기저 포함 | 3.13 |
| 필드 | 대형·장대 팔의 중력 토크와 관절 하중 | 하중 변동·관절 반력 | 7.6, 4.2 |
| 국방·안보 | 원리 수준에서 해당하는 고유 요구 없음 | — | — |
이 표는 이 책의 정리이며 장별 요구는 다르다. 응용별 성능 수치는 이 장이 확인하지 않았다.
3.2.8 관련 규격·프로토콜
| 문서 | 발행 | 무엇을 정하나 | 상세 장 |
|---|---|---|---|
Pinocchio rnea·crba·aba | Pinocchio 4.1.0 | 역동역학·질량행렬·순동역학, 성분 순서 (선형, 각) | 3.6 |
MuJoCo mj_inverse | MuJoCo 3.17.0 문서 | 역동역학, 결과 qfrc_inverse | 3.6 |
InverseDynamics·MassMatrix | modern_robotics 1.1.1 | PoE 기반 RNEA, 성분 순서 $(\omega,v)$ | 3.6 |
DHRobot.rne | Robotics Toolbox 1.5.0 | 수정 DH 로봇의 역동역학 | 3.6 |
URDF <inertial> | ROS wiki | 링크 질량 특성 입력 | 27.9 |
| 수학 표기·기호표 | 이 책 | 트위스트 $(\omega,v)$·렌치 $(m,f)$ | A.2 |
역동역학 알고리즘을 규정한 국제 표준은 확인하지 못했다 (확인 필요).
3.2.9 관련 규제·인증 요구와의 연결
RNEA 자체를 규정하는 법령·인증 요건은 확인하지 못했다. 협동로봇이 모터 전류나 토크로 접촉 힘을 추정하는 경우 동역학 모델의 정확도가 추정 오차를 정하고(9.27의 운동량 관측기), 그 오차가 충돌 안전의 힘 한계 검토(26.9)에 영향을 줄 수 있다. 이 장은 이를 규정하는 규격 조항을 확인하지 않았다 (확인 필요).
3.2.10 한계·유의점·미해결
- 모델 범위. 마찰·회전자 관성·감속기 유연성·케이블 힘을 포함하지 않았다(3.8, 3.9). 실제 토크와 이 장의 값의 차이는 이 요소들이 만든다.
- 사슬 구조. 1자유도 관절의 직렬 사슬만 구현했다. 분기 트리·폐연쇄(3.11)·부유 기저(3.13)는 확장이 필요하다.
- 규약 변환. 성분 순서·프레임·외력 부호·관성 부호가 라이브러리마다 달라 변환 오류가 흔하다.
- 연산량. 곱셈 횟수만 보고했고 실행 시간·희소성 이용·SIMD 효과는 측정하지 않았다. 문헌의 연산량 비교는 읽지 못했다.
- 수치 안정. 임의 사슬 7관절까지 $10^{-13}$ 수준의 오차를 확인했으나 수십 관절·극단적 질량비에서의 조건은 시험하지 않았다.
3.2.11 체크포인트·연구 질문·출처
체크포인트:
- $\frac{d}{dt}\mathrm{Ad}_{T_{i,i-1}}=-\mathrm{ad}_{A_i\dot q_i}\mathrm{Ad}_{T_{i,i-1}}$에서 $\dot V_i$의 $\mathrm{ad}_{V_i}(A_i)\dot q_i$ 항을 유도하라.
- $\tau_i=F_i^{T}A_i$를 관절 일률로 설명하고 $F_i$의 나머지 성분이 무엇인지 설명하라.
- 중력을 $\dot V_0=(0,-g)$로 넣는 것이 각 링크에 $m_ig$의 힘을 가하는 것과 같음을 보여라.
- 곱셈 횟수 $357n$과 $357n^{2}$이 어디서 나오는지 설명하라.
- $M(q)$의 $j$번째 열을 RNEA 호출로 얻는 조건($\dot q=0$, $g=0$, $\ddot q=e_j$)을 적고 이유를 설명하라.
- 평면 2R에서 RNEA를 손으로 전개해 Modern Robotics 식 (8.9)의 $\tau_2$를 얻어라.
- $F_{tip}$이 말단이 환경에 가하는 렌치일 때 Pinocchio의 외력 인자에 넣을 부호를 설명하라.
연구 질문:
- 희소성(블록 삼각 $\mathrm{Ad}$, 블록 대각 $G$)을 사용한 RNEA의 곱셈 횟수는 이 장의 $357n$보다 얼마나 작으며 실제 실행 시간은 어떻게 달라지는가(이 장은 측정하지 않았다)?
- 학습된 잔차 모델(12.27)을 RNEA와 결합할 때 잔차를 어느 프레임·어느 항에 두는 것이 안정적인가?
1차 출처(조회 2026-11-05).
- K. M. Lynch, F. C. Park, Modern Robotics: Mechanics, Planning, and Control, Cambridge University Press, 2017, doi:10.1017/9781316661239 — 8.3절·8.4절 앞부분을 사전 인쇄본(2017-05판) 텍스트로 읽었다.
- MuJoCo 문서(계산 개관의 변수 표와 역동역학 계산 순서)를 읽었다.
- D. E. Orin, R. B. McGhee, M. Vukobratović, G. Hartoch, "Kinematic and kinetic analysis of open-chain linkages utilizing Newton-Euler methods," Mathematical Biosciences 43(1–2), 107–130, 1979, doi:10.1016/0025-5564(79)90104-4 — 서지만 확인.
- J. Y. S. Luh, M. W. Walker, R. P. C. Paul, "On-line computational scheme for mechanical manipulators," J. Dyn. Syst. Meas. Control 102(2), 69–76, 1980, doi:10.1115/1.3149599 — 서지만 확인.
- J. M. Hollerbach, "A recursive Lagrangian formulation of manipulator dynamics and a comparative study of dynamics formulation complexity," IEEE Trans. Systems, Man, and Cybernetics 10(11), 730–736, 1980, doi:10.1109/tsmc.1980.4308393 — 서지만 확인.
- M. W. Walker, D. E. Orin, "Efficient dynamic computer simulation of robotic mechanisms," J. Dyn. Syst. Meas. Control 104(3), 205–211, 1982, doi:10.1115/1.3139699 — 서지만 확인.
- R. Featherstone, Rigid Body Dynamics Algorithms, Springer, 2008, doi:10.1007/978-1-4899-7560-7 — 서지만 확인.
- J. Carpentier 외, "The Pinocchio C++ library," IEEE/SICE Int. Symp. on System Integration, 614–619, 2019, doi:10.1109/sii.2019.8700380; E. Todorov, T. Erez, Y. Tassa, "MuJoCo," IROS, 5026–5033, 2012, doi:10.1109/iros.2012.6386109; P. Corke, J. Haviland, "Not your grandmother's toolbox – the Robotics Toolbox reinvented for Python," ICRA, 11357–11363, 2021, doi:10.1109/icra48506.2021.9561366 — 서지만 확인.
- Pinocchio 4.1.0, MuJoCo 3.17.0, modern_robotics 1.1.1, Robotics Toolbox for Python 1.5.0, numpy 2.5.4.
다음 장. 3.3는 라그랑주 정식화와 에너지 기반 유도를 다룬다. 이 장의 RNEA가 힘과 가속도에서 출발한 것과 달리 운동 에너지와 위치 에너지에서 같은 운동방정식을 유도하고, 두 정식화가 같은 토크를 내는지와 계산량이 어떻게 다른지를 비교한다.