在UAV(Unmanned Aerial Vehicle)中,常見的坐標系有以下幾種:
1. 大地坐標系,WGS84(WorldGeodeticCoordinateSystem1984)
這是為GPS全球定位系統建立的坐標系統。WGS-84坐標系的原點在地球質心,Z軸指向BIH1984.0定義的協定地球極(CTP)方向,X軸指向BIH1984.0的零度子午面和CTP赤道的交點,Y軸和Z、X軸構成右手坐標系。其參數為經度、緯度、海拔高度。
其基本參數如下:
2. 地球中心坐標系,ECEF(Earth-Centered, Earth-Fixed)
ECEF坐標系與地球固聯,且隨着地球轉動。圖中O即為坐標原點,位置在地球質心。X軸通過格林尼治線和赤道線的交點,正方向為原點指向交點方向。Z軸通過原點指向北極。Y軸與X、Z軸構成右手坐標系。
下圖中可以直觀的看出ECEF和WGS84坐標系的區別:
圖中,φ、λ表示緯度和經度,是WGS84坐標系的參數,x、y、z為ECEF坐標系的描述。從圖中可以看出,目標點X標記處在不同坐標系下描述的區別。
3. 局部切線平面
從定義來分類,局部切線平面可分為基於垂直和水平尺寸定義的平面,其表現在縱坐標為上還是下。縱坐標為上時,稱為ENU(東、北、天)坐標系,主要用於地理方面;縱坐標為下時,稱為NED(北、東、地)坐標系,特別用於航空航天。
上圖為ENU坐標系,該坐標系即為控制裝置所在位置的“平面坐標系”,又稱為地理坐標系。
4. 載體坐標系(Body Frame)
載體坐標系指的是以載體的質心為原點,OX沿縱軸方向,即載體前進方向,Z軸沿載體側軸方向,指向右翼,Y沿載體豎軸方向,是右手坐標系而成(即指向天)。總的來說,載體坐標系相對於地理坐標系的關系就是載體的姿態。在我們的實際控制當中,我們關心的顯然是載體坐標系相對於地理坐標系之間的變化,所以我們通常使用的旋轉矩陣是把“地理”坐標系轉到“載體”坐標系的矩陣,從而實現對控制目標(載體)的姿態控制。由地理坐標系到載體坐標系的轉換常用的有三種方式:四元數、歐拉角、方向余弦矩陣。
導航的基本原則就是保證兩個基本坐標系的正確轉化,沒有誤差。只有實現了這個原則,載體才可以在自己的坐標系中完成一系列動作而被轉換到地理坐標系中看起來是正確的。導航的基本原則就是保證兩個基本坐標系的正確轉化,沒有誤差。只有實現了這個原則,載體才可以在自己的坐標系中完成一系列動作而被轉換到地理坐標系中看起來是正確的。
5. 代碼實現
這是之前寫的一個坐標轉換的代碼,經測試可以使用。

1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 4 """ 5 Created on 2019.01.18 6 @Author: Ethan 7 """ 8 9 import math 10 import numpy as np 11 import client_socket.py as client 12 PI= math.pi 13 a=6378137 14 b=6356752.314245 15 E = (a*a - b*b)/(a*a) 16 17 class Goal: 18 def __init__(self,x,y): 19 self.x=0 20 self.y=0 21 22 def deg(x): 23 x=(x/180)*PI 24 return x 25 26 #latitude:緯度 longitude:經度 altitude:海拔高度 27 #latitude0 longitude0----current_local_pos 28 def Translate(latitude:float,longitude:float, 29 latitude0:float,longitude0:float): 30 LAT=deg(latitude) 31 LON=deg(longitude) 32 33 LAT0=deg(latitude0) 34 LON0=deg(longitude0) 35 36 altitude0=0 37 print("GPS坐標(經度、緯度、高度)為: ",latitude,longitude,altitude) 38 #ECEF坐標系 39 N = a /(math.sqrt(1 - E*math.sin(LAT)*math.sin(LAT))) 40 X=(N+altitude)*math.cos(LAT)*math.cos(LON) 41 Y=(N+altitude)*math.cos(LAT)*math.sin(LON) 42 Z=N*(1-e*e)*math.sin(LAT) 43 44 N0 = a /(math.sqrt(1 - E*math.sin(LAT0)*math.sin(LAT0))) 45 X0=(N+altitude)*math.cos(LAT0)*math.cos(LON0) 46 Y0=(N+altitude)*math.cos(LAT0)*math.sin(LON0) 47 Z0=N*(1-E*E)*math.sin(LAT0) 48 49 print("空間直角坐標系下X軸、Y軸、高度為",'%.3f'%X,'%.3f'%Y,'%.3f'%Z) 50 51 #旋轉矩陣 52 mat=np.array([[-math.sin(LON),math.cos(LON),0],\ 53 [-math.sin(LAT)*math.cos(LON),-math.sin(LAT)*math.sin(LON),math.cos(LAT)],\ 54 [math.cos(LAT)*math.cos(LON),math.cos(LAT)*math.sin(LON),math.sin(LAT)]]) 55 56 arr=np.array([[X-X0],[Y-Y0],[Z-Z0]]) #坐標原點糾正 57 res=np.dot(mat,arr) 58 X=res[0] 59 Y=res[1] 60 print("站心坐標系下東、北",'%.3f'%X,'%.3f'%Y) 61 62 return res 63 64 #獲取航點 65 def get_waypoints(x0,y0,x1,y1,cx,cy): 66 waypoints=client.way_choose(x0,y0,x1,y1) 67 for i in waypoints: 68 str=i.split(",") 69 longitude=float(str[0]) 70 latitude=float(str[1]) 71 72 res=Translate(latitude,longitude,x0,y0) 73 g=Goal() 74 g.x=res[0] 75 g.y=res[1] 76 77 cx=list.append(g.x) 78 cy=list.append(g.y)