로봇공학기초

[로봇공학기초 / 2DOF] #3. Work Space (작업공간)

jhpark0518 2025. 3. 31. 10:00

 

🦾 작업공간(Workspace)이란?

 

로봇팔이 실제로 움직일 수 있는 공간.
즉, 말단(End-effector)이 도달할 수 있는 위치의 전체 집합을 우리는 작업공간 (Workspace) 이라고 부릅니다.

 

 

“ 아무리 열심히 움직여도, 절대 닿지 않는 곳이 있다면? ”

그건 작업공간 밖입니다.

 

 

그럼, 이 작업공간은 수치적으로 어떻게 표현할 수 있을까요?

 

✍ 수치적으로 풀기

2자유도 로봇팔에서, 각 관절의 회전 범위가 $360^\circ$라고 가정하면, 말단 위치 $(x, y)$는 다음 조건을 만족해야 합니다:

  • 최대 도달 거리: $L_1 + L_2$
  • 최소 도달 거리: $|L_1 - L_2|$

즉, 작업공간은 아래 조건을 만족하는 원판 형태입니다:

$$
|L_1 - L_2| \leq \sqrt{x^2 + y^2} \leq L_1 + L_2
$$

이 조건을 만족하지 않으면, 해당 위치에는 로봇팔이 절대 도달할 수 없습니다.

 

 

📈 그래프로 그리기

  • 바깥 검정 띠: 최대 도달 거리 $L_1 + L_2$
  • 안쪽 검정 띠: 최소 도달 거리 $|L_1 - L_2|$
  • 그 사이의 회색 원판 영역: 로봇팔이 실제로 움직일 수 있는 작업 공간입니다.
  • 빨간 마커: 목표점(1번: 외곽, 2번: 중간, 3번: 내곽)

 

 

💬 부가 설명

대부분의 경우 작업공간은 단순한 원판처럼 보이지만,
장애물, 관절 제한, 혹은 로봇의 구조적 특성에 따라 훨씬 복잡한 형태가 되기도 합니다.

 

💻 아래는 그래프를 그릴 때 사용한 Python 코드입니다.

import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.family'] = 'Malgun Gothic'
plt.rcParams['axes.unicode_minus'] = False

# 링크 길이
L1, L2 = 1, 0.5

# 목표점 목록
targets = {
    "1번 (외곽)": (0, L1 + L2),
    "2번 (중간)": (-1.0, 1.0),
    "3번 (내곽)": (abs(L1 - L2), 0),
}
marker = ['D', 'o', 's']


# 시각화
fig, ax = plt.subplots(figsize=(6, 6), dpi=300)
ax.set_xlim(-2, 2)
ax.set_ylim(-2, 2)
ax.set_aspect('equal')
ax.set_title("2자유도 로봇팔 작업공간 + 각 목표점 로봇팔")
ax.set_axisbelow(True)
plt.grid(True)

# 작업공간 영역
outer_fill = plt.Circle((0, 0), L1 + L2, color='#999999', alpha=0.2, zorder=1)
inner_fill = plt.Circle((0, 0), abs(L1 - L2), color='white', zorder=2)
outer_edge = plt.Circle((0, 0), L1 + L2, color='black', fill=False, linewidth=1.5, zorder=3)
inner_edge = plt.Circle((0, 0), abs(L1 - L2), color='black', fill=False, linewidth=1.5, zorder=4)
ax.add_patch(outer_fill)
ax.add_patch(inner_fill)
ax.add_patch(outer_edge)
ax.add_patch(inner_edge)

# 각 목표점에 대해: 역기구학 → 로봇팔 그림
for (label, (xt, yt)), marker in zip(targets.items(), marker):
    # 거리 계산
    r = np.hypot(xt, yt)

    # 역기구학 (Cosine Law)
    cos_theta2 = (r**2 - L1**2 - L2**2) / (2 * L1 * L2)
    if abs(cos_theta2) > 1:
        print(f"{label}은 작업공간 밖입니다.")
        continue
    theta2 = np.arccos(cos_theta2)  # Elbow-down 기준
    k1 = L1 + L2 * np.cos(theta2)
    k2 = L2 * np.sin(theta2)
    theta1 = np.arctan2(yt, xt) - np.arctan2(k2, k1)

    # Forward Kinematics
    x0, y0 = 0, 0
    x1 = x0 + L1 * np.cos(theta1)
    y1 = y0 + L1 * np.sin(theta1)
    x2 = x1 + L2 * np.cos(theta1 + theta2)
    y2 = y1 + L2 * np.sin(theta1 + theta2)

    # 로봇팔 그리기
    ax.plot([x0, x1], [y0, y1], 'b', linewidth=3, zorder=6)
    ax.plot([x1, x2], [y1, y2], 'g', linewidth=5, zorder=6)
    ax.plot(x0, y0, 'ko', markersize=7, zorder=7)  # 베이스
    ax.plot(x1, y1, 'ko', markersize=7, zorder=7)  # 관절
    # 목표점 표시
    ax.plot(xt, yt, marker = marker, color = 'red', label=label, markersize=7, zorder=8)

# 라벨
plt.xlabel("X")
plt.ylabel("Y")
plt.legend()
plt.show()

 

🔧 실행 환경

  • Python 3.8 이상
  • matplotlib
  • numpy
  • Jupyter Notebook (추천)

 

📘 다음 편 예고

다음 글에서는, 이 작업공간 안에서 속도와 힘의 방향을 정의하는 Jacobian(자코비안) 행렬에 대해 알아보겠습니다.