좌표는 숫자이기 전에 약속이다
지난 장에서 우리는 벡터의 크기와 방향을 다루었다. 로봇 위치가 [2, 3]이고 목표 위치가 [5, 7]이면, 목표 방향 벡터는 [3, 4]라고 계산했다. 여기까지는 비교적 단순했다. 두 위치가 모두 같은 평면 위에 있고, 같은 기준으로 표현되어 있었기 때문이다.
그런데 실제 로봇에서는 문제가 조금 더 재미있어진다.
로봇 앞에 컵이 하나 있다고 해 보자. 로봇의 카메라는 이렇게 말할 수 있다.
"컵은 내 앞쪽 1.2m, 왼쪽 0.3m에 있어."
하지만 지도는 이렇게 말할 수 있다.
"컵은 전체 방 기준으로 x = 4.5m, y = 2.1m 위치에 있어."
둘 다 같은 컵을 말하고 있다. 그런데 숫자가 다르다. 틀린 것이 아니다. 기준이 다르기 때문이다.
이 장의 핵심은 바로 이것이다. 좌표는 그냥 숫자가 아니라, "무엇을 기준으로 잰 숫자인가?"라는 약속을 포함한다. 이 약속을 좌표계라고 부른다.
로봇공학에서 좌표계를 구분하지 못하면 매우 이상한 일이 생긴다. 카메라는 물체가 정면에 있다고 말하는데, 지도 위에서는 물체가 로봇 뒤쪽에 그려질 수 있다. 목표점은 오른쪽에 있는데 로봇은 왼쪽으로 돌 수 있다. 센서 데이터와 지도 데이터가 서로 다른 언어로 말하고 있는데, 우리가 그것을 같은 언어라고 착각했기 때문이다.
이번 장에서는 가장 기본이 되는 두 좌표계를 다룬다. 하나는 세상에 고정된 월드 좌표계이고, 다른 하나는 로봇 몸에 붙어 함께 움직이는 로봇 좌표계이다.

