本文介紹了基于C語言的GPS衛(wèi)星位置解算原理與程序設(shè)計。針對每個原理、公式、代碼設(shè)計進行了詳細(xì)講解,希望能夠給測繪學(xué)子們帶來幫助。
創(chuàng)新互聯(lián)公司是一家集網(wǎng)站建設(shè),弋江企業(yè)網(wǎng)站建設(shè),弋江品牌網(wǎng)站建設(shè),網(wǎng)站定制,弋江網(wǎng)站建設(shè)報價,網(wǎng)絡(luò)營銷,網(wǎng)絡(luò)優(yōu)化,弋江網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強企業(yè)競爭力。可充分滿足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時我們時刻保持專業(yè)、時尚、前沿,時刻以成就客戶成長自我,堅持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實用型網(wǎng)站。參考書籍:
李征航 黃勁松:GPS測量與數(shù)據(jù)處理(第三版)
目錄
基礎(chǔ)原理
1)衛(wèi)星位置解算流程
2)衛(wèi)星有關(guān)參數(shù)
3)衛(wèi)星位置計算過程?
程序設(shè)計
數(shù)據(jù)預(yù)處理
1)GPS時轉(zhuǎn)換(TimetoGPSsec)
2)選擇最佳歷元(select_epoch)
代碼與解析
BDS衛(wèi)星位置

如流程圖所示,在程序設(shè)計中對于一顆衛(wèi)星的位置解算,是要經(jīng)過多次迭代,直到信號傳播時間收斂。
2)衛(wèi)星有關(guān)參數(shù)在正式開始程序設(shè)計之前,我們還需要了解一下衛(wèi)星的相關(guān)參數(shù)及其含義。
平近點角M?
衛(wèi)星平均運動角速度為,根據(jù)開普勒第三定律得:

所以衛(wèi)星平均運動角速度n:

因此,平近點角M定義為:

t為信號發(fā)射時刻,t0為衛(wèi)星過近地點時刻。
偏近點角E
如下圖所示:以衛(wèi)星橢圓軌道的焦點為原點,以指向近地點的方向為X軸,Y軸平行于橢圓短半軸,建立軌道平面坐標(biāo)系。以衛(wèi)星橢圓中心為圓心,以衛(wèi)星軌道的長半軸a為半徑作一個輔助圓。

過衛(wèi)星S作X軸的垂線,其延長線與輔助圓交于S‘,圓心到S’的向徑與X軸的夾角定義為偏近點角E。?
平近點角與偏近點角的關(guān)系可用開普勒方程表示:

在計算偏近點角E時,E0可用平近點角M做初始值,然后進行迭代計算,因為E非常小,因此迭代幾次即可收斂,可將收斂標(biāo)準(zhǔn)設(shè)為1.0e-5。?
真近點角V
由上圖所示,真近點角V與偏近點角E存在著一定關(guān)系,真近點角V可又下述式子得出:

其中,e為第一偏心率。
如果已知真近點角,那么衛(wèi)星在軌道坐標(biāo)系中的位置向量可以表示為:

衛(wèi)星的運動速度? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
由上式得得衛(wèi)星的運動速度為:

由開普勒方程可得:

因此,可以推導(dǎo)出衛(wèi)星的運動方程:

衛(wèi)星鐘差
衛(wèi)星鐘差方程為:

a0,a1,a2為N文件中的鐘頻,鐘偏和鐘漂。(廣播星歷中的衛(wèi)星鐘差誤差為10ns,等效距離為3m)

其中
為長半軸a的平方根,e為軌道偏心率,二者都由廣播星歷播發(fā);GM為引力常數(shù),大小為:398600500000000;E為衛(wèi)星的偏近點角。(因為偏近點角E很小,該誤差在偽距中可忽略不計)
(1)求平均角速度n:


為廣播星歷(N文件)中衛(wèi)星平均運動速率與計算值之差(
代碼中用deltan表示)。?
(2)求規(guī)劃時刻

t為信號發(fā)射時刻,
為N文件中的參考?xì)v元(
代碼中用TOE表示)。?
信號發(fā)射時刻為:O文件觀測時刻-信號傳播時間。
近似信號傳播時間=偽距觀測值/光速-接收機鐘差+衛(wèi)星鐘差+電離層改正+對流層改正
上式中,用參考時刻toe時刻代替了衛(wèi)星過近地點t0時刻。
這是因為:廣播星歷2h更新一次,間給參考時刻設(shè)在中央時刻時,外推間隔小于1h。而衛(wèi)星的運行周期為12h,采取衛(wèi)星過近地點時刻t0,外推間隔大可能達(dá)到6h。用toe代替t0,模型簡單,并且可以保證精度。
計算t和toe時,需要保證二者之差在兩小時內(nèi),計算才能生效。因此,在計算衛(wèi)星位置前,需要根據(jù)O文件中的觀測選擇N文件中的最佳觀測歷元(代碼見后文)。
(3)求平近角

