c 计算delta_生活丨由广播星历(导航电文)简单计算卫星位置

//写这个花了一天的时间 主要是那一块费了很久
//于是专门把时间背景知识加进来做一个总结
//经常感觉很口渴 思路也很闷 就像上面的停了水的喷灌器
一、时间背景知识



二、不同时间系统之间的转换
利用导航电文计算卫星位置时 需要将目标计算时刻换算到GPS时间



//由于导航电文中的是GPS周内的秒数
在处理时间转换时:应先将(通常属于格里高利历体系)转译为格里高利历体系的相关数据表示方式;随后再将<基于儒略日体系下的时刻值>转译为相应的表示形式
当计算T_GPS与TOE之差时
三、导航电文的数据结构
格式说明采用的是Fortran程序设计语言中的格式说明方式, 一个格式说明项通常一般具有以下结构: [r]fw.[m]其中:
r : 重复次数, 后面的内容会重复出现, 这一部分是可以省略的;
f: 数据类型标识符, 在RINEX 格式的文档中涉及到了如X、A、I、F、D等多种数据类型;
w: 字段宽度;
m: 字段中最少所需的字符数量或小数位数(当数据类型为单精度浮点型或双精度浮点型时)这一项也是可选的。例如:
格式说明符" F9.2, 11X, A1, 19X"表示
此行内容从第1列开始依次为宽度为9位的小数点后两位的单精度浮点数值;
接着是11个空格;
然后是一个宽度为1字符类型的字符串;
之后又是19个空格;
而"3F14.4"则表示此行内容从第1列开始有3个宽度为14位且小数点后有4位的单精度浮点数值排列;**7( 3X, A1, I2 )**则表示此行内容从第1列开始将3个空格、一个宽度为1字符类型的字符串以及一个宽度为2整数值这三者组合连续重复7次。



四、导航电文的计算流程
//为了实现卫星坐标的完整确定 //依次对卫星在轨道坐标系下的各分量进行以下操作:先绕X轴逆时针转-i度、再绕Z轴逆时针转Wk弧度(其中Wk表示升交点经度),最终获得该卫星在地心地固参考系统中的位置信息
|

|

|
|---|---|