월드 좌표계: 세상에 고정된 기준
월드 좌표계는 말 그대로 세상을 기준으로 한 좌표계다. 로봇이 어디로 가든, 어떻게 회전하든, 월드 좌표계는 움직이지 않는다고 생각한다.
방 안에 로봇이 있다고 해 보자. 방의 왼쪽 아래 모서리를 원점 (0, 0)으로 정하고, 오른쪽 방향을 x축, 위쪽 방향을 y축으로 정할 수 있다. 그러면 방 안의 모든 물체 위치를 이 기준으로 표현할 수 있다.
예를 들어 다음과 같이 말할 수 있다.
충전기는
(1.0, 1.0)에 있다.책상은
(4.0, 2.0)에 있다.로봇은 현재
(2.0, 1.5)에 있다.목표 지점은
(5.0, 3.0)에 있다.
이때 모든 좌표는 같은 기준을 사용한다. 방이라는 고정된 공간 위에서 위치를 표현하는 것이다.
지도도 보통 이런 식으로 생각할 수 있다. 로봇이 SLAM으로 지도를 만들거나, 미리 만들어진 지도 위에서 이동할 때, 지도는 하나의 고정된 기준 공간 역할을 한다. 로봇이 왼쪽을 보든 오른쪽을 보든 지도 위의 벽, 문, 장애물 위치가 같이 돌아가면 곤란하다. 지도는 안정적인 기준이어야 한다.
그래서 월드 좌표계는 로봇에게 "전체 세상에서 네가 어디에 있는지"를 알려 주는 기준이 된다.
간단히 그림으로 상상해 보자.
월드 좌표계
y
↑
|
| 목표점 (5, 3)
|
| 로봇 (2, 1.5)
|
+----------------→ x
(0, 0)이 그림에서 x축과 y축은 방에 붙어 있다. 로봇이 회전해도 이 축은 그대로다. 월드 좌표계는 로봇을 따라가지 않는다.
로봇 좌표계: 로봇 몸에 붙은 기준
이번에는 로봇 자신을 기준으로 생각해 보자.
로봇에게 가장 자연스러운 표현은 "세상 기준 x가 얼마, y가 얼마"가 아니다. 로봇에게는 "내 앞인가?", "내 뒤인가?", "내 왼쪽인가?", "내 오른쪽인가?"가 훨씬 직접적이다.
이렇게 로봇 몸체를 기준으로 하는 좌표계를 로봇 좌표계라고 부른다.
이 책에서는 2D 로봇 좌표계를 다음과 같이 약속하겠다.
로봇의 중심을 원점
(0, 0)으로 둔다.로봇이 바라보는 앞쪽을 로봇 x축 양의 방향으로 둔다.
로봇의 왼쪽을 로봇 y축 양의 방향으로 둔다.
즉, 로봇 기준으로 [1.0, 0.0]은 "앞으로 1m"를 뜻하고, [0.0, 1.0]은 "왼쪽으로 1m"를 뜻한다. [0.0, -1.0]은 "오른쪽으로 1m"다.
로봇 좌표계
y_robot (왼쪽)
↑
|
|
● 로봇 중심
|
+----------→ x_robot (앞쪽)여기서 중요한 점이 있다. 로봇 좌표계는 로봇 몸에 붙어 있다. 로봇이 움직이면 원점도 같이 움직이고, 로봇이 회전하면 x축과 y축도 같이 회전한다.
사람도 비슷하다. 우리가 "내 오른쪽에 의자가 있다"고 말할 때, 그 표현은 내 몸 방향에 따라 달라진다. 내가 뒤돌아 서면 같은 의자는 이제 내 왼쪽에 있을 수도 있다. 의자가 순간이동한 것이 아니다. 내가 바라보는 기준이 바뀐 것이다.
로봇도 마찬가지다. 같은 물체라도 로봇이 어느 방향을 보고 있느냐에 따라 로봇 기준 좌표가 바뀐다.
같은 물체, 다른 숫자
이제 구체적인 예를 보자.
월드 좌표계에서 로봇이 (2, 1) 위치에 있다고 하자. 그리고 컵은 월드 좌표로 (5, 2)에 있다.
로봇이 월드 x축의 양의 방향, 즉 오른쪽을 바라보고 있다면 어떻게 될까?
월드 기준
y
↑
|
| 컵 (5, 2)
|
| 로봇 (2, 1) →
|
+----------------------→ x컵은 로봇보다 x 방향으로 3m 앞에 있고, y 방향으로 1m 왼쪽에 있다. 따라서 로봇 기준으로 컵의 위치는 대략 (3, 1)이라고 말할 수 있다.
로봇 기준 컵 위치: 앞쪽 3m, 왼쪽 1m
즉, (3, 1)이번에는 로봇의 위치는 그대로인데, 로봇이 위쪽을 바라보도록 90도 회전했다고 해 보자.
월드 기준
y
↑
|
| 컵 (5, 2)
|
| 로봇 (2, 1)
| ↑
+----------------------→ x컵의 월드 좌표는 여전히 (5, 2)다. 컵은 움직이지 않았다. 하지만 로봇 입장에서는 달라진다.
로봇이 위쪽을 바라보고 있으므로, 월드 y 방향이 로봇의 앞쪽이다. 컵은 로봇보다 위로 1m, 오른쪽으로 3m 떨어져 있다. 로봇 기준으로 표현하면 "앞쪽 1m, 오른쪽 3m"다.
우리 약속에서는 왼쪽이 y 양의 방향이므로, 오른쪽 3m는 -3으로 표현한다.
로봇 기준 컵 위치: 앞쪽 1m, 오른쪽 3m
즉, (1, -3)같은 컵이다. 월드 좌표는 같은 (5, 2)다. 하지만 로봇 기준 좌표는 로봇 방향에 따라 (3, 1)이 되기도 하고 (1, -3)이 되기도 한다.
이것이 좌표계의 핵심이다.
물체가 어디에 있는지는 하나의 사실이지만, 그 사실을 어떤 기준으로 표현하느냐에 따라 숫자는 달라진다.
로봇의 자세: 위치와 방향을 함께 표현하기
월드 좌표계에서 로봇을 표현하려면 위치만으로는 부족하다. 로봇은 "어디에 있는가"뿐 아니라 "어느 방향을 보고 있는가"도 중요하다.
2D 평면에서 로봇의 상태를 다음과 같이 표현해 보자.
robot_pose = [x, y, theta]여기서 x와 y는 월드 좌표계에서 로봇 중심의 위치다. theta는 로봇이 바라보는 방향이다. 보통 2D에서는 월드 x축 양의 방향을 기준으로 반시계 방향 회전을 양수로 둔다.
예를 들어 다음 자세를 생각해 보자.
robot_pose = [2.0, 1.0, 0.0]이것은 로봇이 월드 좌표 (2.0, 1.0)에 있고, 월드 x축 방향을 바라본다는 뜻이다. theta = 0이므로 회전하지 않은 상태다.
이번에는 다음 자세를 보자.
robot_pose = [2.0, 1.0, np.pi / 2]np.pi / 2는 90도다. 즉 로봇은 같은 위치에 있지만 위쪽, 다시 말해 월드 y축 양의 방향을 바라본다.
로봇의 자세를 x, y, theta로 표현하는 방식은 앞으로도 자주 등장한다. 이 세 값은 2D 이동 로봇의 가장 기본적인 상태 표현이다.
pose = 위치 + 방향
= (x, y, theta)로봇 기준 좌표를 월드 좌표로 바꾸기
이제 실제 계산을 해 보자.
로봇 기준으로 어떤 물체가 (1.0, 0.5)에 있다고 하자. 이것은 로봇 앞쪽 1m, 왼쪽 0.5m에 있다는 뜻이다.
그런데 지도 위에 이 물체를 그리려면 월드 좌표가 필요하다. 지도는 월드 좌표계로 표현되기 때문이다. 이때 필요한 것이 좌표 변환이다.
좌표 변환은 어려운 말처럼 들리지만, 본질은 단순하다.
"로봇 기준으로 본 점을 세상 기준으로 다시 말하기"
2D에서 로봇 기준 좌표를 월드 좌표로 바꾸려면 두 가지를 고려해야 한다.
첫째, 로봇이 어느 방향으로 회전해 있는지 반영해야 한다. 둘째, 로봇이 월드 좌표계에서 어디에 있는지 더해야 한다.
아직 회전 행렬을 본격적으로 배우지는 않았지만, 지금은 함수로 감각을 잡아 보자.
import numpy as np
def robot_to_world(point_robot, robot_pose):
"""로봇 기준 좌표를 월드 기준 좌표로 변환한다."""
x, y, theta = robot_pose
px, py = point_robot
c = np.cos(theta)
s = np.sin(theta)
world_x = x + c * px - s * py
world_y = y + s * px + c * py
return np.array([world_x, world_y])이 함수에서 point_robot은 로봇 기준 좌표다. robot_pose는 월드 기준에서 본 로봇의 자세다. 결과는 월드 기준 좌표다.
간단한 예제를 실행해 보자.
robot_pose = np.array([2.0, 1.0, 0.0])
point_robot = np.array([1.0, 0.5])
point_world = robot_to_world(point_robot, robot_pose)
print(point_world)결과는 다음과 같다.
[3. 1.5]로봇이 (2, 1)에 있고 오른쪽을 바라보고 있다. 로봇 기준 앞쪽 1m, 왼쪽 0.5m에 있는 점은 월드 기준으로 (3, 1.5)가 된다. 직관과 잘 맞는다.
이번에는 로봇이 90도 회전한 경우를 보자.
robot_pose = np.array([2.0, 1.0, np.pi / 2])
point_robot = np.array([1.0, 0.5])
point_world = robot_to_world(point_robot, robot_pose)
print(np.round(point_world, 3))결과는 대략 다음과 같다.
[1.5 2. ]로봇이 위쪽을 바라보고 있으므로, 로봇 기준 앞쪽 1m는 월드 y 방향으로 1m를 뜻한다. 로봇 기준 왼쪽 0.5m는 월드 x 방향으로는 왼쪽, 즉 x가 줄어드는 방향이다. 그래서 월드 좌표는 (1.5, 2.0)이 된다.
이 계산을 이해하면 센서 데이터를 지도 위에 올려놓는 첫 번째 감각을 얻은 것이다.
카메라나 LiDAR가 "장애물이 로봇 앞 2m, 왼쪽 0.4m에 있다"고 알려 주면, 로봇은 그 값을 바로 지도에 찍을 수 없다. 먼저 로봇의 현재 위치와 방향을 이용해 월드 좌표로 바꿔야 한다.
월드 좌표를 로봇 기준으로 바꾸기
반대 방향의 변환도 중요하다.
이번에는 지도 위에 목표점이 있다고 하자. 목표점의 월드 좌표는 (5, 2)다. 로봇은 월드 좌표 (2, 1)에 있다. 로봇이 목표를 향해 움직이려면 이런 질문에 답해야 한다.
"목표는 내 기준으로 앞에 있는가, 뒤에 있는가? 왼쪽에 있는가, 오른쪽에 있는가?"
목표가 월드 좌표로 주어졌다고 해서 로봇이 바로 바퀴 속도를 정할 수 있는 것은 아니다. 로봇 제어에는 로봇 기준 정보가 더 직접적일 때가 많다. 예를 들어 목표가 로봇 기준 왼쪽에 있으면 왼쪽으로 회전해야 하고, 오른쪽에 있으면 오른쪽으로 회전해야 한다.
월드 좌표를 로봇 좌표로 바꾸는 함수도 만들어 보자.
def world_to_robot(point_world, robot_pose):
"""월드 기준 좌표를 로봇 기준 좌표로 변환한다."""
x, y, theta = robot_pose
dx = point_world[0] - x
dy = point_world[1] - y
c = np.cos(theta)
s = np.sin(theta)
robot_x = c * dx + s * dy
robot_y = -s * dx + c * dy
return np.array([robot_x, robot_y])먼저 로봇이 월드 x축 방향을 바라보는 경우다.
robot_pose = np.array([2.0, 1.0, 0.0])
target_world = np.array([5.0, 2.0])
target_robot = world_to_robot(target_world, robot_pose)
print(target_robot)결과는 다음과 같다.
[3. 1.]목표는 로봇 기준 앞쪽 3m, 왼쪽 1m에 있다. 자연스럽다.
이번에는 로봇이 90도 회전해 위쪽을 바라보는 경우다.
robot_pose = np.array([2.0, 1.0, np.pi / 2])
target_world = np.array([5.0, 2.0])
target_robot = world_to_robot(target_world, robot_pose)
print(np.round(target_robot, 3))결과는 다음과 같다.
[ 1. -3.]이제 목표는 로봇 기준 앞쪽 1m, 오른쪽 3m에 있다. 같은 목표점인데 로봇이 바라보는 방향이 바뀌었기 때문에 로봇 기준 표현이 달라졌다.
이 변환은 앞으로 목표 추종 로봇을 만들 때 매우 유용하다. 목표점이 로봇 기준으로 왼쪽에 있는지 오른쪽에 있는지만 알아도, 로봇은 어느 방향으로 회전해야 할지 판단할 수 있다.
그림으로 확인하기
좌표 변환은 눈으로 확인하면 훨씬 쉽게 이해된다. Matplotlib으로 월드 좌표계, 로봇의 방향, 로봇 기준 점을 함께 그려 보자.
import numpy as np
import matplotlib.pyplot as plt
def robot_to_world(point_robot, robot_pose):
x, y, theta = robot_pose
px, py = point_robot
c = np.cos(theta)
s = np.sin(theta)
world_x = x + c * px - s * py
world_y = y + s * px + c * py
return np.array([world_x, world_y])
def draw_robot_frame(ax, robot_pose, length=0.8):
x, y, theta = robot_pose
# 로봇 x축: 앞쪽
forward = np.array([np.cos(theta), np.sin(theta)])
# 로봇 y축: 왼쪽
left = np.array([-np.sin(theta), np.cos(theta)])
ax.scatter(x, y, s=80, color="black")
ax.arrow(x, y, forward[0] * length, forward[1] * length,
head_width=0.12, color="red", length_includes_head=True)
ax.arrow(x, y, left[0] * length, left[1] * length,
head_width=0.12, color="blue", length_includes_head=True)
ax.text(x + 0.1, y - 0.2, "robot")
ax.text(x + forward[0] * length, y + forward[1] * length, "x_robot", color="red")
ax.text(x + left[0] * length, y + left[1] * length, "y_robot", color="blue")
robot_pose = np.array([2.0, 1.0, np.pi / 4])
point_robot = np.array([2.0, 0.8])
point_world = robot_to_world(point_robot, robot_pose)
fig, ax = plt.subplots(figsize=(6, 6))
draw_robot_frame(ax, robot_pose)
ax.scatter(point_world[0], point_world[1], s=80, color="green")
ax.text(point_world[0] + 0.1, point_world[1], "object")
ax.plot([robot_pose[0], point_world[0]],
[robot_pose[1], point_world[1]],
linestyle="--", color="gray")
ax.set_aspect("equal")
ax.set_xlim(0, 5)
ax.set_ylim(0, 5)
ax.grid(True)
ax.set_xlabel("world x")
ax.set_ylabel("world y")
ax.set_title("Robot Frame and World Frame")
plt.show()이 그림에서 빨간 화살표는 로봇의 앞쪽, 파란 화살표는 로봇의 왼쪽을 나타낸다. 초록색 점은 로봇 기준으로 (2.0, 0.8)에 있던 물체를 월드 좌표로 변환한 위치다.
중요한 것은 초록색 점이 로봇의 회전 방향에 맞춰 월드 공간에 배치된다는 점이다. 로봇이 회전하면 "앞쪽 2m, 왼쪽 0.8m"라는 같은 로봇 기준 좌표도 월드에서는 다른 위치가 된다.
robot_pose의 theta 값을 바꿔 보자.
robot_pose = np.array([2.0, 1.0, 0.0])
robot_pose = np.array([2.0, 1.0, np.pi / 2])
robot_pose = np.array([2.0, 1.0, np.pi])각도를 바꿀 때마다 로봇의 앞쪽과 왼쪽이 달라지고, 같은 로봇 기준 물체의 월드 위치도 달라진다. 이것이 좌표계가 살아 움직이는 느낌이다.
센서가 보는 좌표와 지도가 쓰는 좌표
좌표 변환이 왜 필요한지 가장 잘 보여 주는 곳은 센서다.
로봇에 달린 카메라, 초음파 센서, LiDAR는 대부분 로봇 또는 센서 자신을 기준으로 물체를 감지한다. 예를 들어 전방 카메라가 물체를 찾았을 때, 그 결과는 보통 이런 의미에 가깝다.
물체는 카메라 앞쪽에 있다.
물체는 카메라 중심보다 약간 왼쪽에 있다.
물체는 카메라에서 약 2m 떨어져 있다.이 정보는 센서 기준 또는 로봇 기준 정보다. 그런데 로봇이 지도를 만들거나 장애물 위치를 기록하려면 월드 기준 좌표가 필요하다.
반대로 목표점은 대개 지도 위에서 주어진다. "복도 끝의 문 앞으로 가라"는 명령은 월드 좌표계나 지도 좌표계에 가까운 정보다. 하지만 로봇이 실제로 움직이려면 목표가 자신의 앞쪽인지, 왼쪽인지, 오른쪽인지 알아야 한다.
그래서 로봇은 계속해서 좌표를 바꿔 말한다.
센서 측정값 → 로봇 기준 → 월드 기준
월드 목표점 → 로봇 기준 → 속도 명령이 과정이 자연스럽게 되면 로봇은 센서로 본 물체와 지도 위의 물체를 연결할 수 있다. 반대로 이 과정이 틀어지면 로봇은 같은 물체를 두 개의 다른 물체로 착각하거나, 목표와 반대 방향으로 움직일 수 있다.
좌표계를 헷갈리면 생기는 일
좌표계 오류는 로봇 프로그램에서 매우 흔하고, 동시에 찾기 까다로운 버그다. 숫자만 보면 그럴듯하기 때문이다.
예를 들어 카메라가 "장애물이 앞쪽 1m에 있다"고 알려 주었다고 하자. 이 값은 로봇 기준 좌표다. 그런데 프로그래머가 이 값을 그대로 월드 지도에 (1, 0)으로 찍어 버리면 어떻게 될까?
로봇이 원점에 있고 월드 x축 방향을 바라볼 때는 운 좋게 맞아 보일 수 있다. 하지만 로봇이 (5, 3)에 있거나 90도 회전해 있으면 완전히 틀린 위치에 장애물이 표시된다.
좌표계가 섞이면 다음과 같은 문제가 생긴다.
장애물이 실제 위치와 다른 곳에 지도화된다.
목표점이 왼쪽에 있는데 로봇이 오른쪽으로 회전한다.
센서 데이터가 로봇이 회전할 때마다 지도 위에서 빙글빙글 돈다.
경로 계획기는 안전하다고 판단하지만 실제 로봇은 장애물에 가까워진다.
이런 버그를 줄이려면 좌표를 다룰 때마다 스스로에게 질문해야 한다.
이 점은 어떤 좌표계 기준인가?
이 벡터는 월드 기준인가, 로봇 기준인가?
이 값을 더하거나 비교해도 되는가?
필요한 좌표 변환을 했는가?특히 서로 다른 좌표계의 벡터를 아무 생각 없이 더하면 안 된다. 월드 기준 벡터와 로봇 기준 벡터는 같은 숫자 모양을 하고 있어도 다른 언어로 쓰인 문장과 같다. 더하기 전에 같은 언어로 번역해야 한다.
작은 실험: 목표가 내 왼쪽인지 오른쪽인지 판단하기
이번에는 월드 좌표계의 목표점을 로봇 기준으로 바꾼 뒤, 목표가 왼쪽에 있는지 오른쪽에 있는지 판단해 보자.
import numpy as np
def world_to_robot(point_world, robot_pose):
x, y, theta = robot_pose
dx = point_world[0] - x
dy = point_world[1] - y
c = np.cos(theta)
s = np.sin(theta)
robot_x = c * dx + s * dy
robot_y = -s * dx + c * dy
return np.array([robot_x, robot_y])
robot_pose = np.array([2.0, 1.0, np.pi / 4])
target_world = np.array([4.0, 3.0])
target_robot = world_to_robot(target_world, robot_pose)
print("로봇 기준 목표 위치:", np.round(target_robot, 3))
if target_robot[1] > 0:
print("목표는 로봇의 왼쪽에 있습니다.")
elif target_robot[1] < 0:
print("목표는 로봇의 오른쪽에 있습니다.")
else:
print("목표는 로봇의 정면 또는 후방 축 위에 있습니다.")여기서 target_robot[1]은 로봇 기준 y좌표다. 우리는 로봇의 왼쪽을 y 양의 방향으로 약속했으므로, 이 값이 양수이면 목표는 왼쪽에 있다. 음수이면 오른쪽에 있다.
이 판단은 매우 단순해 보이지만, 로봇 제어의 중요한 출발점이다. 목표가 왼쪽이면 왼쪽으로 회전하고, 오른쪽이면 오른쪽으로 회전하면 된다. 다음 장에서 배울 각도 계산과 atan2를 결합하면 목표를 향해 정확히 회전하는 로봇을 만들 수 있다.
좌표계 이름을 변수에 드러내기
좌표계를 헷갈리지 않는 좋은 습관이 있다. 변수 이름에 좌표계를 드러내는 것이다.
예를 들어 다음과 같은 변수 이름은 위험하다.
point = np.array([1.0, 0.5])
target = np.array([5.0, 2.0])이 좌표가 월드 기준인지 로봇 기준인지 알 수 없다. 코드가 짧을 때는 괜찮아 보여도, 시뮬레이션이 커질수록 헷갈리기 쉽다.
조금 더 좋은 이름은 다음과 같다.
point_robot = np.array([1.0, 0.5])
target_world = np.array([5.0, 2.0])
target_robot = world_to_robot(target_world, robot_pose)이렇게 쓰면 코드 자체가 작은 설명서가 된다. target_world는 월드 기준 목표점이고, target_robot은 로봇 기준으로 변환된 목표점이다.
좌표 변환 함수 이름도 마찬가지다.
robot_to_world(point_robot, robot_pose)
world_to_robot(point_world, robot_pose)함수 이름만 읽어도 어떤 좌표계에서 어떤 좌표계로 변환하는지 알 수 있다. 로봇 코드는 좌표계가 많아질수록 복잡해진다. 지금부터 이름을 명확히 붙이는 습관을 들이면 나중에 카메라 좌표계, 센서 좌표계, 지도 좌표계를 다룰 때 큰 도움이 된다.
좌표 변환은 번역이다
이번 장에서 가장 중요한 비유는 "좌표 변환은 번역"이라는 것이다.
월드 좌표계는 세상의 언어다. 지도, 목표점, 전역 경로는 보통 이 언어를 사용한다. 로봇 좌표계는 로봇 몸의 언어다. 센서 측정, 전방 장애물, 왼쪽 목표, 오른쪽 회전 같은 표현은 이 언어에 가깝다.
같은 물체라도 월드 언어로는 (5, 2)일 수 있고, 로봇 언어로는 (1, -3)일 수 있다. 둘 중 하나가 더 진짜인 것은 아니다. 상황에 따라 필요한 표현이 다를 뿐이다.
로봇은 이 두 언어를 계속 오가야 한다. 센서로 본 물체를 지도에 올릴 때는 로봇 기준을 월드 기준으로 번역한다. 지도 위 목표를 향해 움직일 때는 월드 기준을 로봇 기준으로 번역한다.
이 번역 능력이 생기면 로봇은 비로소 자신이 보는 것과 세상 속 위치를 연결할 수 있다.
정리
이번 장에서는 로봇 좌표계와 월드 좌표계를 구분했다.
월드 좌표계는 세상에 고정된 기준이다. 지도, 목표점, 장애물의 전역 위치를 표현할 때 사용한다. 로봇이 움직이거나 회전해도 월드 좌표계 자체는 변하지 않는다고 생각한다.
로봇 좌표계는 로봇 몸에 붙은 기준이다. 로봇 중심을 원점으로 두고, 로봇의 앞쪽을 x축 양의 방향, 왼쪽을 y축 양의 방향으로 약속했다. 로봇이 움직이면 원점도 움직이고, 로봇이 회전하면 축도 함께 회전한다.
같은 물체라도 기준 좌표계에 따라 숫자가 달라진다. 월드 좌표로는 같은 위치에 있는 컵도, 로봇이 어느 방향을 바라보느냐에 따라 로봇 기준 좌표는 달라진다.
또한 센서 측정값을 지도 위에 표시하려면 로봇 기준 좌표를 월드 좌표로 변환해야 한다. 반대로 지도 위 목표점을 보고 로봇이 어떻게 움직일지 판단하려면 월드 좌표를 로봇 기준 좌표로 변환해야 한다.
다음 장에서는 이 감각을 바탕으로 두 점 사이의 거리와 각도를 계산한다. 특히 atan2를 사용해 목표가 어느 방향에 있는지 구하고, 로봇이 목표를 향해 회전하는 방법을 배울 것이다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.