GICI学习笔记-RTK

添加测量值:

bool RtkEstimator::addGnssMeasurementAndState(
    const GnssMeasurement& measurement_rov, 
    const GnssMeasurement& measurement_ref)
{
  // Get prior states
  if (!spp_estimator_->addGnssMeasurementAndState(measurement_rov)) {
    return false;
  }
  if (!spp_estimator_->estimate()) {
    return false;
  }
  Eigen::Vector3d position_prior = spp_estimator_->getPositionEstimate();
  Eigen::Vector3d velocity_prior = spp_estimator_->getVelocityEstimate();
  curState().status = GnssSolutionStatus::Single;

  // Set to local measurement handle
  curGnssRov() = measurement_rov;
  curGnssRov().position = position_prior;
  curGnssRef() = measurement_ref;

  // Erase duplicated phases, arrange to one observation per phase
  gnss_common::rearrangePhasesAndCodes(curGnssRov());
  gnss_common::rearrangePhasesAndCodes(curGnssRef());

  // Form double difference pair
  // 按照最高高度角选取基准卫星,
  GnssMeasurementDDIndexPairs index_pairs = gnss_common::formPhaserangeDDPair(
    curGnssRov(), curGnssRef(), gnss_base_options_.common);

  // Cycle-slip detection
  if (!isFirstEpoch()) {
    cycleSlipDetectionSD(lastGnssRov(), lastGnssRef(), 
      curGnssRov(), curGnssRef(), gnss_base_options_.common);
  }
  
  // Add parameter blocks
  double timestamp = curGnssRov().timestamp;
  curState().timestamp = timestamp;
  // position block
  BackendId position_id = addGnssPositionParameterBlock(curGnssRov().id, position_prior);
  curState().id = position_id;
  curState().id_in_graph = position_id;
  // ambiguity blocks
  addSdAmbiguityParameterBlocks(curGnssRov(), 
    curGnssRef(), index_pairs, curGnssRov().id, curAmbiguityState());
  if (rtk_options_.estimate_velocity) {
    // velocity block
    addGnssVelocityParameterBlock(curGnssRov().id, velocity_prior);
    // frequency block
    int num_valid_doppler_system = 0;
    addFrequencyParameterBlocks(curGnssRov(), curGnssRov().id, num_valid_doppler_system);
  }
  
  // Add pseudorange residual blocks
  int num_valid_satellite = 0;
  addDdPseudorangeResidualBlocks(curGnssRov(), 
    curGnssRef(), index_pairs, curState(), num_valid_satellite);

  // Check if insufficient satellites
  if (!checkSufficientSatellite(num_valid_satellite, 0)) {
    // erase parameters in current state
    eraseGnssPositionParameterBlock(curState());
    eraseAmbiguityParameterBlocks(curAmbiguityState());
    if (rtk_options_.estimate_velocity) {
      eraseGnssVelocityParameterBlock(curState());
      eraseFrequencyParameterBlocks(curState());
    }

    return false;
  }
  num_satellites_ = num_valid_satellite;

  // Add phaserange residual blocks
  addDdPhaserangeResidualBlocks(curGnssRov(), curGnssRef(), index_pairs, curState());

  // Add doppler residual blocks
  if (rtk_options_.estimate_velocity) {
    addDopplerResidualBlocks(curGnssRov(), curState(), num_valid_satellite);
  }

  // Add relative errors
  if (!isFirstEpoch()) {
    if (!rtk_options_.estimate_velocity) {
      // position
      addRelativePositionResidualBlock(lastState(), curState());
    }
    else {
      // position and velocity
      addRelativePositionAndVelocityBlock(lastState(), curState());
      // frequency
      addRelativeFrequencyBlock(lastState(), curState());
    }
    // ambiguity
    addRelativeAmbiguityResidualBlock(
      lastGnssRov(), curGnssRov(), lastAmbiguityState(), curAmbiguityState());
  }

  // Compute DOP
  updateGdop(curGnssRov(), index_pairs);

  return true;
}

 

单差对:

