Advertisement

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

阅读量:
cb9229298793c1adb70d0de4601b19f8.png

//写这个花了一天的时间 主要是那一块费了很久

//于是专门把时间背景知识加进来做一个总结

//经常感觉很口渴 思路也很闷 就像上面的停了水的喷灌器

一、时间背景知识

9fc68012057f511548ad95ef686dbe90.png
bad2e82c47bf65d371cbeb698e407d16.png
684724daf84380443dc25a0b03c2841f.png

二、不同时间系统之间的转换

利用导航电文计算卫星位置时 需要将目标计算时刻换算到GPS时间

56dabd86d74e2c14145879bdd752b225.png
78c8f2f122944e9f92ec7036b79c4a64.png
320c34f4667c42c4cb4e7d7c3b1c9e1d.png

//由于导航电文中的是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次。

2d55f1ff789865fec9b1062a91d11c9b.png
12f35aa042dbf1f936b2da2004fda220.png
1a9b51b70625d4d0b9e2b994d3bc315e.png

四、导航电文的计算流程

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

|

1fbf42c30653c108e2ca2576b0741d70.png

|

84dd6e67166c67918525b729c13143b3.png

|
|---|---|

33b69433c63bcf1865cb5827ed5c993e.png
0ed124224fe74c54fd3e1564877577f9.png
ca7d406aa7c06939d63a15d3c34a5a85.png
195b4c8df521d08e65048dcc83cee1ac.png
14ec7d61eea0c3a5ec3b819f180f9365.png
e16f72c8d526bcd9350bcd475f756bd7.png
9a362dc2c239ccc743fc3a663e18746d.png

五、头大的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

928d6d7db9e242c757a0570348b04d15.png

//最近的编程实在是太多了

//感觉编程这东西 身体也搞坏了 事情干的还不怎么地..

//希望早日离开和编程有关的行业

全部评论 (0)

还没有任何评论哟~