周跳探测——带约束的历元间差分法

前言

在利用历元间差分法进行周跳探测时,可以通过增加位置误差约束的方式使结果更加稳健。(对静态基站有用,对动态站效果感觉不明显)

一、带约束的历元间差分法

公式推导:
在这里插入图片描述在这里插入图片描述

参考文献

1、王 力,等: 利用历元间差分观测值进行参考站周跳探测与修复
2、邹 璇,等:一种历元间差分单站单频周跳探测与修复方法
3、刘先冬,等: 历元间差分定位模型的粗差探测法探测周跳
4、胡加星,等:GPS 周跳探测方法综述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的C++程序,用于计算RTK历元差分。这个程序假设你已经有了两个历元的GPS观测数据,并且观测数据已经被预处理成了可用的格式。 ```cpp #include <iostream> #include <fstream> #include <string> #include <vector> #include <cmath> using namespace std; // 定义GPS卫星的常量 const double GM = 3.986005e14; const double OMEGA_E_DOT = 7.2921151467e-5; const double PI = 3.1415926535898; const double LIGHT_SPEED = 299792458.0; // 定义观测数据结构体 struct ObservationData { double prn; double psr; double adr; double doppler; double snr; }; // 定义卫星轨道参数结构体 struct SatelliteOrbit { double toe; double m0; double delta_n; double e; double sqrt_a; double omega0; double i0; double w; double omegadot; }; // 计算卫星位置 void CalculateSatellitePosition(double t, SatelliteOrbit orbit, double* position) { double tk = t - orbit.toe; if (tk > 302400.0) { tk -= 604800.0; } else if (tk < -302400.0) { tk += 604800.0; } double a = orbit.sqrt_a * orbit.sqrt_a; double n0 = sqrt(GM / (a * a * a)); double n = n0 + orbit.delta_n; double mk = orbit.m0 + n * tk; double ek = mk; double ek_old = ek + 1.0; while (abs(ek - ek_old) > 1.0e-15) { ek_old = ek; ek = mk + orbit.e * sin(ek_old); } double sin_vk = sqrt(1.0 - orbit.e * orbit.e) * sin(ek) / (1.0 - orbit.e * cos(ek)); double cos_vk = (cos(ek) - orbit.e) / (1.0 - orbit.e * cos(ek)); double vk = atan2(sin_vk, cos_vk); double phik = vk + orbit.w; double delta_uk = orbit.cus * sin(2.0 * phik) + orbit.cuc * cos(2.0 * phik); double delta_rk = orbit.crs * sin(2.0 * phik) + orbit.crc * cos(2.0 * phik); double delta_ik = orbit.cis * sin(2.0 * phik) + orbit.cic * cos(2.0 * phik); double uk = phik + delta_uk; double rk = a * (1.0 - orbit.e * cos(ek)) + delta_rk; double ik = orbit.i0 + delta_ik + orbit.idot * tk; double xk_p = rk * cos(uk); double yk_p = rk * sin(uk); double omegak = orbit.omega0 + (orbit.omegadot - OMEGA_E_DOT) * tk - OMEGA_E_DOT * orbit.toe; position[0] = xk_p * cos(omegak) - yk_p * cos(ik) * sin(omegak); position[1] = xk_p * sin(omegak) + yk_p * cos(ik) * cos(omegak); position[2] = yk_p * sin(ik); } // 计算卫星钟差 double CalculateSatelliteClockBias(double t, SatelliteOrbit orbit) { double tk = t - orbit.toe; if (tk > 302400.0) { tk -= 604800.0; } else if (tk < -302400.0) { tk += 604800.0; } return orbit.af0 + orbit.af1 * tk + orbit.af2 * tk * tk; } // 计算卫星信号传播时 double CalculateSignalPropagationTime(double* receiver_position, double* satellite_position) { double delta_x = receiver_position[0] - satellite_position[0]; double delta_y = receiver_position[1] - satellite_position[1]; double delta_z = receiver_position[2] - satellite_position[2]; double delta_r = sqrt(delta_x * delta_x + delta_y * delta_y + delta_z * delta_z); return delta_r / LIGHT_SPEED; } // 计算伪距 double CalculatePseudorange(double receiver_clock_bias, double satellite_clock_bias, double signal_propagation_time) { return receiver_clock_bias - satellite_clock_bias + signal_propagation_time * LIGHT_SPEED; } // 计算载波相位 double CalculateCarrierPhase(double receiver_clock_bias, double satellite_clock_bias, double signal_propagation_time, double carrier_frequency) { return CalculatePseudorange(receiver_clock_bias, satellite_clock_bias, signal_propagation_time) / carrier_frequency; } // 计算历元单差 double CalculateSingleDifference(ObservationData data1, ObservationData data2, SatelliteOrbit orbit1, SatelliteOrbit orbit2, double* receiver_position) { double satellite_position1[3]; CalculateSatellitePosition(data1.psr, orbit1, satellite_position1); double satellite_position2[3]; CalculateSatellitePosition(data2.psr, orbit2, satellite_position2); double satellite_clock_bias1 = CalculateSatelliteClockBias(data1.psr, orbit1); double satellite_clock_bias2 = CalculateSatelliteClockBias(data2.psr, orbit2); double signal_propagation_time1 = CalculateSignalPropagationTime(receiver_position, satellite_position1); double signal_propagation_time2 = CalculateSignalPropagationTime(receiver_position, satellite_position2); double pseudorange1 = CalculatePseudorange(data1.psr, satellite_clock_bias1, signal_propagation_time1); double pseudorange2 = CalculatePseudorange(data2.psr, satellite_clock_bias2, signal_propagation_time2); double carrier_phase1 = CalculateCarrierPhase(data1.psr, satellite_clock_bias1, signal_propagation_time1, 1575.42e6); double carrier_phase2 = CalculateCarrierPhase(data2.psr, satellite_clock_bias2, signal_propagation_time2, 1575.42e6); return pseudorange1 - pseudorange2 - (carrier_phase1 - carrier_phase2) / (2.0 * PI); } // 计算历元双差 double CalculateDoubleDifference(ObservationData data1, ObservationData data2, ObservationData data3, ObservationData data4, SatelliteOrbit orbit1, SatelliteOrbit orbit2, SatelliteOrbit orbit3, SatelliteOrbit orbit4, double* receiver_position) { double single_difference1 = CalculateSingleDifference(data1, data2, orbit1, orbit2, receiver_position); double single_difference2 = CalculateSingleDifference(data3, data4, orbit3, orbit4, receiver_position); return single_difference1 - single_difference2; } int main() { // 读取GPS观测数据 ifstream infile("obs.txt"); vector<ObservationData> observations1; vector<ObservationData> observations2; string line; while (getline(infile, line)) { if (line[0] == '>' || line[0] == '#') { continue; } ObservationData data; sscanf(line.c_str(), "%lf %lf %lf %lf %lf", &data.prn, &data.psr, &data.adr, &data.doppler, &data.snr); if (line[0] == '1') { observations1.push_back(data); } else { observations2.push_back(data); } } infile.close(); // 读取卫星轨道参数 infile.open("eph.txt"); vector<SatelliteOrbit> orbits1; vector<SatelliteOrbit> orbits2; while (getline(infile, line)) { if (line[0] == '>' || line[0] == '#') { continue; } SatelliteOrbit orbit; sscanf(line.c_str(), "%d %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf", &orbit.prn, &orbit.toe, &orbit.m0, &orbit.delta_n, &orbit.e, &orbit.sqrt_a, &orbit.cuc, &orbit.cus, &orbit.crc, &orbit.crs, &orbit.cic, &orbit.cis, &orbit.i0, &orbit.w, &orbit.omegadot); if (line[0] == '1') { orbits1.push_back(orbit); } else { orbits2.push_back(orbit); } } infile.close(); // 设置接收机位置 double receiver_position[3] = {0.0, 0.0, 0.0}; // 计算历元双差 double double_difference = CalculateDoubleDifference(observations1[0], observations1[1], observations2[0], observations2[1], orbits1[0], orbits1[1], orbits2[0], orbits2[1], receiver_position); // 输出结果 cout << "Double difference: " << double_difference << endl; return 0; } ``` 注意:这只是一个简单的程序示例,实际应用中可能需要更复杂的算法和数据处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值