드론, 항공기, 로봇의 위치를 다룰 때는 좌표계 선택이 중요하다. GPS는 위도, 경도, 고도처럼 지구 기준 좌표를 주지만, 제어기는 보통 로컬 좌표계에서 위치 오차와 속도를 계산한다.
이때 자주 쓰는 좌표계가 Local tangent plane coordinate이다. 지구 표면의 한 기준점 주변을 평면으로 근사하고, 그 접평면 위에서 위치를 표현한다.
대표적인 local tangent plane 좌표계는 두 가지다.
| 좌표계 | 축 방향 | 주 사용 분야 |
|---|---|---|
| ENU | East, North, Up | robotics, mapping |
| NED | North, East, Down | aerospace, drone |
왜 Local Frame이 필요한가
GPS 위치는 보통 geodetic coordinate로 표현된다.
여기서
| 기호 | 의미 |
|---|---|
| latitude | |
| longitude | |
| altitude 또는 height |
하지만 제어 문제에서는 다음과 같은 값이 더 직접적이다.
목표 지점이 현재 위치에서 북쪽으로 10m, 동쪽으로 3m 떨어져 있다.
즉 위도/경도 차이보다 meter 단위의 local displacement가 필요하다.
Local tangent plane은 지구 곡면 위의 작은 영역을 평면으로 근사해 이런 meter 단위 계산을 쉽게 만든다.
ECEF 좌표계
Local frame을 정의하기 전에 지구 중심 좌표계인 ECEF를 보자. ECEF는 Earth-Centered, Earth-Fixed coordinate이다.
| 축 | 의미 |
|---|---|
| 위도 , 경도 방향 | |
| 위도 , 경도 E 방향 | |
| 북극 방향 |
ECEF 좌표는 지구와 함께 회전하는 3차원 Cartesian coordinate이다. 어떤 지점의 ECEF position을 다음처럼 둔다.
Local frame은 보통 기준점 를 잡고, 주변 점과의 차이를 회전시켜 얻는다.
그리고 이 displacement를 ENU 또는 NED frame으로 변환한다.
ENU 좌표계
ENU는 East-North-Up 좌표계이다. 기준점의 위도 , 경도 에서 세 단위축을 다음처럼 정의한다.
East
East 방향은 경도가 증가하는 방향이다.
North
North 방향은 위도가 증가하는 방향이다.
Up
Up 방향은 지표면 바깥쪽 normal 방향이다.
따라서 ECEF displacement를 ENU로 바꾸는 회전 행렬은 다음과 같다.
변환은 다음처럼 쓴다.
NED 좌표계
NED는 North-East-Down 좌표계이다. 항공 분야에서는 고도가 아래 방향을 양수로 두는 convention을 자주 쓴다.
NED의 세 축은 다음과 같다.
| 축 | 방향 |
|---|---|
| North | |
| East | |
| Down |
Down은 Up의 반대 방향이다.
따라서 ECEF에서 NED로 가는 회전 행렬은 다음과 같다.
변환은 다음과 같다.
이 행렬의 각 row는 NED의 basis vector이다.
| Row | 의미 |
|---|---|
| 1st row | ECEF에서 본 North 방향 |
| 2nd row | ECEF에서 본 East 방향 |
| 3rd row | ECEF에서 본 Down 방향 |
ENU와 NED의 관계
ENU와 NED는 같은 local tangent plane을 다른 축 순서와 부호로 표현한 것이다.
ENU vector를 다음처럼 두자.
NED vector는 다음이다.
따라서 변환 행렬은 간단하다.
반대로도 같은 행렬을 적용하면 된다.
이 행렬은 자기 자신의 inverse이다.
드론에서 NED를 많이 쓰는 이유
항공 분야에서는 NED가 자연스럽다. 항공기는 대부분 지표면 위를 날고, 관심 있는 대상은 기체 아래쪽에 있는 경우가 많다. 그래서 Down을 positive axis로 두면 고도, 하강, 지면과의 관계를 표현하기 쉽다.
드론 제어에서는 local position을 다음처럼 둘 수 있다.
여기서 가 커진다는 것은 아래로 내려간다는 뜻이다. 즉 상승은 가 감소하는 방향이다.
이 convention은 처음에는 어색하지만, PX4나 ArduPilot 같은 autopilot ecosystem에서는 자주 등장한다.
Body Frame과 Local Frame
Local frame은 지구 기준의 근사 평면 좌표계이다. 반면 body frame은 기체에 붙어 있는 좌표계이다.
| Frame | 원점 | 축이 움직이는가 | 용도 |
|---|---|---|---|
| Local NED | 기준 GPS 위치 | 지구 기준으로 고정 | 위치, 속도, waypoint |
| Body frame | 드론 중심 | 드론 자세와 함께 회전 | thrust, torque, IMU |
드론의 추력은 body frame에서 정의되는 것이 자연스럽다.
하지만 위치와 속도 update는 local frame에서 하는 것이 자연스럽다. 따라서 자세 회전 행렬 가 필요하다.
이 글의 핵심은 ECEF에서 local frame으로 가는 좌표 변환이고, 자세 동역학 자체는 별도의 문제이다. 즉 local tangent plane은 "내가 지구 어디 근처에 있는가"를 다루고, body-to-local rotation은 "기체가 어떤 자세인가"를 다룬다.
Python 예시
아래 코드는 위도/경도 기준점에서 ECEF displacement를 NED로 변환하는 기본 구조이다.
import numpy as np
def ecef_to_ned_rotation(lat_rad, lon_rad):
s_lat = np.sin(lat_rad)
c_lat = np.cos(lat_rad)
s_lon = np.sin(lon_rad)
c_lon = np.cos(lon_rad)
return np.array([
[-s_lat * c_lon, -s_lat * s_lon, c_lat],
[-s_lon, c_lon, 0.0],
[-c_lat * c_lon, -c_lat * s_lon, -s_lat],
])
def ecef_delta_to_ned(point_ecef, origin_ecef, origin_lat_rad, origin_lon_rad):
rotation = ecef_to_ned_rotation(origin_lat_rad, origin_lon_rad)
delta = point_ecef - origin_ecef
return rotation @ delta
실제 시스템에서는 geodetic coordinate를 ECEF로 바꾸는 WGS84 변환이 먼저 필요하다. 하지만 한 번 ECEF 좌표가 준비되면, local NED 변환은 위 회전 행렬로 처리된다.
작은 거리에서의 근사
아주 작은 영역에서는 위도/경도 차이를 meter로 근사할 수도 있다. 지구 반지름을 이라 하면,
여기서 , 는 radian 단위이다. 고도 차이를 라 하면 NED의 Down은 다음처럼 볼 수 있다.
이 근사는 짧은 거리에서는 편리하지만, 넓은 영역이나 정밀한 항법에서는 ECEF를 거친 변환을 쓰는 것이 더 안전하다.
흔한 실수
좌표계 버그는 드론 시뮬레이션과 항법 코드에서 매우 자주 발생한다. 대표적인 실수는 다음과 같다.
| 실수 | 결과 |
|---|---|
| degree를 radian으로 바꾸지 않음 | 회전 행렬이 완전히 틀어진다. |
| ENU와 NED를 섞음 | east/north가 바뀌거나 altitude sign이 뒤집힌다. |
| altitude와 down sign 혼동 | 상승 명령이 하강처럼 보일 수 있다. |
| origin을 빼지 않고 회전 | local displacement가 아니라 지구 중심 위치를 회전하게 된다. |
| body frame과 local frame 혼동 | 추력/속도 방향이 잘못 적용된다. |
특히 NED에서는 "위로 올라가는 것"이 증가가 아니라 감소라는 점을 계속 확인해야 한다.
정리
Local tangent plane coordinate는 지구 곡면 위의 작은 영역을 평면으로 근사해 제어와 항법을 쉽게 만드는 좌표계이다.
핵심 변환은 다음이다.
ENU와 NED는 같은 local frame을 다른 convention으로 표현한다.
드론에서는 local NED와 body frame을 구분하는 것이 중요하다. NED는 위치와 속도를 표현하는 지구 기준 local frame이고, body frame은 thrust와 torque처럼 기체에 붙은 물리량을 표현하는 frame이다.