// Form single difference pseudorange pair
GnssMeasurementSDIndexPairs formPseudorangeSDPair(
                            const GnssMeasurement& measurement_rov, 
                            const GnssMeasurement& measurement_ref,
                            const GnssCommonOptions& options)
{
    GnssMeasurementSDIndexPairs index_pairs;
    //循环流动站测量值,确定可用的measurement_rov

    ...

// 双循环,外层循环为measurement_rov,内层循环为measurement_ref,
  // Find valid matches in measurement_ref
  for (auto index : indexes_1) 
  {
    auto& satellite = measurement_rov.satellites.at(index.prn);
    auto observation = satellite.observations.at(index.code_type);
    for (auto& sat : measurement_ref.satellites) {
      auto& satellite_2 = sat.second;

        //寻找流动站和基站的共视卫星
      if (satellite_2.prn != satellite.prn) continue;

      if (!checkObservationValid(measurement_ref, 
          GnssMeasurementIndex(satellite.prn, index.code_type), 
          ObservationType::Pseudorange)) {
        continue;
      }
       // 找到共视卫星后存入SD对index_pairs
      index_pairs.push_back(GnssMeasurementSDIndexPair(
        index, GnssMeasurementIndex(satellite.prn, index.code_type)));
    }
  }
}

 

模糊度相关:

//rtk_estimator.cpp
bool RtkEstimator::estimate() 
{
   ...
 // solve
    AmbiguityResolution::Result ret = ambiguity_resolution_->solveRtk(
      curState().id, curAmbiguityState().ids, 
      ambiguity_covariance, gnss_measurement_pairs_.back());
   ...
}
//ambiguity_resolution_differential.cpp
AmbiguityResolution::Result AmbiguityResolution::solveRtk(
             const BackendId& epoch_id, 
             const std::vector<BackendId>& ambiguity_ids,
             const Eigen::MatrixXd& ambiguity_covariance,
             const std::pair<GnssMeasurement, GnssMeasurement>& measurements)
{
   ...
    int num_fixed = trySolveLanes(
      lane_groups_.at(i), min_percentage_fixation, use_rounding);
   ...
}
//ambiguity_resolution.cpp
// Try to solve ambiguity by all partial AR methods
int AmbiguityResolution::trySolveLanes(
  const std::vector<size_t>& indexes, 
  const double min_percentage_fixation,
  const bool use_rounding)
{
  ...
    num_fixed = solveLanes(indexes, min_percentage_fixation, 
      method, use_rounding, skip_full);
  ...
}
//ambiguity_resolution.cpp
// Solve ambiguities
int AmbiguityResolution::solveLanes(
  const std::vector<size_t>& indexes, 
  const double min_percentage_fixation,
  const DelMethod method,
  const bool use_rounding,
  const bool skip_full)
{
  ...
  if (sqrt(active_float_covariance(num_active - 1, num_active - 1)) < 0.25)
  if (solveAmbiguityLambda(active_float_ambiguities, 
       active_float_covariance, options_.ratio, fixed_ambiguities, ratio)) break;
  ...
}
//ambiguity_common.cpp
// Solve integer ambiguity by LAMBDA
bool solveAmbiguityLambda(const Eigen::VectorXd& float_ambiguities,
                          const Eigen::MatrixXd& covariance, 
                          const double ratio_threshold, 
                          Eigen::VectorXd& fixed_ambiguities,
                          double& ratio)
{
   ...
  // Lambda search
  lambda(float_ambiguities.size(), 2, float_ambiguities.data(), 
         covariance.data(), fixed_template.data(), residuals.data());
   ...
}
//rtlib lambda.c
extern int lambda(int n, int m, const double *a, const double *Q, double *F,
                  double *s)
{
    int info;
    double *L,*D,*Z,*z,*E;
    
    if (n<=0||m<=0) return -1;
    L=zeros(n,n); D=mat(n,1); Z=eye(n); z=mat(n,1); E=mat(n,m);
    
    /* LD factorization */
    if (!(info=LD(n,Q,L,D))) {
        
        /* lambda reduction */
        reduction(n,L,D,Z);
        matmul("TN",n,1,n,1.0,Z,a,0.0,z); /* z=Z'*a */
        
        /* mlambda search */
        if (!(info=search(n,m,L,D,z,E,s))) {
            
            info=solve("T",Z,E,n,m,F); /* F=Z'\E */
        }
    }
    free(L); free(D); free(Z); free(z); free(E);
    return info;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值