五、头大的C++
1. #include
2. #include
3. #include
4. using namespace std;
5.
6. template <class Type>
7. Type stringToNum(const string& str)//将string转换为数字
8. {
9. istringstream iss(str);
10. Type num;
11. iss >> num;
12. return num;
13.}
14.
15.int main()
16.{
17. string fileName = "./brdc2530.18n";
18. fstream file;
19. file.open(fileName);//读入文件
20. if (!file)
21. {
22. cout <"文件地址错误!打开失败!" <
23. return false ;
24. }
25. string RINEX_str; //临时储存数据文件的每一行
26. istringstream str_stream;
27.
28.
29. //一行一行读入
30.
31. //第一行
32. getline(file, RINEX_str);
33. RINEX_str.insert(22, " ");//插入分割空格
34. RINEX_str.insert(42, " ");
35. RINEX_str.insert(62, " ");
36. for (int i=0;i//转换为C++使用的科学计数法
37. if (RINEX_str[i] == 'D')
38. RINEX_str[i] = 'e';
39.
40. int PRN, year, month, day, hour, minute;
41. double second;
42. double t1, t2, t3;
43. str_stream= istringstream(RINEX_str);//转换成流
44. str_stream >> PRN >> year >> month >> day
45. >> hour >> minute >> second>>t1>>t2>>t3;
46. int yy = year;
47. int mm = month;//备份数据
48.
49. //第二行
50. getline(file, RINEX_str);
51. RINEX_str.insert(22, " ");
52. RINEX_str.insert(42, " ");
53. RINEX_str.insert(62, " ");
54. for (int i = 0; i
55. if (RINEX_str[i] == 'D')
56. RINEX_str[i] = 'e';
57. double IODE, C_rs, delta_n, M_0;
58. str_stream = istringstream(RINEX_str);
59. str_stream >> IODE >> C_rs >> delta_n >> M_0;
60.
61. //第三行
62. getline(file, RINEX_str);
63. RINEX_str.insert(22, " ");
64. RINEX_str.insert(42, " ");
65. RINEX_str.insert(62, " ");
66. for (int i = 0; i
67. if (RINEX_str[i] == 'D')
68. RINEX_str[i] = 'e';
69. double C_uc, e, C_us, sqrt_A;
70. str_stream = istringstream(RINEX_str);
71. str_stream >> C_uc >> e >> C_us >> sqrt_A;
72.
73. //第四行
74. getline(file, RINEX_str);
75. RINEX_str.insert(22, " ");
76. RINEX_str.insert(42, " ");
77. RINEX_str.insert(62, " ");
78. for (int i = 0; i
79. if (RINEX_str[i] == 'D')
80. RINEX_str[i] = 'e';
81. double TOE, C_ic, OMEGA_0, C_is;
82. str_stream = istringstream(RINEX_str);
83. str_stream >> TOE >> C_ic >> OMEGA_0 >> C_is;
84.
85. //第五行
86. getline(file, RINEX_str);
87. RINEX_str.insert(22, " ");
88. RINEX_str.insert(42, " ");
89. RINEX_str.insert(62, " ");
90. for (int i = 0; i
91. if (RINEX_str[i] == 'D')
92. RINEX_str[i] = 'e';
93. double i_0, C_rc, omega, OMEGA_DOT;
94. str_stream = istringstream(RINEX_str);
95. str_stream >> i_0 >> C_rc >> omega >> OMEGA_DOT;
96.
97. //第六行
98. getline(file, RINEX_str);
99. RINEX_str.insert(22, " ");
100. RINEX_str.insert(42, " ");
101. RINEX_str.insert(62, " ");
102. for (int i = 0; i
103. if (RINEX_str[i] == 'D')
104. RINEX_str[i] = 'e';
105. double i_dot, L_2_code, PS_week, L_2P_code;
106. str_stream = istringstream(RINEX_str);
107. str_stream >> i_dot>> L_2_code>> PS_week>> L_2P_code;
108.
109. //第七行
110. getline(file, RINEX_str);
111. RINEX_str.insert(22, " ");
112. RINEX_str.insert(42, " ");
113. RINEX_str.insert(62, " ");
114. for (int i = 0; i
115. if (RINEX_str[i] == 'D')
116. RINEX_str[i] = 'e';
117. double st_precision, st_health, TGD, IODC;
118. str_stream = istringstream(RINEX_str);
119. str_stream >> st_precision >> st_health >> TGD >> IODC;
120.
121. //第八行
122. getline(file, RINEX_str);
123. RINEX_str.insert(22, " ");
124. RINEX_str.insert(42, " ");
125. RINEX_str.insert(62, " ");
126. for (int i = 0; i
127. if (RINEX_str[i] == 'D')
128. RINEX_str[i] = 'e';
129. double Z_number, h, other1, other2;
130. str_stream = istringstream(RINEX_str);
131. str_stream >> Z_number >> h >> other1 >> other2;
132. file.close();
133.
134.
135. //导航电文计算卫星坐标
136.
137. //归化时间 计算t时刻的卫星位置
138. double t = second + 0.1059;//0.1059为学号后四位 仅作计算样例
139. double UT;//民用时 格里高利历 此处以小时为单位
140. UT = hour + (double(minute) / 60.0) + (t / 3600);
141. //GPS时起始时刻1980年1月6日0点
142. //year是两位数 需要转换到四位数
143. if(year>=80)
144. {
145. if(year==80&&month==1&&day<6)
146. {
147. year = year + 2000;
148. }
149. year = year + 1900;
150. }
151. else
152. {
153. year = year + 2000;
154. }
155. if(month<=2)
156. {
157. year = year - 1;
158. month = month + 12;
159. }
160. double JD;//儒略日
161. //TOE是GPS周内的秒数
162. //需要将当前需计算的时刻t先转换到儒略日再转换到GPS时间
163. JD = long long(365.25 * year) + int(30.6001 * (month + 1)) + day + UT / 24 + 1720981.5;
164. //cout <
165. double t_GPS;//目标时刻的GPS秒
166. int WN;//目标时刻的GPS周
167. //t_GPS = ((JD - 2444244.5) % 7) * 604800.0;
168. WN = int((JD - 2444244.5) / 7);
169. //cout <
170. t_GPS = (JD - 2444244.5 - 7.0 * WN) * 24 * 3600.0;
171. //cout <秒="<
172. //cout <
173. double temp_t_TOE = t_GPS - TOE;
174. //while(temp_t_TOE > 302400|| temp_t_TOE
175. if (temp_t_TOE > 302400)
176. temp_t_TOE -= 604800;
177. else if (temp_t_TOE
178. temp_t_TOE += 604800;
179.
180. //轨道计算
181. double GM = 3.986005e14;//万有引力与地球质量常数
182. double n_0;//平均角速度初值
183. n_0 = sqrt(GM) / pow(sqrt_A, 3);
184. double n;//平均角速度
185. n = n_0 + delta_n;
186.
187. double M;//平近点角
188. M = M_0 + n * temp_t_TOE;
189.
190. double E, E1;//偏近点角
191. E = 0;
192. E1 = 1;
193. int count = 0;
194. while(abs(E1-E)>1e-10)
195. {
196. count++;
197. E1 = E;
198. E = M + e * sin(E);
199. if(count>1e8)
200. {
201. cout <"计算偏近点角时未收敛!\n";
202. break ;
203. }
204. }
205.
206. double f;//真近点角
207. f = atan((sqrt(1 - e * e) * sin(E))/( cos(E) - e));
208.
209. double u_0;//升交距角初值
210. //omega近地点角距
211. u_0 = omega + f;
212.
213. double delta_u, delta_r, delta_i;//扰动项
214. delta_u = C_uc * cos(2 * u_0) + C_us * sin(2 * u_0);
215. delta_r = C_rc * cos(2 * u_0) + C_rs * sin(2 * u_0);
216. delta_i = C_ic * cos(2 * u_0) + C_is * sin(2 * u_0);
217.
218. double u;//升交距角
219. double r;//卫星矢径
220. double i;//卫星轨道倾角
221. u = u_0 + delta_u;
222. r = pow(sqrt_A, 2) * (1 - e * cos(E)) + delta_r;
223. i = i_0 + delta_i + i_dot * (temp_t_TOE);
224.
225. double x, y;//卫星在轨道平面坐标系中的位置
226. x = r * cos(u);
227. y = r * sin(u);
228.
229. double omega_e = 7.292115e-5;//地球自转角速度
230. double L;//升交点经度 地心地固坐标系
231. L = OMEGA_0 + (OMEGA_DOT - omega_e) * t_GPS - OMEGA_DOT * TOE;
232.
233. double X, Y, Z;//地心地固坐标系坐标
234. X = x * cos(L) - y * cos(i) * sin(L);
235. Y = x * sin(L) + y * cos(i) * cos(L);
236. Z = y * sin(i);
237. ofstream file_result;
238. file_result.open("./Result.txt");
239. file_result <"真近点角f=\n\t" <"\n";
240. file_result <"升交角距u=\n\t" <"\n";
241. file_result <"卫星矢径r=\n\t" <"\n";
242. file_result <"卫星轨道倾角i=\n\t" <"\n";
243. file_result <"轨道平面坐标\n\tx=" <"\ty=" <"\n";
244. file_result <"升交点赤经L=\n\t" <"\n";
245. file_result.flags(ios::fixed);
246. file_result.precision(5); //设置保留小数位数
247. file_result <<"Time: "<" "<" "<" " <":" <":" <"\n"
248. <<"PRN: " <"\nECEF coordinate:\n";
249. file_result <"X\t" <"Y\t" <"Z\t\n";
250. file_result <"\t" <"\t" <
251. file_result.close();
252. return 0;
253.
254.}
六、样例数据
1. 30 18 9 10 23 30 0.0 0.257638748735D-04-0.517630383001D-11 0.000000000000D+00
2. 0.580000000000D+02 0.188164062500D+02 0.547040643581D-08-0.622776027704D+00
3. 0.903382897377D-06 0.361847691238D-02 0.313762575388D-05 0.515368414416D+04
4. 0.171000000000D+06 0.381842255592D-07-0.144146169606D+01 0.745058059692D-08
5. 0.942749310893D+00 0.307683593750D+03-0.297645179209D+01-0.877084455405D-08
6. 0.303584074067D-10 0.100000000000D+01 0.201800000000D+04 0.000000000000D+00
7. 0.204800000000D+04 0.000000000000D+00 0.372529029846D-08 0.580000000000D+02
8. 0.165612000000D+06 0.400000000000D+01 0.000000000000D+00 0.000000000000D+00

//最近的编程实在是太多了
//感觉编程这东西 身体也搞坏了 事情干的还不怎么地..
//希望早日离开和编程有关的行业