為N文件中的參考時間的平近點角。
(4)求偏近點角E


e為N文件中軌道偏心率;偏近點角需要迭代計算,將平近角M作為E的初始值帶入,因為E很小,一般迭代幾次即可收斂,收斂條件為

1.0e-12為科學(xué)計數(shù)法,表示10的負(fù)12次方。
(5)求真近點角

(6)求升交角距u

為N文件中的近地點角距(
代碼中用omega表示)。
(7)攝動改正
升交角距改正項:
軌道向徑改正項:
軌道向徑改正項:
分別為N文件中提供的6個攝動改正參數(shù)。(
在代碼中分別用Epsilon_u、Epsilon_r、Epsilon_i表示)
(8)計算改正后的升交角距、軌道向徑、軌道向徑



(9)衛(wèi)星在升交點軌道直角坐標(biāo)系的坐標(biāo)


(10)計算升交點經(jīng)度L

為N文件中GPS周開始時刻的升交點經(jīng)度,
為N文件中升交點赤經(jīng)變化率,
為N文件中參考?xì)v元時刻。
(11) 計算衛(wèi)星在地固坐標(biāo)系中的空間直角坐標(biāo)系



(12)計算Z軸旋轉(zhuǎn)變換,得到的新坐標(biāo)



為地球自轉(zhuǎn)角速度,
為信號傳播時間。
(13)重新計算衛(wèi)地距

為接收機坐標(biāo),可將O文件中接收機概略坐標(biāo)當(dāng)作接收機坐標(biāo)初始值,減少迭代次數(shù)。
(14)重新計算信號傳播時間

R為新的衛(wèi)地距,Cv表示光速。?
(15)重復(fù)步驟1~14,直到信號傳播時間收斂,收斂條件為

