로봇공학기초

[로봇공학기초 / 2DOF] #4. Jacobian Matrix (자코비안 행렬)

jhpark0518 2025. 4. 2. 10:00

 

📐 Jacobian(자코비안)이란?

지난 글에서는 2자유도 로봇팔의 Workspace ( 작업공간 )에 대해 알아보며,  
로봇이 실제로 움직일 수 있는 위치의 범위를 수치적으로 표현해봤습니다.

그보다 앞에서는 Inverse Kinematics(역기구학)을 통해 관절 각도를 구하는 방법도 다뤘죠.

 

로봇팔의 말단 위치 $(x_2, y_2)$를 기준으로 각 관절 각도 $\theta_1$, $\theta_2$를 어떻게 구하는지 살펴보았습니다.

이번에는 속도에 대해 알아보겠습니다.

 

 

✍ 로봇팔의 말단 속도 구하기 (2 DOF 로봇 기준)

 

말단 위치 $(x_2, y_2)$는 관절각 $\theta_1, \theta_2$와 링크 길이 $L_1, L_2$에 따라 다음과 같이 표현됩니다:

\[
\begin{aligned}
x_2 &= L_1 \cos\theta_1 + L_2 \cos(\theta_1 + \theta_2) \\
y_2 &= L_1 \sin\theta_1 + L_2 \sin(\theta_1 + \theta_2)
\end{aligned}
\]

편의상 $(x_2, y_2)$를 $(x, y)$로 표기하겠습니다.

 

로봇팔의 말단 속도 $\dot{x}, \dot{y}$는
각 관절의 속도 $\dot{\theta}_1, \dot{\theta}_2$에 의해 다음과 같이 표현됩니다:

\[
\begin{bmatrix}
\dot{x} \\
\dot{y}
\end{bmatrix}
=
\mathbf{J}(\theta_1, \theta_2)
\begin{bmatrix}
\dot{\theta}_1 \\
\dot{\theta}_2
\end{bmatrix}
\]

 

여기서 $\mathbf{J}$는 각 위치를 관절 각도에 대해 편미분한 자코비안 행렬(Jacobian matrix)이며, 다음과 같이 정의됩니다:

\[
\mathbf{J} =
\begin{bmatrix}
\dfrac{\partial x}{\partial \theta_1} & \dfrac{\partial x}{\partial \theta_2} \\
\dfrac{\partial y}{\partial \theta_1} & \dfrac{\partial y}{\partial \theta_2}
\end{bmatrix}
\]

 

이를 실제로 계산하면, 2자유도 로봇팔의 자코비안 행렬은 다음과 같습니다:

\[
\mathbf{J} =
\begin{bmatrix}
- L_1 \sin\theta_1 - L_2 \sin(\theta_1 + \theta_2) & - L_2 \sin(\theta_1 + \theta_2) \\
L_1 \cos\theta_1 + L_2 \cos(\theta_1 + \theta_2) & L_2 \cos(\theta_1 + \theta_2)
\end{bmatrix}
\]

 

 

이제 여기에 각 관절의 속도 $\dot{\theta}_1$, $\dot{\theta}_2$를 곱해보면, 말단 속도 $\dot{x}, \dot{y}$는 다음과 같이 계산됩니다:

\[ \begin{bmatrix} \dot{x} \\ \dot{y} \end{bmatrix} = \mathbf{J} \begin{bmatrix} \dot{\theta}_1 \\ \dot{\theta}_2 \end{bmatrix} = \begin{bmatrix} (-L_1 \sin\theta_1 - L_2 \sin(\theta_1 + \theta_2)) \dot{\theta}_1 + (-L_2 \sin(\theta_1 + \theta_2)) \dot{\theta}_2 \\ (L_1 \cos\theta_1 + L_2 \cos(\theta_1 + \theta_2)) \dot{\theta}_1 + (L_2 \cos(\theta_1 + \theta_2)) \dot{\theta}_2 \end{bmatrix} \]

 

 

📈 그래프로 그려보기

 

아래는 두 관절에 동일한 속도 $\dot{\theta}_1 = \dot{\theta}_2 = 0.1\ \text{rad/s}$를 줄 때,
자코비안을 이용해 계산한 말단 속도를 화살표로 시각화한 예시입니다.

 

 

