C语言计算GPS卫星位置

C语言计算GPS卫星位置
C语言计算GPS卫星位置

C

语言计算G P S 卫星位置

1 概述 在用GPS 信号进行导航定位以及制订观测计划时,都必须已知GPS 卫星在空间的瞬间位置。卫星位置的计算是根据卫星电文所提供的轨道参数按一定的公式计算的。本节专门讲解观测瞬间GPS 卫星在地固坐标系中坐标的计算方法。

2 卫星位置的计算

1. 计算卫星运行的平均角速度n

根据开普勒第三定律,卫星运行的平均角速度n0可以用下式计算:

式中μ为WGS-84坐标系中的地球引力常数,且μ=3.986005×1014m 3/s 2。平均角速度n 0加上卫星电文给出的摄动改正数Δn ,便得到卫星运行的平均角速度n

n=n 0+Δn (4-12)

2. 计算归化时间t k

首先对观测时刻t ′作卫星钟差改正

t=t ′-Δt

然后对观测时刻t 归化到GPS 时系

t k =t-t oc (4-13)

式中t k 称作相对于参考时刻t oe 的归化时间(读者注意:toc ≠toe )。

3. 观测时刻卫星平近点角M k 的计算

M k =M 0+n tk (4-14)

式中M 0是卫星电文给出的参考时刻toe 的平近点角。

4. 计算偏近点角E k

E k =M k +esinE k (E k ,M k 以弧度计) (4-15)

上述方程可用迭代法进行解算,即先令E k =M k ,代入上式,求出E k 再代入上式计

算,因为GPS 卫星轨道的偏心率e 很小,因此收敛快,只需迭代计算两次便可求得偏近点角E k 。

5. 真近点角V k 的计算

由于:

因此:

6.升交距角Φk 的计算

ω为卫星电文给出的近地点角距。

7. 摄动改正项δu,δr,δi 的计算

δu,δr,δi 分别为升交距角u 的摄动量,卫星矢径r 的摄动量和轨道

倾角i 的摄动量。

8. 计算经过摄动改正的升交距角u k 、卫星矢径r k 和轨道倾角i k

9. 计算卫星在轨道平面坐标系的坐标

卫星在轨道平面直角坐标系(X 轴指向升交点)中的坐标为

10. 观测时刻升交点经度Ωk 的计算

升交点经度Ωk 等于观测时刻升交点赤经Ω(春分点和升交点之间的角距)与

格林泥治视恒星时GAST (春分点和格林尼治起始子午线之间的角距)之差,

Ωk =Ω-GAST (4-23)

又因为:

tk oe Ω+Ω=Ω (4-24)

其中Ωoe 为参与时刻t oe 的升交点的赤经;

Ω

是升交点赤经的变化率,卫星电文每小时更新一次Ω和t oe 。 此外,卫星电文中提供了一周的开始时刻t w 的格林尼治视恒星时GAST w 。由于

地球自转作用,GAST 不断增加,所以:

GAST=GAST w +ωe t (4-25)

式中ωe ×10-5rad/s 为地球自转的速率;t 为观测时刻。

由式(4-24)和(4-25),得:

由(4-13)式,得:

其中0oe w GAST Ω=Ω-,o Ω、Ω、oe t 的值可从卫星电文中获取。

11. 计算卫星在地心固定坐标系中的直角坐标

把卫星在轨道平面直角坐标系中的坐标进行旋转变换,可得出卫星在地心固定坐标系中的三维坐标:

12. 卫星在协议地球坐标系中的坐标计算

考虑极移的影响,卫星在协议地球坐标系中的坐标为

利用C语言程序实现

#include

#include

#include

#include

#define WE 7.292115e-6

struct canshu

{

int prn, nian, yue, ri, shi, fen;//卫星PRN号,年,月,日,时,分double miao;//秒

long double adoe, a0, a1, a2, mo, dn, e, ga, pio, io, w, pid, ii, cuc, cus, cue, crs, crc, cis, cic, toe, aodc, wn;

/*参数说明: ADOE值,a0 卫星钟偏差, a1 卫星钟漂移, a2 卫星钟频率漂移, M0 平近点角, Δn平运动差, e偏心率, a1/2半长轴的平方根, Ω0 轨道平面升交点经度,

i0 倾角, ω近地点角距, *Ω升交点速率, IDot 倾角速率, Cuc Cus 升交角距的摄动改正项, Crc Crs 地心距的摄动改正项, Cic Cis 倾角的摄动改正项,

toe 参考历元*/

};

void wxzbjx(struct canshu *pt)

