@brief Use a GMM to estimate the error distribution of a factor * * @param Graph reference to the factor graph object * @param Config reference to the factor graph config object that specifies the motion model * @return nothing * */
| 166 | * |
| 167 | */ |
| 168 | void TuneErrorModel(libRSF::FactorGraph &Graph, |
| 169 | libRSF::FactorGraphConfig &Config) |
| 170 | { |
| 171 | if(Config.GNSS.ErrorModel.TuningType != libRSF::ErrorModelTuningType::None) |
| 172 | { |
| 173 | /** compute resudiuals of the factor graph */ |
| 174 | std::vector<double> ErrorData; |
| 175 | Graph.computeUnweightedError(libRSF::FactorType::Pseudorange3_ECEF, ErrorData); |
| 176 | |
| 177 | if(Config.GNSS.ErrorModel.TuningType == libRSF::ErrorModelTuningType::EM) |
| 178 | { |
| 179 | /** fill empty GMM */ |
| 180 | libRSF::GaussianMixture<1> GMM; |
| 181 | |
| 182 | if(GMM.getNumberOfComponents() == 0) |
| 183 | { |
| 184 | GMM.initSpread(GMM_N, 10); |
| 185 | } |
| 186 | |
| 187 | /** call the EM algorithm */ |
| 188 | libRSF::GaussianMixture<1>::EstimationConfig GMMConfig; |
| 189 | GMMConfig.EstimationAlgorithm = libRSF::ErrorModelTuningType::EM; |
| 190 | GMMConfig.RemoveSmallComponents = false; |
| 191 | GMMConfig.MergeSimiliarComponents = false; |
| 192 | GMM.estimate(ErrorData, GMMConfig); |
| 193 | |
| 194 | /** remove offset of the first "LOS" component */ |
| 195 | GMM.removeOffset(); |
| 196 | |
| 197 | /** apply error model */ |
| 198 | if(Config.GNSS.ErrorModel.MixtureType == libRSF::ErrorModelMixtureType::SumMix) |
| 199 | { |
| 200 | libRSF::SumMix1 NewSMModel(GMM); |
| 201 | Graph.setNewErrorModel(libRSF::FactorType::Pseudorange3_ECEF, NewSMModel); |
| 202 | } |
| 203 | else if(Config.GNSS.ErrorModel.MixtureType == libRSF::ErrorModelMixtureType::MaxMix) |
| 204 | { |
| 205 | libRSF::MaxMix1 NewMMModel(GMM); |
| 206 | Graph.setNewErrorModel(libRSF::FactorType::Pseudorange3_ECEF, NewMMModel); |
| 207 | } |
| 208 | |
| 209 | } |
| 210 | else if(Config.GNSS.ErrorModel.TuningType == libRSF::ErrorModelTuningType::VBI) |
| 211 | { |
| 212 | /** initialize GMM */ |
| 213 | static libRSF::GaussianMixture<1> GMMAdaptive; |
| 214 | libRSF::GaussianComponent<1> Component; |
| 215 | |
| 216 | if(GMMAdaptive.getNumberOfComponents() == 0) |
| 217 | { |
| 218 | GMMAdaptive.initSpread(1, 10); |
| 219 | } |
| 220 | |
| 221 | /** calculate statistics for GMM initialization*/ |
| 222 | std::vector<double> v = ErrorData; |
| 223 | double sum = std::accumulate(v.begin(), v.end(), 0.0); |
| 224 | double mean = sum / v.size(); |
| 225 |
no test coverage detected