벡터는 화살표다
지난 장에서 우리는 위치를 숫자로 표현했다. 2차원 평면에서 로봇의 위치는 [x, y]처럼 나타낼 수 있었다. 예를 들어 로봇이 [2, 1]에 있다면, 원점에서 오른쪽으로 2만큼, 위로 1만큼 떨어진 곳에 있다는 뜻이다.
그런데 로봇은 가만히 위치만 갖고 있지 않다. 로봇은 움직인다. 그리고 움직임을 이해하려면 위치보다 한 단계 더 중요한 질문을 해야 한다.
"어느 방향으로?"
"얼마나 빠르게?"
이 두 질문에 답하는 도구가 바로 벡터다. 벡터는 단순한 숫자 묶음이 아니라, 방향과 크기를 함께 가진 화살표라고 생각하면 된다. [3, 4]라는 벡터는 x방향으로 3, y방향으로 4만큼 향하는 화살표다. 이 화살표는 오른쪽 위를 향하고 있으며, 길이는 5다.
로봇에게 벡터는 매우 자연스러운 언어다. 목표가 어디에 있는지, 얼마나 떨어져 있는지, 어느 방향으로 움직여야 하는지, 속도를 어떻게 줄 것인지가 모두 벡터 계산으로 이어진다. 겉보기에는 수학처럼 보이지만, 실제로는 로봇이 길을 찾기 위해 매 순간 던지는 질문에 가깝다.
이번 장에서는 벡터의 두 가지 핵심 성질인 크기와 방향을 다룬다. 그리고 마지막에는 현재 위치에서 목표 위치를 바라보는 방향 벡터를 만들고, 그 방향으로 로봇을 움직이는 속도 벡터까지 계산해 볼 것이다.

