AbstractSingleFrequencyCombination.java
- /* Copyright 2002-2020 CS Group
- * Licensed to CS Group (CS) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * CS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.orekit.estimation.measurements.gnss;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- import org.orekit.errors.OrekitException;
- import org.orekit.errors.OrekitMessages;
- import org.orekit.gnss.CombinedObservationData;
- import org.orekit.gnss.CombinedObservationDataSet;
- import org.orekit.gnss.Frequency;
- import org.orekit.gnss.MeasurementType;
- import org.orekit.gnss.ObservationData;
- import org.orekit.gnss.ObservationDataSet;
- import org.orekit.gnss.ObservationType;
- import org.orekit.gnss.RinexHeader;
- import org.orekit.gnss.SatelliteSystem;
- /** Base class for single frequency combination of measurements.
- * @author Bryan Cazabonne
- * @since 10.1
- */
- public abstract class AbstractSingleFrequencyCombination implements MeasurementCombination {
- /** Type of combination of measurements. */
- private final CombinationType type;
- /** Satellite system used for the combination. */
- private final SatelliteSystem system;
- /**
- * Constructor.
- * @param type combination of measurements type
- * @param system satellite system
- */
- protected AbstractSingleFrequencyCombination(final CombinationType type, final SatelliteSystem system) {
- this.type = type;
- this.system = system;
- }
- /** {@inheritDoc} */
- @Override
- public String getName() {
- return type.getName();
- }
- /** {@inheritDoc} */
- @Override
- public CombinedObservationDataSet combine(final ObservationDataSet observations) {
- // Rinex file header
- final RinexHeader header = observations.getHeader();
- // Rinex version to integer
- final int version = (int) header.getRinexVersion();
- // Initialize list of measurements
- final List<ObservationData> pseudoRanges = new ArrayList<>();
- final List<ObservationData> phases = new ArrayList<>();
- // Loop on observation data to fill lists
- for (final ObservationData od : observations.getObservationData()) {
- if (!Double.isNaN(od.getValue())) {
- if (od.getObservationType().getMeasurementType() == MeasurementType.PSEUDO_RANGE) {
- pseudoRanges.add(od);
- } else if (od.getObservationType().getMeasurementType() == MeasurementType.CARRIER_PHASE) {
- phases.add(od);
- }
- }
- }
- // Initialize list of combined observation data
- final List<CombinedObservationData> combined = new ArrayList<>();
- for (int i = 0; i < phases.size(); i++) {
- for (int j = 0; j < pseudoRanges.size(); j++) {
- final boolean combine = isCombinationPossible(version, phases.get(i), pseudoRanges.get(j));
- if (combine) {
- combined.add(combine(phases.get(i), pseudoRanges.get(j)));
- }
- }
- }
- return new CombinedObservationDataSet(observations.getHeader(), observations.getSatelliteSystem(),
- observations.getPrnNumber(), observations.getDate(),
- observations.getRcvrClkOffset(), combined);
- }
- /**
- * Combines observation data using a single frequency combination of measurements.
- * @param phase phase measurement
- * @param pseudoRange pseudoRange measurement
- * @return a combined observation data
- */
- public CombinedObservationData combine(final ObservationData phase, final ObservationData pseudoRange) {
- // Observation types
- final ObservationType obsType1 = phase.getObservationType();
- final ObservationType obsType2 = pseudoRange.getObservationType();
- // Frequencies
- final Frequency freq1 = obsType1.getFrequency(system);
- final Frequency freq2 = obsType2.getFrequency(system);
- // Check if the combination of measurements if performed for two different frequencies
- if (freq1 != freq2) {
- throw new OrekitException(OrekitMessages.INCOMPATIBLE_FREQUENCIES_FOR_COMBINATION_OF_MEASUREMENTS,
- freq1, freq2, getName());
- }
- // Measurements types
- final MeasurementType measType1 = obsType1.getMeasurementType();
- final MeasurementType measType2 = obsType2.getMeasurementType();
- // Check if measurement types are the same
- if (measType1 == measType2) {
- // If the measurement types are the same, an exception is thrown
- throw new OrekitException(OrekitMessages.INVALID_MEASUREMENT_TYPES_FOR_COMBINATION_OF_MEASUREMENTS,
- measType1, measType2, getName());
- }
- // Frequency
- final double f = freq1.getMHzFrequency();
- // Combined value
- final double combinedValue = getCombinedValue(phase.getValue(), pseudoRange.getValue());
- // Combined observation data
- return new CombinedObservationData(CombinationType.PHASE_MINUS_CODE, MeasurementType.COMBINED_RANGE_PHASE,
- combinedValue, f, Arrays.asList(phase, pseudoRange));
- }
- /**
- * Get the combined observed value of two measurements.
- * @param phase observed value of the phase measurement
- * @param pseudoRange observed value of the range measurement
- * @return combined observed value
- */
- protected abstract double getCombinedValue(double phase, double pseudoRange);
- /**
- * Verifies if two observation data can be combine.
- * @param version Rinex file version (integer part)
- * @param phase phase measurement
- * @param pseudoRange pseudoRange measurement
- * @return true if observation data can be combined
- */
- private boolean isCombinationPossible(final int version, final ObservationData phase, final ObservationData pseudoRange) {
- // Observation types
- final ObservationType obsType1 = phase.getObservationType();
- final ObservationType obsType2 = pseudoRange.getObservationType();
- // Single-frequency combination is possible only if data frequencies are the same
- if (obsType1.getFrequency(system) == obsType2.getFrequency(system)) {
- // Switch on Rinex version
- switch (version) {
- case 2 : return true;
- case 3 : return obsType1.getSignalCode() == obsType2.getSignalCode();
- default: return false;
- }
- } else {
- // False because observation data have different frequency
- return false;
- }
- }
- }