로봇의 첫 번째 질문: 나는 어디에 있는가
로봇이 움직이기 전에 가장 먼저 알아야 하는 것은 무엇일까? 모터를 얼마나 세게 돌릴지, 카메라로 무엇을 볼지, 장애물을 어떻게 피할지보다 더 앞서는 질문이 있다.
"나는 어디에 있는가?"
로봇공학의 많은 문제는 이 질문에서 출발한다. 이동 로봇이 복도를 따라 움직일 때도, 드론이 공중에서 자세를 잡을 때도, 로봇 팔이 컵을 집으려 할 때도 결국 핵심은 위치다. 위치를 모르면 목표와의 차이를 알 수 없고, 차이를 모르면 움직일 방향도 정할 수 없다.
그런데 위치는 그냥 존재하지 않는다. 위치는 항상 어떤 기준을 정했을 때 숫자로 표현된다. 예를 들어 "로봇이 오른쪽에 있다"라는 말은 누가 봐도 대략 이해할 수 있지만, 로봇에게 명령하기에는 부족하다. 로봇은 이런 식의 표현을 더 좋아한다.
로봇의 위치 = x = 2.0 m
목표의 위치 = x = 5.0 m이제 로봇은 계산할 수 있다. 목표는 현재 위치보다 3.0 m 오른쪽에 있다. 그러므로 오른쪽으로 이동하면 된다.
이 단순한 감각이 앞으로 나올 좌표 변환, 회전 행렬, 경로 추종, 위치 추정의 출발점이다. 복잡한 로봇 수학도 결국 "위치를 숫자로 어떻게 표현할 것인가"에서 시작한다.