벡터의 크기는 거리다
먼저 벡터의 크기부터 생각해 보자. 벡터 [3, 4]가 있다고 하자. 이 벡터는 x방향으로 3, y방향으로 4만큼 이동하는 화살표다. 그렇다면 이 화살표 자체의 길이는 얼마일까?
직각삼각형을 떠올리면 쉽다. 밑변이 3, 높이가 4인 삼각형의 빗변 길이가 바로 벡터의 크기다.
크기 = sqrt(32 + 42) = 5
이 값은 로봇공학에서 여러 의미로 해석된다. 위치 차이 벡터의 크기라면 두 점 사이의 거리다. 속도 벡터의 크기라면 로봇의 속력이다. 힘 벡터의 크기라면 힘의 세기다.
즉, 벡터의 크기는 "화살표가 얼마나 긴가?"에 대한 답이다.
Python으로 계산해 보자.
import numpy as np
v = np.array([3.0, 4.0])
length = np.linalg.norm(v)
print(length)실행하면 다음 값이 나온다.
5.0여기서 np.linalg.norm()은 벡터의 크기를 계산해 주는 NumPy 함수다. norm은 노름이라고 읽는다. 이름은 조금 낯설지만, 지금 단계에서는 "벡터의 길이를 구하는 함수"라고 이해하면 충분하다.
직접 계산해도 같은 결과가 나온다.
x = v[0]
y = v[1]
length_manual = np.sqrt(x2 + y2)
print(length_manual)결과는 역시 5.0이다. 2차원 벡터 [x, y]의 크기는 sqrt(x2 + y2)로 계산한다. 3차원 벡터 [x, y, z]라면 sqrt(x2 + y2 + z**2)가 된다.
v3 = np.array([2.0, 3.0, 6.0])
print(np.linalg.norm(v3))NumPy의 좋은 점은 차원이 늘어나도 같은 함수로 처리할 수 있다는 것이다. 2D 로봇이든, 3D 드론이든, 로봇팔의 관절 공간이든 "벡터의 크기"라는 생각은 그대로 유지된다.
거리도 벡터의 크기다
두 위치가 있다고 하자.
robot_pos = np.array([1.0, 2.0])
target_pos = np.array([7.0, 5.0])로봇은 [1, 2]에 있고, 목표는 [7, 5]에 있다. 두 점 사이의 거리를 구하고 싶다. 이때 바로 거리를 계산하려고 공식부터 외울 필요는 없다. 먼저 "로봇에서 목표까지 가려면 얼마나 이동해야 하지?"라고 생각하면 된다.
목표 위치에서 현재 위치를 빼면 된다.
to_target = target_pos - robot_pos
print(to_target)결과는 다음과 같다.
[6. 3.]이 벡터는 로봇 위치에서 목표 위치까지 향하는 화살표다. x방향으로 6만큼, y방향으로 3만큼 가면 목표에 도착한다는 뜻이다.
이제 이 화살표의 크기를 구하면 두 점 사이의 거리가 된다.
distance = np.linalg.norm(to_target)
print(distance)결과는 약 6.708이다. 로봇은 목표에서 직선거리로 약 6.7만큼 떨어져 있다.
여기서 아주 중요한 감각을 잡아야 한다. 거리 공식은 따로 떨어져 있는 공식이 아니다. 두 위치의 차이를 벡터로 만들고, 그 벡터의 크기를 구한 것이 거리다.
거리 = 목표 위치 - 현재 위치의 크기수학 기호로 외우기보다 이렇게 기억하는 편이 훨씬 오래 간다. 로봇 입장에서 말하면 더 쉽다.
"목표가 나를 기준으로 어디에 있지? 그 화살표는 얼마나 길지?"
그 답이 방향과 거리다.
속력과 속도는 다르다
일상에서는 "속도"와 "속력"을 거의 같은 뜻으로 쓰지만, 로봇을 제어할 때는 둘을 구분하면 생각이 훨씬 선명해진다.
속력은 빠르기의 크기만 말한다. 예를 들어 "초당 1미터로 이동한다"는 말은 속력이다. 방향 정보는 없다.
반면 속도 벡터는 방향과 빠르기를 함께 가진다. 예를 들어 [1.0, 0.0]은 x방향으로 초당 1만큼 움직인다는 뜻이다. [0.0, 1.0]은 y방향으로 초당 1만큼 움직인다는 뜻이다. [0.7, 0.7]은 오른쪽 위 방향으로 움직인다는 뜻이다.
즉, 속력은 숫자 하나이고, 속도는 벡터다.
speed = 1.0
velocity = np.array([1.0, 0.0])여기서 speed는 "얼마나 빠르게"만 말한다. velocity는 "어느 방향으로 얼마나 빠르게"를 말한다.
속도 벡터의 크기를 구하면 속력이 된다.
velocity = np.array([0.6, 0.8])
speed = np.linalg.norm(velocity)
print(speed)결과는 다음과 같다.
1.0[0.6, 0.8]이라는 속도 벡터는 오른쪽 위 방향을 향하고 있고, 그 크기는 1이다. 따라서 로봇은 그 방향으로 초당 1만큼 움직인다.
나중에 경로 추종, 제어, 센서 퓨전으로 넘어가면 이 구분이 매우 중요해진다. 로봇에게 "빠르게 가라"라고만 말하면 부족하다. 어느 방향으로 빠르게 갈지도 함께 알려 주어야 한다.
단위 벡터는 방향만 남긴 벡터다
이제 방향을 다루는 핵심 도구인 단위 벡터를 배워 보자.
단위 벡터는 크기가 1인 벡터다. 크기는 1이지만 방향은 그대로 유지한다. 예를 들어 [3, 4]라는 벡터가 있다. 이 벡터의 크기는 5다. 이 벡터를 5로 나누면 [0.6, 0.8]이 된다.
v = np.array([3.0, 4.0])
length = np.linalg.norm(v)
unit_v = v / length
print(unit_v)
print(np.linalg.norm(unit_v))결과는 다음과 같다.
[0.6 0.8]
1.0[3, 4]와 [0.6, 0.8]은 같은 방향을 향한다. 다만 [0.6, 0.8]의 길이는 1이다. 벡터를 자기 자신의 크기로 나누어 단위 벡터로 만드는 과정을 정규화라고 한다.
단위 벡터 = 벡터 / 벡터의 크기단위 벡터가 중요한 이유는 방향과 크기를 분리할 수 있기 때문이다. 로봇을 목표 방향으로 움직이고 싶다고 하자. 먼저 목표를 향하는 방향만 구한다. 그다음 원하는 속력을 곱한다. 그러면 그 방향으로 원하는 빠르기를 가진 속도 벡터가 된다.
요리로 비유하면 단위 벡터는 "어느 방향으로 갈지"라는 레시피이고, 속력은 "얼마나 세게 밀지"라는 양념의 양이다. 방향과 빠르기를 분리해 두면 로봇 제어가 훨씬 깔끔해진다.
0 벡터는 조심해야 한다
단위 벡터를 만들 때는 한 가지 조심할 점이 있다. 벡터의 크기로 나누어야 하므로, 벡터의 크기가 0이면 문제가 생긴다.
v = np.array([0.0, 0.0])
length = np.linalg.norm(v)
unit_v = v / length
print(unit_v)이 코드는 정상적인 방향을 만들 수 없다. [0, 0]은 길이가 0인 벡터다. 아무 방향도 가리키지 않는다. 방향이 없는 벡터를 단위 벡터로 바꾸려고 하니 "0으로 나누기" 문제가 생긴다.
로봇에서 이 상황은 흔하다. 로봇이 이미 목표 위치에 도착했다면 target_pos - robot_pos가 [0, 0]이 된다. 이때는 목표 방향을 계산할 필요가 없다. 이미 도착했으므로 멈추면 된다.
안전한 정규화 함수를 만들어 보자.
import numpy as np
def normalize(v):
length = np.linalg.norm(v)
if length < 1e-8:
return np.zeros_like(v)
return v / length
print(normalize(np.array([3.0, 4.0])))
print(normalize(np.array([0.0, 0.0])))여기서 1e-8은 아주 작은 숫자다. 컴퓨터는 실수를 완벽하게 정확히 계산하지 못하기 때문에, 길이가 정확히 0인지 비교하기보다 "거의 0인가?"를 확인하는 편이 안전하다.
np.zeros_like(v)는 v와 같은 모양의 0 벡터를 만든다. 입력이 2차원 벡터면 [0, 0], 3차원 벡터면 [0, 0, 0]을 반환한다.
이 작은 방어 코드 하나가 시뮬레이터를 훨씬 튼튼하게 만든다. 로봇 프로그램은 수학적으로 아름다운 경우만 만나지 않는다. 이미 도착했거나, 센서값이 이상하거나, 계산 결과가 거의 0이 되는 순간을 자주 만난다. 좋은 로봇 코드는 이런 순간에도 당황하지 않는다.
목표 방향 벡터 구하기
이제 로봇이 목표를 향해 움직이는 문제로 돌아가 보자. 로봇의 현재 위치와 목표 위치가 있을 때, 목표를 향하는 벡터는 다음처럼 구한다.
to_target = target_pos - robot_pos이 한 줄은 앞으로 계속 등장한다. 로봇공학에서 정말 자주 쓰는 패턴이다. "어디로 가야 하는가?"라는 질문에 대한 첫 번째 답이기 때문이다.
예제를 보자.
robot_pos = np.array([2.0, 1.0])
target_pos = np.array([8.0, 5.0])
to_target = target_pos - robot_pos
distance = np.linalg.norm(to_target)
direction = normalize(to_target)
print('목표 방향 벡터:', to_target)
print('목표까지 거리:', distance)
print('단위 방향 벡터:', direction)결과는 다음과 비슷하다.
목표 방향 벡터: [6. 4.]
목표까지 거리: 7.211102550927978
단위 방향 벡터: [0.83205029 0.5547002 ]여기서 to_target은 목표까지 가는 전체 화살표다. 이 벡터의 크기는 거리다. direction은 같은 방향을 가리키지만 길이가 1인 단위 벡터다.
이제 로봇은 두 가지 정보를 얻었다.
목표는 현재 위치에서
[6, 4]방향에 있다.목표까지 거리는 약
7.21이다.목표를 향하는 순수한 방향은
[0.832, 0.555]이다.
이제 남은 일은 간단하다. 이 방향으로 얼마나 빠르게 움직일지 정하면 된다.
속력과 단위 방향 벡터를 곱하면 속도 벡터가 된다
로봇이 목표 방향으로 초당 0.5만큼 움직이게 하고 싶다고 하자. 그러면 단위 방향 벡터에 속력을 곱하면 된다.
speed = 0.5
velocity = direction * speed
print(velocity)
print(np.linalg.norm(velocity))결과는 다음과 비슷하다.
[0.41602515 0.2773501 ]
0.5속도 벡터의 방향은 목표를 향하고 있고, 크기는 0.5다. 즉 로봇은 목표 방향으로 초당 0.5만큼 이동한다.
이 관계는 매우 중요하다.
속도 벡터 = 단위 방향 벡터 * 속력또는 로봇의 말로 바꾸면 다음과 같다.
어디로 갈지 정한다 → 그 방향을 길이 1로 만든다 → 원하는 빠르기를 곱한다이렇게 하면 방향과 속력을 따로 제어할 수 있다. 방향은 목표 위치가 정하고, 속력은 우리가 정한다. 목표가 멀리 있든 가까이 있든, 로봇은 같은 속력으로 목표를 향해 움직일 수 있다.
한 걸음 이동시키기
속도 벡터를 만들었다면 위치 업데이트는 어렵지 않다. 시간 간격 dt 동안 움직였다고 하면, 새 위치는 다음처럼 계산한다.
새 위치 = 현재 위치 + 속도 벡터 * 시간 간격Python으로 써 보자.
robot_pos = np.array([2.0, 1.0])
target_pos = np.array([8.0, 5.0])
speed = 0.5
dt = 1.0
to_target = target_pos - robot_pos
direction = normalize(to_target)
velocity = direction * speed
robot_pos = robot_pos + velocity * dt
print(robot_pos)결과는 다음과 비슷하다.
[2.41602515 1.2773501 ]로봇이 목표 방향으로 한 걸음 이동했다. 이동 전 위치는 [2, 1]이었고, 이동 후 위치는 [2.416, 1.277] 정도가 되었다. 목표 [8, 5]에 아주 조금 가까워진 것이다.
여기서 dt는 시간 간격이다. dt = 1.0이면 1초 동안 움직였다는 뜻이다. dt = 0.1이면 0.1초 동안 움직인 것이다. 시뮬레이션에서는 보통 작은 시간 간격을 두고 같은 계산을 반복한다. 그러면 로봇이 부드럽게 움직이는 것처럼 보인다.
목표를 향해 여러 번 움직이기
이제 이 과정을 반복해 보자. 로봇이 목표에 가까워질 때까지 계속 방향을 계산하고, 속도 벡터를 만들고, 위치를 업데이트한다.
import numpy as np
def normalize(v):
length = np.linalg.norm(v)
if length < 1e-8:
return np.zeros_like(v)
return v / length
robot_pos = np.array([2.0, 1.0])
target_pos = np.array([8.0, 5.0])
speed = 0.5
dt = 0.1
arrival_distance = 0.05
positions = [robot_pos.copy()]
for step in range(300):
to_target = target_pos - robot_pos
distance = np.linalg.norm(to_target)
if distance < arrival_distance:
print('목표에 도착했습니다.')
break
direction = normalize(to_target)
velocity = direction * speed
robot_pos = robot_pos + velocity * dt
positions.append(robot_pos.copy())
print('최종 위치:', robot_pos)
print('목표까지 남은 거리:', np.linalg.norm(target_pos - robot_pos))이 코드는 작지만 중요한 로봇 제어 구조를 담고 있다. 매 반복마다 로봇은 목표 방향을 새로 계산한다. 그리고 그 방향으로 조금 이동한다. 이동한 뒤에는 현재 위치가 바뀌므로, 다음 반복에서 목표 방향도 다시 계산한다.
사람이 길을 걸을 때도 비슷하다. 멀리 있는 문을 향해 걸어간다고 해서 처음에 한 번 방향을 정하고 눈을 감은 채 걷지는 않는다. 걸으면서 계속 문이 어느 방향인지 확인하고, 조금씩 방향을 조정한다. 로봇도 마찬가지다.
궤적을 그려 보기
숫자만 보면 로봇이 움직였다는 사실은 알 수 있지만, 감각이 잘 오지 않을 수 있다. 이번에는 Matplotlib으로 궤적을 그려 보자.
import numpy as np
import matplotlib.pyplot as plt
def normalize(v):
length = np.linalg.norm(v)
if length < 1e-8:
return np.zeros_like(v)
return v / length
robot_pos = np.array([2.0, 1.0])
target_pos = np.array([8.0, 5.0])
speed = 0.5
dt = 0.1
arrival_distance = 0.05
positions = [robot_pos.copy()]
for step in range(300):
to_target = target_pos - robot_pos
distance = np.linalg.norm(to_target)
if distance < arrival_distance:
break
direction = normalize(to_target)
velocity = direction * speed
robot_pos = robot_pos + velocity * dt
positions.append(robot_pos.copy())
positions = np.array(positions)
plt.figure(figsize=(6, 6))
plt.plot(positions[:, 0], positions[:, 1], 'b-', label='trajectory')
plt.scatter(positions[0, 0], positions[0, 1], c='green', s=100, label='start')
plt.scatter(target_pos[0], target_pos[1], c='red', s=100, label='target')
plt.axis('equal')
plt.grid(True)
plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.show()그래프를 보면 로봇이 시작점에서 목표점까지 직선으로 움직이는 것을 확인할 수 있다. 지금은 장애물도 없고, 회전 제한도 없고, 바퀴의 물리적 제약도 없는 단순한 점 로봇이다. 하지만 핵심은 이미 들어 있다.
로봇은 현재 위치와 목표 위치의 차이로 방향 벡터를 만든다. 그 방향 벡터를 정규화해 단위 방향 벡터로 바꾼다. 여기에 속력을 곱해 속도 벡터를 만들고, 시간 간격만큼 위치를 업데이트한다.
이 흐름은 앞으로 계속 확장된다. 회전하는 로봇, 센서 오차가 있는 로봇, 경로를 따라가는 로봇, 장애물을 피하는 로봇도 결국 이 기본 감각 위에 올라간다.
너무 가까울 때는 속도를 줄여야 할까?
방금 만든 코드는 목표에 거의 도착할 때까지 일정한 속력으로 움직인다. 그런데 한 가지 문제가 생길 수 있다. 목표 바로 앞에서도 같은 속력으로 움직이면, 한 번의 업데이트에서 목표를 살짝 지나칠 수 있다.
예를 들어 목표까지 남은 거리가 0.02인데, 한 번에 0.05만큼 이동하면 목표를 지나가 버린다. 이 문제를 피하는 간단한 방법은 한 번에 이동할 거리보다 목표까지 남은 거리가 더 짧으면, 목표 위치로 바로 이동시키는 것이다.
robot_pos = np.array([2.0, 1.0])
target_pos = np.array([8.0, 5.0])
speed = 0.5
dt = 0.1
for step in range(300):
to_target = target_pos - robot_pos
distance = np.linalg.norm(to_target)
step_distance = speed * dt
if distance <= step_distance:
robot_pos = target_pos.copy()
print('목표에 정확히 도착했습니다.')
break
direction = normalize(to_target)
velocity = direction * speed
robot_pos = robot_pos + velocity * dt
print(robot_pos)이 방식은 단순하지만 시뮬레이션에서는 매우 유용하다. 로봇이 목표 근처에서 덜덜 떨거나 목표를 지나쳐 왔다 갔다 하는 문제를 줄여 준다.
더 발전된 제어에서는 목표에 가까워질수록 속도를 줄이기도 한다. 예를 들어 거리가 멀 때는 빠르게 가고, 가까워지면 천천히 접근하는 방식이다. 자동차가 주차할 때를 생각해 보면 자연스럽다. 멀리서는 빠르게 움직여도 되지만, 벽 바로 앞에서는 조심스럽게 움직여야 한다.
하지만 지금은 너무 복잡하게 가지 않아도 된다. 이 장의 핵심은 방향과 크기를 분리해서 생각하는 것이다.
방향 벡터를 눈으로 확인하기
벡터는 숫자로만 보면 조금 건조하다. 이번에는 로봇 위치에서 목표를 향하는 방향 벡터를 화살표로 그려 보자. Matplotlib의 quiver 함수를 사용하면 벡터를 화살표로 표현할 수 있다.
import numpy as np
import matplotlib.pyplot as plt
def normalize(v):
length = np.linalg.norm(v)
if length < 1e-8:
return np.zeros_like(v)
return v / length
robot_pos = np.array([2.0, 1.0])
target_pos = np.array([8.0, 5.0])
to_target = target_pos - robot_pos
direction = normalize(to_target)
plt.figure(figsize=(6, 6))
plt.scatter(robot_pos[0], robot_pos[1], c='blue', s=100, label='robot')
plt.scatter(target_pos[0], target_pos[1], c='red', s=100, label='target')
plt.quiver(
robot_pos[0], robot_pos[1],
direction[0], direction[1],
angles='xy', scale_units='xy', scale=1,
color='orange', width=0.008,
label='unit direction'
)
plt.plot([robot_pos[0], target_pos[0]], [robot_pos[1], target_pos[1]], 'k--', alpha=0.4)
plt.axis('equal')
plt.xlim(0, 10)
plt.ylim(0, 7)
plt.grid(True)
plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.show()그래프에는 로봇, 목표점, 그리고 로봇이 바라보아야 할 단위 방향 벡터가 나타난다. 주황색 화살표는 길이가 1이기 때문에 목표까지 완전히 닿지는 않는다. 하지만 방향은 정확히 목표를 향한다.
이것이 단위 벡터의 장점이다. 목표가 멀리 있든 가까이 있든 방향만 깔끔하게 뽑아낼 수 있다. 방향을 얻은 뒤에는 원하는 만큼 속력을 곱하면 된다.
로봇의 머릿속 계산 정리
이제 로봇이 목표를 향해 움직이는 과정을 한 번에 정리해 보자. 로봇의 머릿속에서는 다음 계산이 반복된다.
현재 위치와 목표 위치의 차이를 구해 목표 방향 벡터를 만든다.
목표 방향 벡터의 크기를 구해 목표까지의 거리를 계산한다.
목표 방향 벡터를 정규화해 단위 방향 벡터를 만든다.
단위 방향 벡터에 속력을 곱해 속도 벡터를 만든다.
속도 벡터에 시간 간격을 곱해 현재 위치를 업데이트한다.
이 과정을 코드로 압축하면 다음과 같다.
to_target = target_pos - robot_pos
distance = np.linalg.norm(to_target)
direction = normalize(to_target)
velocity = direction * speed
robot_pos = robot_pos + velocity * dt다섯 줄이지만, 이 안에는 로봇 이동의 핵심이 들어 있다. 이 계산을 이해하면 앞으로 나올 목표 추종, 경로 추종, 속도 제어를 훨씬 편하게 받아들일 수 있다.
물론 실제 로봇은 더 복잡하다. 바퀴가 옆으로 미끄러지지 못하는 로봇도 있고, 제자리에서 먼저 회전해야 하는 로봇도 있다. 드론처럼 3차원에서 움직이는 로봇도 있다. 하지만 그런 복잡한 모델도 결국 "어느 방향으로 얼마나 움직일 것인가?"라는 질문에서 출발한다.
작은 실험: 속력을 바꿔 보기
마지막으로 직접 실험해 보자. 아래 코드에서 speed 값을 바꾸면 로봇의 궤적은 어떻게 달라질까?
import numpy as np
import matplotlib.pyplot as plt
def normalize(v):
length = np.linalg.norm(v)
if length < 1e-8:
return np.zeros_like(v)
return v / length
def simulate(speed):
robot_pos = np.array([2.0, 1.0])
target_pos = np.array([8.0, 5.0])
dt = 0.1
positions = [robot_pos.copy()]
for step in range(300):
to_target = target_pos - robot_pos
distance = np.linalg.norm(to_target)
step_distance = speed * dt
if distance <= step_distance:
robot_pos = target_pos.copy()
positions.append(robot_pos.copy())
break
direction = normalize(to_target)
velocity = direction * speed
robot_pos = robot_pos + velocity * dt
positions.append(robot_pos.copy())
return np.array(positions)
speeds = [0.3, 0.7, 1.2]
target_pos = np.array([8.0, 5.0])
plt.figure(figsize=(6, 6))
for speed in speeds:
positions = simulate(speed)
plt.plot(positions[:, 0], positions[:, 1], label=f'speed={speed}')
plt.scatter(2.0, 1.0, c='green', s=100, label='start')
plt.scatter(target_pos[0], target_pos[1], c='red', s=100, label='target')
plt.axis('equal')
plt.grid(True)
plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.show()세 궤적은 모두 같은 직선을 따라간다. 방향이 같기 때문이다. 하지만 목표에 도착하는 시간은 다르다. 속력이 클수록 더 적은 반복 횟수로 목표에 도착한다.
이 실험에서 확인할 수 있는 사실은 단순하지만 강력하다. 방향은 단위 벡터가 결정하고, 빠르기는 속력이 결정한다. 둘을 분리하면 로봇의 움직임을 훨씬 명확하게 설계할 수 있다.
이번 장에서 기억할 것
이번 장에서는 로봇이 목표를 향해 움직이는 문제를 벡터의 방향과 크기로 해석했다. 벡터의 크기는 거리나 속력으로 이해할 수 있고, NumPy에서는 np.linalg.norm()으로 계산할 수 있다. 벡터를 자기 크기로 나누면 방향만 남은 단위 벡터가 되며, 이 단위 방향 벡터에 속력을 곱하면 속도 벡터가 된다.
가장 중요한 한 줄은 이것이다.
to_target = target_pos - robot_pos이 한 줄은 현재 위치에서 목표를 향하는 화살표를 만든다. 그리고 이 화살표의 크기는 목표까지의 거리, 정규화한 결과는 목표를 향하는 방향이다.
다음 장에서는 이 생각을 한 단계 더 확장한다. 지금까지는 모든 위치를 같은 기준에서 바라보았다. 하지만 실제 로봇은 자기 몸을 기준으로 앞, 뒤, 왼쪽, 오른쪽을 판단한다. 세상 전체를 기준으로 보는 좌표와 로봇 자신을 기준으로 보는 좌표는 서로 다르다. 이제 우리는 로봇 좌표계와 월드 좌표계를 구분하기 시작할 것이다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.