{

long double a, n0, n, t, tk, toc, mk, ek, vk, fik, uk, rk, ik;

long double xk, yk ,zk, lk;

long double XK, YK, ZK;

int temp;

pt->nian = pt->nian + 2000;

t = (long double)(((pt ->nian)- 1980) * 365 * 24 * 3600 + (pt -

>yue - 1) * 30 * 24 * 3600 + pt ->ri

* 24 * 3600 + pt->shi * 3600 + pt ->miao);

a = pt ->ga * pt ->ga;

n0 = sqrt(WE/(a*a*a));//平均角速度n0

n = n0 + pt ->dn;

tk = t - pt ->toe;

toc = pt ->a0 + pt ->a1 * (t - pt ->toe) + pt ->a2 * (t - pt->toe) * (t - pt ->toe);

tk = tk - pt ->toe;

mk = pt ->mo + n * tk;

ek = mk;

for(temp=0;temp<10;temp++)

{

ek=mk+ pt ->e * sin(ek);//利用迭代法求偏近点角ek }

vk = 2 * atan(sqrt((1+ pt ->e) / (1 - pt ->e))* (tan(ek)) / 2 );

fik = vk + pt ->w;

uk = fik + pt ->cuc * cos(2* fik) + pt ->cus * sin(2*fik);

rk = pt ->ga * pt ->ga * (1 - pt ->e * ek) + pt ->crc * cos(2* fik) + pt ->crs * sin(2*fik);

ik = pt ->io + pt ->cic * cos(2 * fik) + pt ->cis * sin(2* fik) + pt ->ii * tk;

xk = rk * cos(uk);

yk = rk * sin(uk);

zk = 0;

lk = pt ->pio + (pt ->pid - WE) * tk - WE * pt->toe;

XK = xk * cos(lk) - yk * cos(ik) * sin(lk);

YK = xk * sin(lk) + yk * cos(ik) * cos(lk);

ZK = yk * sin(ik);

printf("\n%d年%d月%d号%d时%.2f秒 %d号卫星的坐标:", pt->nian,

pt->yue ,pt->ri , pt->shi ,pt->miao, pt->prn);

printf("\nXk = %.9f\nYk= %.9f\nZK = %.9f\n\n", XK, YK, ZK);

}

int main(void)

{

FILE *fp, *fp1, *fp2;

struct canshu a;

int i=0, hanhao = 1;

long double t emp1, temp2, temp3, temp5, temp4, temp6, temp7;

char ch, ch1;

if((fp1 = fopen("E:\\星历文件\\guangboxingli2.txt", "r")) == NULL)//请自定义星历文件位置及名称

{

printf("文件无法打开!");

exit(0);

}

else

{

if((fp2 = fopen("E:\\星历文件\\guangboxingli2fu.txt", "w")) == NULL)

{

printf("文件无法打开!");

exit(0);

}

else

{

while((ch1 = fgetc(fp1)) != EOF)

{

if(ch1 == '\n')

{

i ++;

}

putchar(ch1);

if(i == 15)

{

break;

}

}

while(!feof(fp1))

{

ch1=fgetc(fp1);

if(ch1 == 'D')

{

ch1 = 'e';

}

fputc(ch1,fp2);

}

fclose(fp1);

}

fclose(fp2);

}

printf("以上是星历文件的头文件!\n");

system("pause");

printf("读取文件参数数据\n!");

if((fp = fopen("E:\\星历文件\\guangboxingli2fu.txt", "r")) == NULL)//创建计算结果文档

{

printf("文件无法打开!");

exit(0);

}

while(!feof(fp))

{

switch(hanhao)

{

case 1:

{

fscanf(fp,"\n%d%d%d%d%d%d%lf %le %le %le", &a.prn, &a.nian, &a.yue, &a.ri, &a.shi,

&a.fen, &a.miao, &a.a0, &a.a1, &a.a2);

printf("%d %d %d %d %d %d %lf %le %le %le", a.prn, a.nian, a.yue, a.ri, a.shi,

a.fen, a.miao, a.a0, a.a1, a.a2);

hanhao++;

}

case 2:

{

fscanf(fp,"%le %le %le %le", &a.adoe, &a.crs,

&a.dn, &a.mo);

printf("\n%le %le %le %le", a.adoe, a.crs, a.dn, a.mo);

hanhao++;

}

case 3:

{

fscanf(fp,"%le %le %le %le", &a.cue, &a.e, &a.cus, &a.ga);

printf("\n%le %le %le %le", a.cue, a.e, a.cus,

a.ga);

hanhao++;

}

case 4:

{

fscanf(fp,"%le %le %le %le", &a.toe, &a.cic,

&a.pio, &a.cis);

printf("\n%le %le %le %le", a.toe, a.cic, a.pio, a.cis);

hanhao++;

}

case 5:

{

fscanf(fp,"%le %le %le %le", &a.io, &a.crc, &a.w, &a.pid);

printf("\n%le %le %le %le", a.io, a.crc, a.w,

a.pid);

hanhao++;

}

case 6:

{

fscanf(fp,"%le %le %le %le", &a.ii, &temp1, &a.wn, &temp2);

printf("\n%le %le %le %le", a.ii, temp1, a.wn, temp2);

hanhao++;

}

case 7:

{

fscanf(fp,"%le %le %le %le", &temp3, &temp4,

&temp5, &a.aodc);

printf("\n%le %le %le %le", temp3, temp1, temp5, a.aodc);

hanhao++;

}

case 8:

{

fscanf(fp,"%le", &temp6);

printf("\n%le", temp6);

if((ch=fgetc(fp)) != '\n')

{

fscanf(fp,"%le", &temp7);

printf(" %le\n", temp7);

}

}

}

wxzbjx(&a);

system("pause");

hanhao = 1;

}

fclose(fp);

return 0;

}

相关主题
相关文档
最新文档