직선 경로는 단순하면서도 가장 효율적인 이동 방법을 제공하며, 경로 계획과 유도 알고리즘의 기본 단위로 사용된다. 또한 직선은 다양한 경로 생성 기법의 기본 빌딩 블록이 된다. 다각형 경로나 꺾이는 경로는 직선 구간들의 집합으로 구성되며, 원형이나 타원 같은 곡선 경로 역시 직선 접선과의 관계 속에서 이해된다. 즉, 직선을 이해하고 정의하는 것은 복잡한 경로를 다루기 전에 반드시 거쳐야 할 출발점이다. 이번 포스팅에서는 항법의 기본이 되는 직선 경로를 구현한 내용을 다룬다.
- 직선 경로 생성 함수
- 시작점, 끝점 활용
직선 경로는 시작점과 끝점을 지정하는 것만으로도 정의된다. 두 점 \(P_{start} = (x_{s}, y_{s})\) , \(P_{end} = (x_{e}, y_{e})\)가 주어지면, 이들을 잇는 직선 위의 점은 다음과 같이 나타낼 수 있다.
$$P(t) = (1-t) P_{start} + t P_{end} \;,\;\;(0 \leq t \leq 1)$$
여기서 매개변수 \(t\)가 0일 때는 시작점, 1일 때는 끝점이 되고, 그 사이의 값은 모두 직선 위의 점을 의미한다. 이 단순한 식은 경로점을 일정 간격으로 생성할 때 매우 유용하다. 예를 들어 \(N\)개의 점을 얻고 싶다면 \(t\)를 \(\frac{0}{N-1},\frac{1}{N-1},...,\frac{N-1}{N-1}\) 로 구성하면 된다. 이 방식으로 경로점 집합을 만들면, 무인기가 따라야 할 기준선을 손쉽게 정의할 수 있다.
- 시작점, 방위각, 길이 활용
직선의 또 다른 정의 방법은 시작점과 방위각(bearing), 그리고 길이로 설정하는 것이다. 항공기의 현재 위치가 \(P_{start} = (x_{s}, y_{s})\) 이동해야 할 거리 \(L\), 비행해야 할 방위각 \(\psi\)가 주어지면 끝점은 다음과 같이 계산된다.
$$P_{end} = P_{start} + L [sin(\psi), cos(\psi)]^T$$
이때 방위각은 북위 기준 시계방향으로 (+)인 각도를 의미한다. 이 방식은 경로점이 미리 주어지지 않은 상황에서 특히 유용하다. 예를 들어 “현재 위치에서 북동쪽 30도 방향으로 2km 직진하라”는 명령을 단순한 벡터 연산으로 표현할 수 있기 때문이다.
import numpy as np import matplotlib.pyplot as plt def generate_straight_bearing(start, bearing, length, num_points): start = np.array(start) psi = np.deg2rad(bearing) end = start + length * np.array([np.sin(psi), np.cos(psi)]) Path_Straight, is_loop = generate_straight_p2p(start, end, num_points) return Path_Straight, is_loop def generate_straight_p2p(start, end, num_points): is_loop=False start = np.array(start) end = np.array(end) t = np.linspace(0, 1, num_points) # Interpolate start to end Path_Straight = np.outer(1 - t, start) + np.outer(t, end) return Path_Straight, is_loop if __name__ == "__main__": # 시작점, 끝점 활용 직선 경로 생성 #P_start = [0, 0] #P_end = [2000, 1000] #WP_num_points = 200 # #WP_gen, is_loop = generate_straight_p2p(P_start, P_end, WP_num_points) #or # 시작점, 베어링, 거리 활용 직선 경로 생성 P_start = [0, 0] bearing = 240 length = 3000 WP_num_points = 200 WP_gen, is_loop = generate_straight_bearing(P_start, bearing, length, WP_num_points) # 시각화 fig, ax = plt.subplots() ax.set_aspect('equal', adjustable='box') ax.grid(True, linestyle=':', alpha=0.3) ax.scatter([WP_gen[0,0], WP_gen[-1,0]], [WP_gen[0,1], WP_gen[-1,1]], c='r', marker='o', label="Start/End") ax.plot(WP_gen[:,0], WP_gen[:,1], 'k:', linewidth=2, label="Path") plt.show()
- 직선 경로 생성 결과
아래 그림은 직선 경로 시작점 [0, 0], 끝점 [3000, 4500] 을 입력하여 도출된 경로점을 가시화한 결과이다. 지난번 포스팅한 장주선회 경로와는 다르게 loop형태의 끝점에서 시작점으로 연결되는 형태의 경로가 아님으로 마지막 경로점을 지나친 이후의 추가적인 처리를 해줘야 한다. 일반적으로는 hold 선회 명령으로 마무리하는것이 일반적이다.
직선 경로는 가장 단순한 형태이지만, 항공기 시뮬레이션과 제어 알고리즘 설계에서는 반드시 거쳐야 하는 기본기다. 시작점과 끝점을 잇는 직선은 효율적인 이동 수단일 뿐 아니라, 다양한 알고리즘 성능을 검증하는 기준선이 된다. 더 나아가 직선 구간을 조합하면 다각형이나 복잡한 임무 경로도 만들 수 있다. 최종 구성된 파일은 아래 깃허브 주소에 업로드하였다. 추후의 업데이트 내용들도 해당 깃허브 레포에 업데이트할 예정이다. 이로서 포스팅을 마무리하겠다.
https://github.com/Piggymode/UAV_2D_Simulation.git
GitHub - Piggymode/UAV_2D_Simulation: 2D 3-dof UAV simulation framework for experimenting with guidance, navigation, and control
2D 3-dof UAV simulation framework for experimenting with guidance, navigation, and control algorithms. Includes modular components for testing aircraft dynamics, control strategies, and mission sce...
github.com
'MnS' 카테고리의 다른 글
[알쓸신잡 연구노트 M&S 9편] Nonlinear Path-Following Guidance Method 알고리즘 구현 (7) | 2025.08.16 |
---|---|
[알쓸신잡 연구노트 M&S 8편] 장주선회(Traffic Pattern) 경로 생성 함수 구현 (7) | 2025.08.15 |
[알쓸신잡 연구노트 M&S 7편] Simple UAV Simulator, 초단순 무인기 시뮬레이터 개발 (Unicycle Model) (12) | 2025.08.09 |
[알쓸신잡 연구노트 M&S 6편] VS Code 활용 Python 개발을 위한 패키지 설치 (feat. pip) (5) | 2025.08.06 |
[알쓸신잡 연구노트 M&S 5편] VS Code 활용 Python 개발을 위한 가상 환경 설정 (2) | 2025.08.04 |