文件采用RINEX2的格式的星历文件
计算一颗卫星在某时间上20分钟内每间隔一分钟的坐标
计算原理如下:
1计算轨道长半轴a。
2计算平均角速度。
3计算从需要时刻到参考时刻的时间差
4改正平角速度
5计算平近点角
6由以知轨道参数计算偏近点角
7计算真近点角
8计算升交距角
9计算卫星轨道摄动项改正数
10计算改正后的向经
11计算改正后的倾角
12计算观测升交点的经度
12计算卫星在轨平面坐标
13最后计算卫星在协议地球坐标系中的位置
代码如下
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <regex>
#include <vector>
#include <iostream>
#include <sstream>
#include <cmath>
using namespace std;
string read_satellite_ephemeris(const std::string& file_name, const std::string& target_satellite, const std::string& target_time, const std::string& target_time1, const std::string& target_time2, const std::string& target_time3)
{
std::ifstream file(file_name);
if (!file.is_open()) {
std::cerr << "无法打开文件" << std::endl;
return 0;
}
string data;
std::string line;
int line_number = 0;
while (std::getline(file, line)) {
std::istringstream iss(line);
std::string satellite, time, time1, time2, time3;
iss >> satellite >> time >> time1 >> time2 >> time3; // 假设每行的第一个字段是卫星名,第二个字段是时间,分别是年月日
if (satellite == target_satellite && time == target_time)
if (time1 == target_time1 && time2 == target_time2)
if (time3 == target_time3) {
data = line;
// 找到了目标卫星和时间的记录,处理该记录及其后的六行
for (int i = 0; i < 7; i++) {
if (std::getline(file, line)) {
data = data + (" " + line);//将相关数据内容进行存储
}
else {
break;
}
}
file.close();
return data;
}
++line_number;
}
file.close();
return 0;
}
double GM ;
double t1 ;
double M0 ;
double a ;
double dn ;
double dt ;
double n0 ;
double n ;
double tk, uk;
double a1, b, c, d, e1, f,g,h,l,m;
double Xk, Yk, Zk;//全局变量
void jishuan()//计算函数
{
double toe = 302400.00;
tk = tk + dt;
double Mk, fk, Dk, duk, drk, dik, ik, i, rk, Lk;
Mk = M0 + n * tk;
double Ek = (Mk / 180) * 3.14 + 0.01 * sin((Mk / 180) * 3.14);
for (int i = 0; i < 10; i++)
{
Ek = (Mk / 180) * 3.14 + 0.01 * sin(Ek);
}
fk = atan((sqrt(1 - 0.01 * 0.01) * sin(Ek)) / (cos(Ek) - 0.01));
Dk = fk + (a1 / 180) * 3.14;
duk = b * sin(2 * Dk) + c * cos(2 * Dk);
drk = d * sin(2 * Dk) + e1 * cos(2 * Dk);
dik = f * sin(2 * Dk) + g * cos(2 * Dk);
uk = Dk + duk;
rk = a * (1 - 0.01 * cos(Ek)) + drk;
ik = h + dik + l * tk;
Lk = (g / 180) * 3.14 + ((m / 180) * 3.14 - 0.00007292115) * tk - toe * m;
double xk = rk * cos(uk);
double yk = rk * sin(uk);
double zk = 0;
Xk = cos(Lk) * xk - sin(Lk) * cos(ik) * yk;
Yk = sin(Lk) * xk + cos(Lk) * cos(ik) * yk;
Zk = sin(ik) * yk;
}
int main() {
std::string file_name = "F:/卫星导航定位原理/weixing.txt"; // 将文件名替换为实际的卫星星历文件名
std::string target_satellite = "G09"; // 将卫星名替换为实际的目标卫星名
std::string target_time = "2024"; // 将时间替换为实际的目标时间
std::string target_time1 = "02";
std::string target_time2 = "01"; // 将时间替换为实际的目标时间
std::string target_time3 = "12";
std::string input = read_satellite_ephemeris(file_name, target_satellite, target_time, target_time1, target_time2, target_time3);
std::regex e("(\\d+\\.\\d+E[+-]\\d+)([^\s])");
std::string result = std::regex_replace(input, e, "$1 $2");//在字符串中两个不易分割的数据之间插入空格
std::replace(result.begin(), result.end(), 'E', 'e');
istringstream in(result);
vector<string> v; string t;
while (getline(in, t, ' ')) { //这里单引号要注意
v.push_back(t);
}//分割读取
for (auto it = v.begin(); it != v.end();) {
if (*it == "") {
it = v.erase(it);
}
else if (*it == "G09") {
it = v.erase(it);
}
else {
++it;
}
}//删除空值以及不能转换为数字的部分
vector<double> vec;
for (const auto& str : v) {
double num = stod(str);
vec.push_back(num);
}//将字符类型转换为数字类型
GM = 4041.8087658;
t1 = 0;
M0 = vec[12];
a = vec[16] * vec[16];
dn = vec[11];
dt = 0;
n0 = sqrt(GM/(pow(a,3)));
n = n0 + dn;
tk = -302400;
a1 = vec[23]; b = vec[15]; c = vec[13]; d = vec[10]; e1 = vec[22];
f = vec[20]; g = vec[19]; h = vec[21]; l = vec[25]; m = vec[24];
for (int i = 0; i <= 20; i++)
{
jishuan();
cout << "2024 02 01 12 "<<i<<"00坐标为X=" << Xk <<" " << "Y=" << Yk << " " << "Z=" << Zk << endl;
dt += 60;
}//遍历输出
return 0;
}