單顆衛(wèi)星位置解算流程:
GPS時,也稱GPS time,GPST,由GPS星載原子鐘和地面監(jiān)控站原子鐘組成的一種原子時基準(zhǔn),其起點為1980年1月6日0時00分00秒。
觀測值文件中的參考時刻是以年月日進行記錄的,不利于計算,需轉(zhuǎn)換成周內(nèi)秒的形式。?
程序設(shè)計主要思想:?
TimetoGPSsec代碼如下:
double TimetoGPSsec(int year, int month, int day, int hour, int min, double sec)
{
int DayofYear = 0, DayofMonth = 0, SecofWeek = 0;
int i = 0;
for (i = 1980; i< year; i++)
{
//判斷閏年
if ((i % 4 == 0 && i % 100 != 0) || i % 400 == 0)
DayofYear += 366;
else
DayofYear += 365;
}
for (i = 1; i< month; i++)
{
//判斷大小月
if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12)
DayofMonth += 31;
else if (i == 4 || i == 6 || i == 9 || i == 11)
DayofMonth += 30;
else
{
if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
DayofMonth += 29;
else
DayofMonth += 28;
}
}
int Day = DayofYear + DayofMonth + day - 6;//計算到1980年1月6號(星期日)有多少天
SecofWeek = (double)(Day % 7) * 24 * 60 * 60 + (double)hour * 3600 + (double)min * 60 + sec;
return SecofWeek;
}其中:
根據(jù)衛(wèi)星的PRN號以及觀測時間,選擇與N文件中時間間隔最小的數(shù)據(jù)塊進行解算。
主要思想:?
select_epoch代碼如下:
//挑選合適的星歷
extern int select_epoch(double SecofWeek, int sPRN, pnav_body nav_b, int n_n)
{
int n_epoch = 0;
double min=10000;//假設(shè)最小值是1萬秒
double Min;
int i;
for (i = 0; i< n_n / 8; i++)
{
if (sPRN == nav_b[i].sPRN)
{
Min = fabs(SecofWeek - nav_b[i].TOE);
if (Min<= min)
{
n_epoch = i;
min = Min;
}
}
}
return n_epoch;
}其中:
在程序設(shè)計時,將單次解算衛(wèi)星位置的過程封裝成一個函數(shù),然后放入while循環(huán)中迭代計算,當(dāng)信號傳播時間收斂后,輸出衛(wèi)星位置結(jié)果。
定義一個結(jié)構(gòu)體,用來當(dāng)作函數(shù)的傳參
//衛(wèi)星位置傳參
typedef struct Pos_t
{
double X;
double Y;
double Z;
double deltat;//改正前的接收機鐘差
double delta_t;//改正后的接收機鐘差
}Pos_t;#define C_V 299792458//光速(m)
#define GM 398600500000000//地心引力常數(shù)
#define math_e 2.718281828459 //e值
#define PI 3.141592653589793
#define Earth_e 7.2921151467e-5 //地球自轉(zhuǎn)角速度
#define C1 4
//時間轉(zhuǎn)換
double GPSsec = TimetoGPSsec(obs_e[i].y, obs_e[i].m, obs_e[i].d, obs_e[i].h, obs_e[i].min, obs_e[i].sec);
//根據(jù)O文件歷元參考時間選擇合適的N文件數(shù)據(jù)
int n_epoch = select_epoch(GPSsec, obs_e[i].sPRN[j], nav_b, n_n);
//觀測時刻 - 參考時刻
double detat_toc = GPSsec - nav_b[n_epoch].TOE;
//計算近似的信號傳播時間,接收機鐘差已初始化為0(偽距/光速-接收機鐘差+衛(wèi)星鐘差)
double delta_t = (obs_b[i].obs[j][C1] / C_V) - sta[i].delta_TR + nav_b[n_epoch].sa0 + nav_b[n_epoch].sa1 * detat_toc + nav_b[n_epoch].sa2 * pow(detat_toc, 2);
//計算衛(wèi)星位置
double deltat = 0.0;//判斷收斂
while (fabs(delta_t - deltat) >0.0001)
{
//臨時結(jié)構(gòu)體變量tmp,用來傳參
Pos_t tmp = { 0 };
//計算衛(wèi)星位置函數(shù)
tmp = sat_pos(nav_b[n_epoch].deltan, nav_b[n_epoch].sqrtA, nav_b[n_epoch].TOE,
nav_b[n_epoch].M0, nav_b[n_epoch].e, nav_b[n_epoch].omega, nav_b[n_epoch].OMEGA,
nav_b[n_epoch].deltaomega, nav_b[n_epoch].Cuc, nav_b[n_epoch].Crc, nav_b[n_epoch].Cic,
nav_b[n_epoch].Cus, nav_b[n_epoch].Crs, nav_b[n_epoch].Cis, nav_b[n_epoch].i0, nav_b[n_epoch].IDOT,
delta_t, deltat, sta[i].X, sta[i].Y, sta[i].Z, GPSsec);
//傳參,更新信號傳播時間
deltat = tmp.deltat;
delta_t = tmp.delta_t;
sat[i][j].X = tmp.X;
sat[i][j].Y = tmp.Y;
sat[i][j].Z = tmp.Z;
}其中:
計算衛(wèi)星位置函數(shù)
//計算衛(wèi)星位置
Pos_t sat_pos( double deltan,double sqrtA,double TOE,double M0,double e,
double omega,double OMEGA,double deltaomega,double Cuc,double Crc, double Cic,
double Cus,double Crs,double Cis,double i0,double IDOT,double delta_t, double deltat, double X_R,
double Y_R, double Z_R, double GPSsec)
{
Pos_t pos_t={0};
//計算信號發(fā)射時刻=O文件觀測時刻-信號傳播時間
double T_S = GPSsec - delta_t;
//計算衛(wèi)星的平均角速度n
double n0 = sqrt(GM) / pow(sqrtA, 3);
double n = n0 + deltan;
//計算歸劃時間tk
double tk = T_S - TOE;
if (tk >32400)tk -= 604800;//規(guī)劃時間改正
else if (tk< -32400)tk += 604800;
//計算衛(wèi)星發(fā)射時衛(wèi)星的平近角M
double M = M0 + n * tk;
//迭代計算偏近點角
double E = M, E0;
do
{
E0 = E;
E = M + e * sin(E);
} while (fabs(E - E0) >1.0e-5);
//計算真近點角V
double cosv = (cos(E) - e) / (1 - e * cos(E));//cosV
double sinv = sqrt(1 - pow(e, 2)) * sin(E) / (1 - e * cos(E));//sinV
double Vk = atan2(sinv, cosv);//注意atan與atan2的不同
//計算升交角距u
double u = Vk + omega;
//計算攝動改正項
double Epsilon_u = Cuc * cos(2 * u) + Cus * sin(2 * u);
double Epsilon_r = Crc * cos(2 * u) + Crs * sin(2 * u);
double Epsilon_i = Cic * cos(2 * u) + Cis * sin(2 * u);
//計算改正后的升交角距、軌道向徑、軌道傾角
double uk = u + Epsilon_u;
double rk = pow(sqrtA, 2) * (1 - e * cos(E)) + Epsilon_r;
double ik = i0 + Epsilon_i + IDOT * tk;
//計算衛(wèi)星在升交點軌道直角坐標(biāo)系的坐標(biāo)
double xk = rk * cos(uk);
double yk = rk * sin(uk);
//計算升交點經(jīng)度
double L = OMEGA + (deltaomega - Earth_e) * tk - Earth_e * TOE;
//計算衛(wèi)星在地固系下的直角坐標(biāo)
double X = xk * cos(L) - yk * cos(ik) * sin(L);
double Y = xk * sin(L) + yk * cos(ik) * cos(L);
double Z = yk * sin(ik);
//通過 Z 軸的旋轉(zhuǎn)變換,對該坐標(biāo)進行地球自轉(zhuǎn)改正,得到新坐標(biāo)
pos_t.X = cos(Earth_e * delta_t) * X + sin(Earth_e * delta_t) * Y;
pos_t.Y = -sin(Earth_e * delta_t) * X + cos(Earth_e * delta_t) * Y;
pos_t.Z = Z;
//重新計算信號傳播的時間
double R = sqrt(pow(X - X_R, 2) + pow(Y - Y_R, 2) + pow(Z - Z_R, 2));
pos_t.deltat = delta_t;
pos_t.delta_t = R / C_V;
return pos_t;
}(上述代碼為了更加清晰的體現(xiàn)哪個是新變量、哪個是舊變量,將開辟變量的工作放在函數(shù)中間;讀者自己寫代碼時,建議將開辟變量的工作統(tǒng)一放到函數(shù)的起始位置,增加運行效率;有些語言不支持程序運行后再開辟變量,例如:Fortran)
傳入?yún)?shù):從deltann到IDOT,均為N文件中讀取的參數(shù),delta_t和deltat為信號傳播時間,用于判斷信號傳播時間是否收斂,X_R,Y_R,Z_R為測站坐標(biāo),首次迭代時,可初始化為0或概略坐標(biāo)(O文件頭),GPSsec為轉(zhuǎn)化成GPS時的觀測時刻
上述代碼中有關(guān)時間的參數(shù)比較多,這里再次梳理一遍,防止混淆:
觀測時刻(GPSsec):接收機收到信號的時刻,O文件每個歷元的第一行記錄,需轉(zhuǎn)換成GPS周內(nèi)秒
衛(wèi)星鐘差時間(detat_toc):由觀測時刻減去衛(wèi)星信號發(fā)射時刻TOE,TOE以GPS周內(nèi)秒的形式存儲,這個時間只用于衛(wèi)星鐘差改正
信號近似傳播時間(delta_t):由偽距進行計算,需要進行衛(wèi)星鐘差、接收機鐘差、電離層和對流層改正(上述代碼沒有加入電離層和流層改正,推薦兩種簡單的改正模型:電離層經(jīng)驗?zāi)P蚄lobuchar,對流層經(jīng)驗?zāi)P虶CAT)
信號發(fā)射時刻(T_S):由觀測時刻減去信號近似傳播時間
規(guī)劃時間(tk):將信號發(fā)射時刻規(guī)劃到以TOE為基準(zhǔn)的時刻
上述代碼與公式一一對應(yīng),需要注意以下幾點:
1)if (tk >32400)tk -= 604800;else if (tk< -32400)tk += 604800;規(guī)劃時間改正,604800為一周的秒數(shù),32400為一周半的秒數(shù)。該部分內(nèi)容可參考其他博主:衛(wèi)星發(fā)射時刻歸化
2)計算偏近點角E時,因為E極小,迭代幾次即可收斂,因此收斂條件只要保證精度即可,在計算衛(wèi)星鐘差時,末項的改正數(shù)用到了偏近點角E,如需改正,可將E保留進行傳參
3)C語言中角度計算均是以弧度為單位;atan和atan2均是求反正切函數(shù),后者的使用范圍是是四象限角
4)上述中用到的sqrt,pow,fabs分別是:開方函數(shù),冪函數(shù),取絕對值函數(shù),均需包含頭文件
BDS的衛(wèi)星位置解算與GPS衛(wèi)星有很大相似之處,其中MEO與IGSO衛(wèi)星位置解算與GPS一致,GEO衛(wèi)星從計算升交點赤經(jīng)開始有所變化,在解算位置前,需要根據(jù)衛(wèi)星的PRN號來判斷衛(wèi)星的種類,GEO計算公式如下(公式選自本科時期的論文,如有錯誤多多包涵):

注意:(4-27)中-5°表示角度,為GEO衛(wèi)星的傾角

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
當(dāng)前標(biāo)題:GPS衛(wèi)星位置解算-創(chuàng)新互聯(lián)
本文路徑:http://chinadenli.net/article2/cejhoc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、響應(yīng)式網(wǎng)站、網(wǎng)站收錄、網(wǎng)站策劃、動態(tài)網(wǎng)站、外貿(mào)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容