“각 관절이 같은 속도로 회전하더라도,
말단 속도는 로봇팔의 자세(즉, 관절각도)에 따라
방향과 크기가 달라집니다.”

 

 

이는 자코비안 행렬이 로봇팔의 현재 자세에 따라 달라지기 때문입니다.
즉, 자코비안은 특정 관절 속도가 말단 속도에 어떤 영향을 미치는지를 나타냅니다.

자세에 따라 말단이 더 잘 움직일 수 있는 방향과 그렇지 않은 방향이 존재하게 되며,
이러한 특성은 제어, 경로 계획, 특이점 회피 등 다양한 분야에서 매우 중요하게 활용됩니다.

 

💻 속도 벡터 시각화 코드 (Python)

import numpy as np
import matplotlib.pyplot as plt

# 한글 및 유니코드 지원 폰트 설정 (예: NanumGothic)
plt.rcParams['font.family'] = 'NanumGothic'
plt.rcParams['axes.unicode_minus'] = False

def forward_kinematics(theta1, theta2, l1, l2):
    base = np.array([0, 0])
    joint = np.array([l1 * np.cos(theta1), l1 * np.sin(theta1)])
    end_effector = joint + np.array([l2 * np.cos(theta1 + theta2), l2 * np.sin(theta1 + theta2)])
    return base, joint, end_effector

def jacobian(theta1, theta2, l1, l2):
    J11 = -l1 * np.sin(theta1) - l2 * np.sin(theta1 + theta2)
    J12 = -l2 * np.sin(theta1 + theta2)
    J21 = l1 * np.cos(theta1) + l2 * np.cos(theta1 + theta2)
    J22 = l2 * np.cos(theta1 + theta2)
    return np.array([[J11, J12],
                     [J21, J22]])

# 파라미터 설정
l1, l2 = 1, 0.5
theta1 = np.deg2rad(121.5)
theta2 = np.deg2rad(41.4)

joint_velocities = np.array([0.1, 0.1])

base, joint, end_effector = forward_kinematics(theta1, theta2, l1, l2)
J = jacobian(theta1, theta2, l1, l2)
end_effector_velocity = J @ joint_velocities
vx, vy = end_effector_velocity
v = np.linalg.norm(end_effector_velocity)

# 그래프 설정 및 로봇팔 그리기
fig, ax = plt.subplots(figsize=(6, 6), dpi=300)
ax.plot([base[0], joint[0], end_effector[0]], [base[1], joint[1], end_effector[1]],
        'ko-', linewidth=2, markersize=8, label="로봇팔")
ax.plot(base[0], base[1], 'ks', markersize=10)

# 속도 벡터
ax.quiver(end_effector[0], end_effector[1], vx, vy, angles='xy',
          scale_units='xy', scale=1, color='r', width=0.005, label="말단 속도 벡터")

# 텍스트 스타일 박스
bbox_style = dict(facecolor='white', edgecolor='black', boxstyle='round,pad=0.3')

# 속도 벡터 설명
ax.text(end_effector[0]-0.4, end_effector[1] + 0.3,
        f"v_x = {vx:.2f} m/s\nv_y = {vy:.2f} m/s\nv = {v:.2f} m/s",
        fontsize=10, color='red', bbox=bbox_style)

# 각속도 설명
ax.text(base[0] + 0.1, base[1] + 0.1,
        f"w_1 = {joint_velocities[0]:.2f} rad/s",
        fontsize=10, color='black', bbox=bbox_style)
ax.text(joint[0] + 0.1, joint[1] + 0.1,
        f"w_2 = {joint_velocities[1]:.2f} rad/s",
        fontsize=10, color='black', bbox=bbox_style)

ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_title("2자유도 로봇팔: 말단 속도 성분 및 각속도 표시")
ax.grid(True)
ax.legend()

# 현재 작업 폴더에 '04_graph.png'로 저장됩니다
plt.savefig("04_graph.png", dpi=300, bbox_inches='tight')  # 저장
plt.show()

 

🔧 실행 환경

  • Python 3.8 이상
  • numpy
  • matplotlib
  • Jupyter Notebook 환경 추천

 

📘 다음 편 예고

이번 글에서는 자코비안 행렬이 무엇인지, 그리고 말단 속도를 어떻게 계산하는지 알아보았습니다.
다음 시간에는 로봇팔에서 아주 아주 아주 중요한 개념인 특이점(Singularity)에 대해 다룹니다.