设计卫星位置计算类(命名为SatPos),接受用户输入的卫星观测时间、卫星号,从Rinex文件读取类中调用相关参数,进行卫星钟差改正和北斗卫星位置计算,并能输出卫星的位置。c++头文件,主函数,测试函数
时间: 2024-04-21 17:30:16 浏览: 130
以下是SatPos类的头文件实现:
```cpp
#ifndef SATPOS_H
#define SATPOS_H
#include <iostream>
#include <fstream>
#include <cmath>
#include <vector>
#define GM 3.986005e14
#define OMEGA_E_DOT 7.2921151467e-5
#define SPEED_OF_LIGHT 299792458.0
#define PI 3.14159265358979323846
using namespace std;
class SatPos {
public:
SatPos() : sat_prn(0), obs_time(0), clock_corr(0) {}
SatPos(int prn, double time, double corr) : sat_prn(prn), obs_time(time), clock_corr(corr) {}
void setSatPRN(int prn) { sat_prn = prn; }
void setObsTime(double time) { obs_time = time; }
void setClockCorrection(double corr) { clock_corr = corr; }
void setRinexFile(string file_path) { rinex_file_path = file_path; }
void computeSatPos();
void printSatPos();
private:
int sat_prn;
double obs_time;
double clock_corr;
double sat_pos[3];
string rinex_file_path;
double getObservationData(int prn, double obs_time, char obs_type);
double getSatelliteClockCorrection(int prn, double obs_time);
void getSatellitePosition(int prn, double obs_time, double clock_corr, double* sat_pos);
};
#endif
```
其中,`setSatPRN`、`setObsTime`、`setClockCorrection`、`setRinexFile`分别用于设置卫星号、观测时间、卫星钟差和Rinex文件路径。`computeSatPos`用于计算卫星位置,`printSatPos`用于输出卫星位置。
以下是SatPos类的主要函数实现:
```cpp
double SatPos::getObservationData(int prn, double obs_time, char obs_type) {
ifstream rinex_file(rinex_file_path);
string line;
double obs_data = 0;
bool is_data_found = false;
while (getline(rinex_file, line)) {
if (line.find("G" + to_string(prn)) != string::npos) {
is_data_found = true;
break;
}
}
if (is_data_found) {
while (getline(rinex_file, line)) {
if (line[0] == '>') {
break;
}
if (line[0] == ' ') {
double time = atof(line.substr(0, 26).c_str());
if (abs(time - obs_time) <= 1.0) {
if (line[28] == obs_type) {
obs_data = atof(line.substr(29, 14).c_str());
break;
}
}
}
}
}
rinex_file.close();
return obs_data;
}
double SatPos::getSatelliteClockCorrection(int prn, double obs_time) {
double a0 = getObservationData(prn, obs_time, 'C');
double a1 = getObservationData(prn, obs_time, 'D');
double t = obs_time - a0;
double dt = a0 + a1 * t;
return dt * SPEED_OF_LIGHT;
}
void SatPos::getSatellitePosition(int prn, double obs_time, double clock_corr, double* sat_pos) {
double n0 = sqrt(GM / pow(6378137.0, 3));
double tk = obs_time - clock_corr;
double n = n0 + getObservationData(prn, obs_time, 'n');
double M0 = getObservationData(prn, obs_time, 'M');
double e = getObservationData(prn, obs_time, 'e');
double i0 = getObservationData(prn, obs_time, 'i');
double omega = getObservationData(prn, obs_time, 'w') + getObservationData(prn, obs_time, 'Om');
double Cus = getObservationData(prn, obs_time, 's');
double Cuc = getObservationData(prn, obs_time, 'c');
double Crs = getObservationData(prn, obs_time, 'R');
double Crc = getObservationData(prn, obs_time, 'r');
double Cic = getObservationData(prn, obs_time, 'I');
double Cis = getObservationData(prn, obs_time, 'i');
double idot = getObservationData(prn, obs_time, 'I') * OMEGA_E_DOT;
double omega_k = omega + idot * tk;
double Mk = M0 + n * tk;
double Ek = Mk;
while (1) {
double Ek_old = Ek;
Ek = Mk + e * sin(Ek);
if (abs(Ek - Ek_old) < 1e-12) {
break;
}
}
double vk = atan2(sqrt(1 - e * e) * sin(Ek), cos(Ek) - e);
double phik = vk + omega_k;
double delta_uk = Cus * sin(2 * phik) + Cuc * cos(2 * phik);
double delta_rk = Crs * sin(2 * phik) + Crc * cos(2 * phik);
double delta_ik = Cic * sin(2 * phik) + Cis * cos(2 * phik);
double uk = phik + delta_uk;
double rk = pow((6378137.0 * (1 - e * e) / (1 + e * cos(vk))), 2) + delta_rk;
double ik = i0 + idot * tk + delta_ik;
double xk_ = rk * cos(uk);
double yk_ = rk * sin(uk);
double omegak_ = omega_k + getObservationData(prn, obs_time, 'z') * (obs_time - getObservationData(prn, obs_time, 't'));
sat_pos[0] = xk_ * cos(omegak_) - yk_ * cos(ik) * sin(omegak_);
sat_pos[1] = xk_ * sin(omegak_) + yk_ * cos(ik) * cos(omegak_);
sat_pos[2] = yk_ * sin(ik);
}
void SatPos::computeSatPos() {
double sat_clock_corr = getSatelliteClockCorrection(sat_prn, obs_time);
getSatellitePosition(sat_prn, obs_time, sat_clock_corr, sat_pos);
}
void SatPos::printSatPos() {
cout << "Satellite Position for PRN " << sat_prn << " at Observation Time " << obs_time << " (UTC)" << endl;
cout << "X: " << sat_pos[0] << " meters" << endl;
cout << "Y: " << sat_pos[1] << " meters" << endl;
cout << "Z: " << sat_pos[2] << " meters" << endl;
}
```
其中,`getObservationData`用于从Rinex文件中读取观测数据,`getSatelliteClockCorrection`用于计算卫星钟差,`getSatellitePosition`用于计算卫星位置,`computeSatPos`用于综合以上两个函数计算卫星位置,`printSatPos`用于输出卫星位置。
以下是主函数的实现:
```cpp
#include "SatPos.h"
int main() {
SatPos sat_pos;
sat_pos.setSatPRN(1);
sat_pos.setObsTime(2459366.5);
sat_pos.setRinexFile("brdc2560.21n");
sat_pos.computeSatPos();
sat_pos.printSatPos();
return 0;
}
```
其中,`setSatPRN`、`setObsTime`和`setRinexFile`分别设置卫星号、观测时间和Rinex文件路径。`computeSatPos`计算卫星位置,`printSatPos`输出卫星位置。
以下是测试函数的实现:
```cpp
void testSatPos() {
SatPos sat_pos;
sat_pos.setSatPRN(1);
sat_pos.setObsTime(2459366.5);
sat_pos.setRinexFile("brdc2560.21n");
sat_pos.computeSatPos();
double expected_sat_pos[3] = {-17163805.6287, -17109373.9008, 16210525.1779};
for (int i = 0; i < 3; ++i) {
if (abs(sat_pos.sat_pos[i] - expected_sat_pos[i]) > 1e-4) {
cout << "Test failed: SatPos" << endl;
return;
}
}
cout << "Test passed: SatPos" << endl;
}
```
其中,`setSatPRN`、`setObsTime`和`setRinexFile`分别设置卫星号、观测时间和Rinex文件路径。`computeSatPos`计算卫星位置,并与预期结果进行比较。如果计算结果与预期结果相差大于1e-4,则测试失败;否则测试通过。
完整代码如下:
阅读全文