首页 > 其他分享 >C语言计算GPS卫星位置

C语言计算GPS卫星位置

时间:2024-10-10 21:21:05浏览次数:10  
标签:fp le pt C语言 printf toe 卫星 GPS

1 概述

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

2 卫星位置的计算

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

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

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

n=n0+Δn          (4-12)

2. 计算归化时间tk

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

t=t′-Δt

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

tk=t-toc                             (4-13)

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

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

Mk=M0+ntk                    (4-14)

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

4. 计算偏近点角Ek

Ek=Mk+esinEk(Ek,Mk以弧度计)      (4-15)

上述方程可用迭代法进行解算,即先令Ek=Mk,代入上式,求出Ek再代入上式计算,因为GPS卫星轨道的偏心率e很小,因此收敛快,只需迭代计算两次便可求得偏近点角Ek。

5. 真近点角Vk的计算

由于:

因此:

6.升交距角Φk的计算

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

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

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

8. 计算经过摄动改正的升交距角uk、卫星矢径rk和轨道倾角ik

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

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

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

升交点经度Ωk等于观测时刻升交点赤经Ω(春分点和升交点之间的角距)与格林泥治视恒星时GAST(春分点和格林尼治起始子午线之间的角距)之差,

Ωk=Ω-GAST       (4-23)

又因为:

         (4-24)

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

是升交点赤经的变化率,卫星电文每小时更新一次Ω和toe。

此外,卫星电文中提供了一周的开始时刻tw的格林尼治视恒星时GASTw。由于地球自转作用,GAST不断增加,所以:

GAST=GASTw+ωet        (4-25)

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

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

由(4-13)式,得:

其中

的值可从卫星电文中获取。

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

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

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

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

利用C语言程序实现

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <math.h>

#define u 3.986004418e+14

#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 temp1, 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;

}

标签:fp,le,pt,C语言,printf,toe,卫星,GPS
From: https://blog.csdn.net/m0_38073539/article/details/142831865

相关文章

  • C语言必背词汇有哪些
    auto:声明自动变量;double:声明双精度变量或函数;int:声明整型变量或函数;struct:声明结构体变量或函数;break:跳出当前循环;else:条件语句否定分支(与;if;连用);long:声明长整型变量或函数;switch:用于开关语句;case:开关语句分支;enum:声明枚举类型;register:声明寄存器变量;typedef:用以给......
  • C语言初学:常量和变量
    常量整型常量实型常量字符常量用一对单引号将一个字符括起来。字符串常量由一对双引号引起将零个或多个字符序列括起来。变量变量的输入与输出标准格式转换将标准日期格式YYYY-MM-DD转换为中国美国英国三个国家的三种日期格式代码如下:输出公民身份证号码的各组成......
  • 【趣学C语言和数据结构100例】
    【趣学C语言和数据结构100例】问题描述输入两个正整数m和n,求其最大公约数和最小公倍数输入一行字符,分别统计出其中英文字母、空格、数字和其他字符的个数求Sn=a+aa+aaa+…+a…a之值,其中a是一个数字,n表示a的位数,n、a由键盘输入。例如:2+22......
  • 组合定位-GPS-IMU-Odom
    组合定位GPS遵守NMEA0184GPS每次测量都是独立的,即与上次测量无关,所以不存在误差累计不同IMU器件,其驱动是不同的IMU存在数据漂移,测量相对位置GPS/INS组合制导INS是惯性导航系统(InertialNavigationSystem)的GPS/DR组合定位系统的组成:GPS传感器;odom:novatel/odom-pos......
  • 【Leecode 随笔】C语言版看了不后悔系列持续更新中。。。
    文章目录题目一:两数相除题目描述示例1:示例2:注意:解题思路示例代码深入剖析题目二:加一题目描述示例1:示例2:解题思路示例代码深入剖析题目三:快乐数题目描述示例1:示例2:解题思路示例代码深入剖析......
  • 实验2_C语言分支与循环基础应用编程
    task1#include<stdio.h>#include<stdlib.h>#include<time.h>#defineN5#defineN1397#defineN2476#defineN321//随机摇学号intmain(){intcnt;intrandom_major,random_no;srand(time(NULL));//以当前系统时间作为随机种子......
  • 【C语言复习】常见概念(零基础)
    【C语言复习】常见概念1、C语言是什么?2、C语言的历史和辉煌3、编译器的选择VS20223.1编译和链接3.2编译器的对比3.3VS2022的优缺点4、VS项⽬和源⽂件、头⽂件介绍5、第一个C语言程序6、main函数(主函数)7、printf和库函数8、关键字介绍9、字符和ASCII编码10、字符串......
  • 操作系统:内核的基本实现(一)屏幕输出与C语言支持
    使用C语言cdecl约定HimuOSKernel遵守cdecl约定,在32位操作系统上,函数实参在线程栈上按照从右至左的顺序依次压栈(x86cdecl的参数总是在栈上)函数结果保存在寄存器EAX/AX/AL中浮点型结果存放在寄存器ST0中编译后的函数名前缀以一个下划线字符调用者负责清栈8比特或......
  • C语言函数栈帧的创建与销毁(32)
    文章目录前言一、什么是函数栈帧?二、理解函数栈帧能解决什么问题?三、函数栈帧的创建和销毁解析什么是栈?认识相关寄存器和汇编指令四、解析函数栈帧的创建和销毁预备知识函数的调用堆栈准备环境转到反汇编函数栈帧的创建函数栈帧的销毁五、回答开篇总结前言应该是......
  • 实验二 C语言分支与循环基础应用编程-1
    task1.c #include<stdio.h>#include<stdlib.h>#include<time.h>#defineN5#defineN1397#defineN2476#defineN321intmain(){intcnt;intrandom_major,random_no;srand(time(NULL));//以当前系统时间作为随机种子cnt=0;while(cnt<N){rando......