위치는 기준점이 있어야 숫자가 된다
위치를 숫자로 표현하려면 먼저 기준점이 필요하다. 기준점은 보통 원점이라고 부른다. 원점은 좌표의 출발점이다.
책상 위에 작은 로봇을 올려놓았다고 생각해 보자. 책상의 왼쪽 아래 모서리를 기준점으로 정하면, 로봇의 위치는 그 모서리에서 얼마나 떨어져 있는지로 표현할 수 있다. 반대로 책상 중앙을 기준점으로 정하면 같은 로봇도 전혀 다른 숫자로 표현된다.
중요한 사실은 이것이다.
위치 숫자는 물체 자체에 붙어 있는 절대적인 값이 아니라, 우리가 정한 기준점과 축에 따라 달라지는 값이다.
그래서 로봇을 다룰 때는 늘 다음 세 가지를 의식해야 한다.
기준점, 즉 원점이 어디인지
어느 방향을 양수로 볼 것인지
숫자의 단위가 미터인지, 센티미터인지, 픽셀인지
이 세 가지가 정해지면 비로소 위치를 숫자로 말할 수 있다. 이제 가장 단순한 1차원부터 시작해 보자.
1차원 위치: 선 위에서 앞과 뒤를 구분하기
1차원 위치는 하나의 선 위에서 위치를 표현하는 방식이다. 엘리베이터가 위아래로 움직이는 상황, 컨베이어 벨트 위의 물체, 직선 레일을 따라 이동하는 로봇을 떠올리면 된다.
직선 위에 원점을 하나 정한다. 그리고 오른쪽을 양수 방향으로 정해 보자.
<---- -3 ---- -2 ---- -1 ---- 0 ---- 1 ---- 2 ---- 3 ---->
원점이제 어떤 물체가 원점보다 오른쪽에 있으면 양수로 표현된다. 원점보다 왼쪽에 있으면 음수로 표현된다.
로봇 위치: x = 2.0
목표 위치: x = -1.0이 말은 로봇이 원점에서 오른쪽으로 2.0만큼 떨어져 있고, 목표는 원점에서 왼쪽으로 1.0만큼 떨어져 있다는 뜻이다.
Python으로 표현하면 아주 간단하다.
robot_x = 2.0
target_x = -1.0
move = target_x - robot_x
print(move)실행 결과는 다음과 같다.
-3.0target_x - robot_x는 현재 로봇 위치에서 목표 위치까지 가기 위해 얼마나 이동해야 하는지를 뜻한다. 결과가 -3.0이므로 로봇은 음수 방향, 즉 왼쪽으로 3.0만큼 이동해야 한다.
여기서 중요한 감각이 하나 생긴다. 두 위치의 차이는 이동을 뜻한다.
현재 위치 = 2.0
목표 위치 = -1.0
목표 - 현재 = -3.0위치 자체는 "어디에 있는가"를 나타내고, 위치의 차이는 "어디로 얼마나 움직여야 하는가"를 나타낸다.
1차원에서는 위치가 숫자 하나뿐이다. 하지만 로봇이 실제로 움직이는 바닥은 보통 선이 아니라 평면이다. 이제 숫자가 하나 더 필요해진다.
2차원 위치: 바닥 위의 점을 x, y로 표현하기
이동 로봇이 실내 바닥을 돌아다닌다고 생각해 보자. 로봇은 앞뒤로만 움직이는 것이 아니라 왼쪽과 오른쪽으로도 위치가 달라질 수 있다. 이때는 위치를 숫자 하나로 표현할 수 없다.
평면에서는 두 개의 숫자가 필요하다.
위치 = (x, y)x는 가로 방향 위치를 나타내고, y는 세로 방향 위치를 나타낸다. 예를 들어 다음 위치를 보자.
로봇 위치 = (2.0, 1.0)이것은 원점에서 x 방향으로 2.0, y 방향으로 1.0만큼 떨어진 곳에 로봇이 있다는 뜻이다.
평면 좌표를 머릿속으로 그려 보면 다음과 같다.
y
↑
|
3|
2|
1| ● robot (2, 1)
0+--------------------→ x
0 1 2 3 4Python에서는 2차원 위치를 리스트나 튜플로 표현할 수도 있지만, 계산을 생각하면 NumPy 배열을 사용하는 것이 편하다.
import numpy as np
robot = np.array([2.0, 1.0])
target = np.array([5.0, 4.0])
move = target - robot
print(move)결과는 다음과 같다.
[3. 3.]이 결과는 로봇이 목표에 도달하려면 x 방향으로 3.0, y 방향으로 3.0 이동해야 한다는 뜻이다.
1차원에서는 이동이 숫자 하나였다. 2차원에서는 이동이 숫자 두 개가 된다. 이처럼 여러 숫자를 묶어서 방향과 크기를 함께 표현하는 대상을 벡터라고 부른다.
아직 벡터를 어렵게 생각할 필요는 없다. 지금은 이렇게 이해하면 충분하다.
2차원 위치 벡터 = [x, y]
2차원 이동 벡터 = [dx, dy]위치 벡터는 원점에서 어떤 점까지의 위치를 나타낸다. 이동 벡터는 한 점에서 다른 점으로 가는 변화를 나타낸다. 둘 다 [숫자, 숫자] 모양으로 생겼지만 의미가 다르다.
2차원 위치를 그림으로 확인하기
좌표는 그림으로 보면 훨씬 빨리 익숙해진다. 앞에서 만든 로봇 위치와 목표 위치를 Matplotlib으로 그려 보자.
import numpy as np
import matplotlib.pyplot as plt
robot = np.array([2.0, 1.0])
target = np.array([5.0, 4.0])
move = target - robot
plt.figure(figsize=(6, 6))
plt.scatter(robot[0], robot[1], s=120, label="robot")
plt.scatter(target[0], target[1], s=120, label="target")
plt.arrow(
robot[0], robot[1],
move[0], move[1],
head_width=0.15,
length_includes_head=True,
color="tab:orange"
)
plt.text(robot[0] + 0.1, robot[1], "robot")
plt.text(target[0] + 0.1, target[1], "target")
plt.xlim(0, 6)
plt.ylim(0, 6)
plt.gca().set_aspect("equal", adjustable="box")
plt.grid(True)
plt.legend()
plt.show()이 그림에서 점 하나는 위치를 뜻하고, 화살표는 이동을 뜻한다. 로봇 위치에서 목표 위치까지 그은 화살표가 바로 target - robot이다.
이 계산은 로봇공학에서 정말 자주 등장한다. 목표점으로 이동하기, 장애물까지의 상대 위치 구하기, 카메라가 본 물체의 위치를 로봇 기준으로 바꾸기, 경로 위의 다음 지점으로 향하기 같은 작업이 모두 이 감각 위에 놓인다.
x와 y는 약속이다
좌표를 처음 배울 때 은근히 헷갈리는 부분이 있다. 바로 x축과 y축의 방향이다.
수학 그래프에서는 보통 x축이 오른쪽, y축이 위쪽을 향한다. 하지만 화면 좌표에서는 y축이 아래쪽으로 증가하는 경우가 많다. 이미지에서 픽셀 위치를 다룰 때는 왼쪽 위가 원점이고, 오른쪽으로 갈수록 x가 커지고, 아래로 내려갈수록 y가 커지는 방식이 흔하다.
예를 들어 수학 좌표에서는 위로 올라가면 y가 커진다.
수학 좌표:
오른쪽: x 증가
위쪽: y 증가하지만 이미지 좌표에서는 아래로 내려가면 y가 커질 수 있다.
이미지 좌표:
오른쪽: x 증가
아래쪽: y 증가둘 중 어느 하나가 절대적으로 옳은 것은 아니다. 중요한 것은 약속을 분명히 하는 것이다. 로봇은 약속을 모호하게 이해하지 못한다. 우리가 원점을 어디에 두었는지, 축이 어느 방향으로 증가하는지 정확히 정해 주어야 한다.
나중에 카메라 좌표와 로봇 좌표를 변환할 때 이 차이가 중요해진다. 같은 물체를 보고 있어도 좌표계가 다르면 숫자가 다르게 나오기 때문이다.
3차원 위치: 공간 속의 점을 x, y, z로 표현하기
2차원 평면에서는 [x, y] 두 개의 숫자로 위치를 표현했다. 하지만 실제 세계는 평면이 아니라 공간이다. 로봇 팔의 손끝은 위아래로도 움직이고, 드론은 높이를 바꾸며 날아다니고, 카메라는 물체가 얼마나 멀리 있는지도 알아야 한다.
3차원 위치는 세 개의 숫자로 표현한다.
위치 = (x, y, z)여기서 z는 보통 높이 또는 깊이 방향을 나타낸다. 예를 들어 로봇 팔의 손끝 위치가 다음과 같다고 하자.
손끝 위치 = (0.4, 0.2, 0.7)단위가 미터라면, 이 손끝은 원점에서 x 방향으로 0.4 m, y 방향으로 0.2 m, z 방향으로 0.7 m 떨어진 곳에 있다는 뜻이다.
Python에서는 3차원 위치도 NumPy 배열로 표현할 수 있다.
import numpy as np
end_effector = np.array([0.4, 0.2, 0.7])
object_pos = np.array([0.6, -0.1, 0.5])
move = object_pos - end_effector
print(move)결과는 다음과 같다.
[ 0.2 -0.3 -0.2]이 이동 벡터는 손끝이 물체 위치로 가기 위해 x 방향으로 0.2, y 방향으로 -0.3, z 방향으로 -0.2만큼 이동해야 한다는 뜻이다.
3차원에서도 원리는 같다. 위치는 원점에서 점까지의 숫자 묶음이고, 두 위치의 차이는 한 점에서 다른 점으로 가는 이동이다.
로봇 팔과 카메라에서 3차원 좌표가 필요한 이유
바닥을 돌아다니는 2D 이동 로봇은 처음에는 [x, y]만으로도 많은 것을 설명할 수 있다. 하지만 로봇 팔이나 카메라가 등장하면 이야기가 달라진다.
로봇 팔이 컵을 집으려면 손끝이 컵의 중심에 가까워져야 한다. 이때 컵이 왼쪽에 있는지 오른쪽에 있는지만 알아서는 부족하다. 컵이 테이블 위에 있는지, 공중에 떠 있는지, 손끝보다 높은지 낮은지도 알아야 한다.
cup = np.array([0.5, 0.1, 0.3])
gripper = np.array([0.2, 0.1, 0.6])
to_cup = cup - gripper
print(to_cup)결과가 다음과 같다면,
[ 0.3 0. -0.3]그리퍼는 x 방향으로 0.3 이동하고, y 방향으로는 그대로 있으며, z 방향으로 0.3 내려가야 컵 위치에 가까워진다.
카메라도 마찬가지다. 카메라가 물체를 본다는 것은 단순히 이미지 안의 픽셀 위치만 얻는 것이 아니다. 깊이 카메라나 3D 센서를 사용하면 물체가 카메라 기준으로 어느 방향에 있고 얼마나 떨어져 있는지도 숫자로 표현할 수 있다.
카메라 기준 물체 위치 = [0.2, -0.1, 1.5]이 값은 물체가 카메라의 기준 좌표계에서 x 방향으로 0.2, y 방향으로 -0.1, z 방향으로 1.5 떨어져 있다는 뜻으로 해석할 수 있다. 다만 실제 카메라 좌표계에서는 축의 방향이 장비와 소프트웨어에 따라 다를 수 있다. 그래서 3D 위치를 다룰 때도 항상 "어떤 기준에서 본 좌표인가?"를 함께 생각해야 한다.
위치 벡터와 이동 벡터는 모양은 같지만 의미가 다르다
다음 두 배열을 보자.
p = np.array([2.0, 1.0])
v = np.array([2.0, 1.0])숫자만 보면 둘은 완전히 같다. 하지만 p를 위치로 해석하면 원점에서 (2.0, 1.0)에 있는 점을 뜻한다. 반면 v를 이동으로 해석하면 x 방향으로 2.0, y 방향으로 1.0만큼 움직이는 변화를 뜻한다.
로봇공학에서는 이 차이가 중요하다. 위치는 "어디"이고, 이동은 "얼마나 변했는가"다.
예를 들어 로봇이 다음 위치에 있다고 하자.
robot = np.array([1.0, 1.0])
move = np.array([2.0, 1.0])
new_robot = robot + move
print(new_robot)결과는 다음과 같다.
[3. 2.]여기서 robot은 위치이고, move는 이동이다. 위치에 이동을 더하면 새로운 위치가 된다.
새 위치 = 현재 위치 + 이동반대로 두 위치를 빼면 이동이 된다.
이동 = 목표 위치 - 현재 위치이 두 식은 로봇 시뮬레이션의 심장처럼 계속 반복된다.
여러 위치를 한 번에 저장하기
로봇은 보통 위치 하나만 다루지 않는다. 이동 경로에는 여러 점이 있고, 지도에는 여러 장애물이 있으며, 센서에는 여러 물체가 잡힌다. 따라서 여러 위치를 한 번에 저장하고 계산하는 방법이 필요하다.
2차원 위치 여러 개는 NumPy 배열 하나에 담을 수 있다.
import numpy as np
points = np.array([
[0.0, 0.0],
[1.0, 2.0],
[3.0, 1.0],
[4.0, 4.0]
])
print(points)
print(points.shape)결과는 다음과 같다.
[[0. 0.]
[1. 2.]
[3. 1.]
[4. 4.]]
(4, 2)shape가 (4, 2)라는 것은 위치가 4개 있고, 각 위치가 2개의 숫자, 즉 x와 y로 이루어져 있다는 뜻이다.
각 점의 x 좌표만 꺼내고 싶다면 다음처럼 쓴다.
xs = points[:, 0]
ys = points[:, 1]
print(xs)
print(ys)[0. 1. 3. 4.]
[0. 2. 1. 4.]points[:, 0]은 모든 행에서 첫 번째 열을 꺼낸다. 여기서는 모든 점의 x 좌표다. points[:, 1]은 모든 점의 y 좌표다.
이 방식은 궤적을 그릴 때 아주 유용하다.
import matplotlib.pyplot as plt
plt.figure(figsize=(6, 6))
plt.plot(points[:, 0], points[:, 1], marker="o")
plt.xlim(-1, 5)
plt.ylim(-1, 5)
plt.gca().set_aspect("equal", adjustable="box")
plt.grid(True)
plt.show()점들이 선으로 이어지면 로봇이 지나간 경로처럼 보인다. 앞으로 경로 추종을 만들 때 이런 식으로 여러 위치를 저장하고 시각화하게 된다.
로봇에서 여러 목표점까지의 이동 벡터 구하기
이번에는 로봇 하나와 여러 목표점이 있다고 생각해 보자. 로봇은 현재 [1.0, 1.0]에 있고, 목표 후보가 여러 개 있다.
robot = np.array([1.0, 1.0])
targets = np.array([
[2.0, 3.0],
[4.0, 1.0],
[0.0, 5.0]
])
moves = targets - robot
print(moves)결과는 다음과 같다.
[[ 1. 2.]
[ 3. 0.]
[-1. 4.]]여기서 첫 번째 이동 벡터 [1.0, 2.0]은 첫 번째 목표로 가려면 x 방향으로 1.0, y 방향으로 2.0 움직여야 한다는 뜻이다. 두 번째 이동 벡터 [3.0, 0.0]은 오른쪽으로만 3.0 움직이면 된다는 뜻이다. 세 번째 이동 벡터 [-1.0, 4.0]은 왼쪽으로 1.0, 위쪽으로 4.0 움직여야 한다는 뜻이다.
여기서 NumPy는 robot 배열 하나를 targets의 각 행에 맞춰 자동으로 빼 준다. 이전에 다룬 브로드캐스팅이 자연스럽게 쓰인 것이다. 로봇공학에서는 이런 계산을 자주 한다. 센서가 여러 물체를 감지했을 때, 로봇에서 각 물체까지의 상대 위치를 한 번에 구할 수 있기 때문이다.
그림으로도 확인해 보자.
import numpy as np
import matplotlib.pyplot as plt
robot = np.array([1.0, 1.0])
targets = np.array([
[2.0, 3.0],
[4.0, 1.0],
[0.0, 5.0]
])
moves = targets - robot
plt.figure(figsize=(6, 6))
plt.scatter(robot[0], robot[1], s=150, label="robot")
plt.scatter(targets[:, 0], targets[:, 1], s=100, label="targets")
for move in moves:
plt.arrow(
robot[0], robot[1],
move[0], move[1],
head_width=0.12,
length_includes_head=True,
alpha=0.7
)
plt.xlim(-1, 5)
plt.ylim(0, 6)
plt.gca().set_aspect("equal", adjustable="box")
plt.grid(True)
plt.legend()
plt.show()그림을 보면 로봇에서 각 목표점으로 뻗어 나가는 화살표가 보인다. 이 화살표들이 바로 이동 벡터다. 로봇이 어디로 갈지 판단하려면 먼저 이런 벡터를 계산해야 한다.
3차원 위치 여러 개 저장하기
3차원에서도 같은 방식이 통한다. 로봇 팔 주변에 물체가 여러 개 있다고 하자.
objects = np.array([
[0.3, 0.2, 0.1],
[0.5, -0.1, 0.2],
[0.4, 0.3, 0.5]
])
print(objects.shape)결과는 다음과 같다.
(3, 3)(3, 3)은 물체가 3개 있고, 각 물체의 위치가 x, y, z 세 값으로 표현된다는 뜻이다.
로봇 팔의 손끝 위치가 다음과 같다면,
gripper = np.array([0.2, 0.0, 0.3])
to_objects = objects - gripper
print(to_objects)결과는 다음처럼 나온다.
[[ 0.1 0.2 -0.2]
[ 0.3 -0.1 -0.1]
[ 0.2 0.3 0.2]]각 행은 손끝에서 해당 물체까지의 이동 벡터다. 이 값들을 바탕으로 로봇 팔은 어떤 물체가 가까운지, 어떤 방향으로 손끝을 움직여야 하는지 판단할 수 있다.
지금은 단순히 뺄셈만 했다. 하지만 이 뺄셈 하나가 로봇 팔 제어, 카메라 인식, 물체 집기 작업의 첫걸음이 된다.
좌표를 다룰 때 자주 생기는 실수
위치를 숫자로 표현하는 일은 단순해 보이지만, 실제 로봇 프로그램에서는 작은 약속 하나가 어긋나도 로봇이 엉뚱한 방향으로 움직일 수 있다. 특히 다음 실수를 조심해야 한다.
원점이 어디인지 정하지 않고 좌표를 사용한다.
x, y, z축의 양수 방향을 확인하지 않는다.
미터, 센티미터, 밀리미터, 픽셀 같은 단위를 섞어 쓴다.
예를 들어 로봇 위치는 미터 단위인데 목표 위치는 센티미터 단위라면 어떻게 될까? 로봇은 1.0 m를 1.0 cm처럼 해석하거나, 반대로 100 cm를 100 m처럼 해석할 수 있다. 숫자는 맞아 보이지만 실제 의미는 완전히 달라진다.
또 하나의 흔한 실수는 이미지 좌표와 수학 좌표를 섞는 것이다. 화면에서는 아래로 내려갈수록 y가 커지는데, 로봇 바닥 좌표에서는 위쪽으로 갈수록 y가 커진다고 가정하면 로봇이 목표와 반대 방향으로 움직일 수 있다.
좌표는 숫자이지만, 숫자만으로는 충분하지 않다. 숫자가 어떤 기준과 단위를 가진 숫자인지 함께 생각해야 한다.
작은 실험: 위치에 이동을 더해 궤적 만들기
마지막으로 위치와 이동 벡터를 이용해 간단한 궤적을 만들어 보자. 로봇이 처음에 [0.0, 0.0]에 있고, 여러 이동 명령을 차례대로 받는 상황이다.
import numpy as np
import matplotlib.pyplot as plt
position = np.array([0.0, 0.0])
commands = np.array([
[1.0, 0.0],
[1.0, 1.0],
[0.0, 1.0],
[-1.0, 0.5],
[0.5, -1.0]
])
trajectory = [position.copy()]
for command in commands:
position = position + command
trajectory.append(position.copy())
trajectory = np.array(trajectory)
print(trajectory)결과는 다음과 비슷하다.
[[0. 0. ]
[1. 0. ]
[2. 1. ]
[2. 2. ]
[1. 2.5]
[1.5 1.5]]각 행은 로봇이 지나간 위치다. 이동 명령을 하나씩 더할 때마다 새로운 위치가 만들어졌다.
이제 그림으로 그려 보자.
plt.figure(figsize=(6, 6))
plt.plot(trajectory[:, 0], trajectory[:, 1], marker="o")
for i, point in enumerate(trajectory):
plt.text(point[0] + 0.05, point[1] + 0.05, str(i))
plt.xlim(-1, 3)
plt.ylim(-1, 3)
plt.gca().set_aspect("equal", adjustable="box")
plt.grid(True)
plt.show()이 코드는 로봇의 이동 기록을 점과 선으로 보여 준다. 처음 위치에서 시작해 이동 벡터를 하나씩 더하면 궤적이 된다. 이전에 만든 첫 번째 로봇 시뮬레이터도 결국 이 원리를 사용했다. 현재 위치가 있고, 이동량을 계산하고, 그 이동량을 현재 위치에 더해 다음 위치를 만든다.
현재 위치 + 이동 = 다음 위치이 식을 정말 잘 이해하면 로봇의 움직임이 훨씬 선명하게 보인다.
위치 표현의 핵심 정리
로봇이 판단하고 움직이려면 먼저 위치를 숫자로 표현해야 한다. 1차원에서는 숫자 하나로 선 위의 위치를 나타내고, 2차원에서는 [x, y]로 평면 위의 위치를 나타내며, 3차원에서는 [x, y, z]로 공간 속의 위치를 나타낸다.
위치를 표현할 때는 반드시 기준점이 필요하다. 원점이 어디인지, 축이 어느 방향으로 증가하는지, 단위가 무엇인지가 정해져야 숫자가 의미를 가진다.
또한 두 위치의 차이는 이동 벡터가 된다.
이동 벡터 = 목표 위치 - 현재 위치
다음 위치 = 현재 위치 + 이동 벡터이 두 식은 앞으로 계속 등장한다. 목표를 향해 움직이는 로봇도, 여러 센서값을 합치는 로봇도, 지도 위에서 자신의 위치를 추정하는 로봇도 결국 위치와 이동을 계산한다.
다음 단계에서는 벡터가 가진 방향과 크기를 더 자세히 살펴볼 것이다. 로봇이 "목표가 어디에 있는지"를 알았다면, 이제는 "어느 방향으로 얼마나 가야 하는지"를 이해해야 한다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.