RtcmMsmHeader.java
/* Copyright 2022-2026 Thales Alenia Space
* 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.gnss.metric.messages.rtcm.msm.headers;
import java.util.ArrayList;
import java.util.List;
import org.hipparchus.util.Pair;
import org.orekit.gnss.SatInSystem;
/**
* Base class for RTCM MSM message headers, holding common metadata and bit masks.
* @author Nathan Schiffmacher
* @since 14.0
*/
public abstract class RtcmMsmHeader {
/** Reference Station ID. */
private String referenceStation;
/** Multiple Message Indicator. */
private boolean multipleMessage;
/** Issue of Data Station. */
private int issueofDataStation;
/** Clock Steering Indicator. */
private int clockSteeringIndicator;
/** External Clock Indicator. */
private int externalClockIndicator;
/** Divergence-free Smoothing Indicator. */
private boolean divergenceFreeSmoothingIndicator;
/** Smoothing Interval. */
private int smoothingInterval;
/** Satellites mask indicating which satellites are included in the MSM message. */
private long satellitesMask;
/** Signals mask indicating which signals are included in the MSM message. */
private long signalsMask;
/** Cells mask indicating which satellite/signal combinations are included in the MSM message. */
private long cellsMask;
/** Epoch time within the BeiDou week, in seconds. */
private double epochTime;
/** Constructor. */
public RtcmMsmHeader() {
// Nothing to do ...
}
/**
* Get the epoch time.
* @return epoch time within the GNSS week, in seconds
*/
public double getEpochTime() {
return this.epochTime;
}
/**
* Set the epoch time.
* @param epochTime epoch time within the GNSS week, in seconds
*/
public void setEpochTime(final double epochTime) {
this.epochTime = epochTime;
}
/**
* Get the Reference Station ID.
* @return the Reference Station ID
*/
public String getReferenceStation() {
return referenceStation;
}
/**
* Set the Reference Station ID.
* @param referenceStation the Reference Station ID to set
*/
public void setReferenceStation(final String referenceStation) {
this.referenceStation = referenceStation;
}
/**
* Get the MSM Multiple Message Flag (DF393).
* @return true if more MSM messages follow for the epoch, false otherwise
*/
public boolean getMultipleMessageFlag() {
return multipleMessage;
}
/**
* Set the MSM Multiple Message Flag (DF393).
* @param multipleMessageFlag true if more MSM messages follow for the epoch, false otherwise
*/
public void setMultipleMessageFlag(final boolean multipleMessageFlag) {
this.multipleMessage = multipleMessageFlag;
}
/**
* Get the Issue of Data Station.
* @return the Issue of Data Station
*/
public int getIssueofDataStation() {
return issueofDataStation;
}
/**
* Set the Issue of Data Station.
* @param issueofDataStation the Issue of Data Station to set
*/
public void setIssueofDataStation(final int issueofDataStation) {
this.issueofDataStation = issueofDataStation;
}
/**
* Get the Clock Steering Indicator.
* @return the Clock Steering Indicator
*/
public int getClockSteeringIndicator() {
return clockSteeringIndicator;
}
/**
* Set the Clock Steering Indicator.
* @param clockSteeringIndicator the Clock Steering Indicator to set
*/
public void setClockSteeringIndicator(final int clockSteeringIndicator) {
this.clockSteeringIndicator = clockSteeringIndicator;
}
/**
* Get the External Clock Indicator.
* @return the External Clock Indicator
*/
public int getExternalClockIndicator() {
return externalClockIndicator;
}
/**
* Set the External Clock Indicator.
* @param externalClockIndicator the External Clock Indicator to set
*/
public void setExternalClockIndicator(final int externalClockIndicator) {
this.externalClockIndicator = externalClockIndicator;
}
/**
* Get the Divergence-free Smoothing Indicator.
* @return true if divergence-free smoothing is used, false otherwise
*/
public boolean getDivergenceFreeSmoothingIndicator() {
return divergenceFreeSmoothingIndicator;
}
/**
* Set the Divergence-free Smoothing Indicator.
* @param divergenceFreeSmoothingIndicator the Divergence-free Smoothing Indicator to set
*/
public void setDivergenceFreeSmoothingIndicator(final boolean divergenceFreeSmoothingIndicator) {
this.divergenceFreeSmoothingIndicator = divergenceFreeSmoothingIndicator;
}
/**
* Get the Smoothing Interval.
* @return the Smoothing Interval
*/
public int getSmoothingInterval() {
return smoothingInterval;
}
/**
* Set the Smoothing Interval.
* @param smoothingInterval the Smoothing Interval to set
*/
public void setSmoothingInterval(final int smoothingInterval) {
this.smoothingInterval = smoothingInterval;
}
/**
* Get the satellites mask.
* @return bit mask indicating which satellites are present
*/
public long getSatellitesMask() {
return this.satellitesMask;
}
/**
* Set the satellites mask.
* @param satellitesMask bit mask indicating which satellites are present
*/
public void setSatellitesMask(final long satellitesMask) {
this.satellitesMask = satellitesMask;
}
/**
* Get the number of satellites present in the mask.
* @return number of satellites with their bit set in the mask
*/
public int getNumberOfSatellites() {
return Long.bitCount(this.satellitesMask);
}
/**
* Get the signals mask.
* @return bit mask indicating which signals are present
*/
public long getSignalsMask() {
return this.signalsMask;
}
/**
* Set the signals mask.
* @param signalsMask bit mask indicating which signals are present
*/
public void setSignalsMask(final long signalsMask) {
this.signalsMask = signalsMask;
}
/**
* Get the number of signals present in the mask.
* @return number of signals with their bit set in the mask
*/
public int getNumberOfSignals() {
return Long.bitCount(this.signalsMask);
}
/**
* Get the cells mask.
* @return bit mask indicating which satellite/signal cells are present
*/
public long getCellsMask() {
return this.cellsMask;
}
/**
* Set the cells mask.
* @param cellsMask bit mask indicating which satellite/signal cells are present
*/
public void setCellsMask(final long cellsMask) {
this.cellsMask = cellsMask;
}
/**
* Get the number of cells present in the mask.
* @return number of satellite/signal cells with their bit set in the mask
*/
public int getNumberOfCells() {
return Long.bitCount(this.cellsMask);
}
/**
* Convert the cells mask to a list of satellite/signal pairs.
* @return list of satellite/signal pairs corresponding to the active cells
*/
public List<Pair<SatInSystem, RtcmMsmSignalId>> convertCellsMask() {
final List<SatInSystem> satellites = this.convertSatellitesMask();
final List<RtcmMsmSignalId> signals = this.convertSignalsMask();
final List<Pair<SatInSystem, RtcmMsmSignalId>> cells = new ArrayList<>();
// Compute the number of cells
final int nSatellites = satellites.size();
final int nSignals = signals.size();
final int nCells = nSatellites * nSignals;
// Use the cells mask to build the List of cells present
for (int satIdx = 0; satIdx < nSatellites; satIdx++) {
for (int sigIdx = 0; sigIdx < nSignals; sigIdx++) {
final int cellIdx = satIdx * nSignals + sigIdx;
if ((this.getCellsMask() >> (nCells - 1 - cellIdx) & 1) == 1) {
cells.add(new Pair<>(satellites.get(satIdx), signals.get(sigIdx)));
}
}
}
return cells;
}
/**
* Convert the satellites mask to a list of satellites.
* @return list of satellites present in the MSM message
*/
public abstract List<SatInSystem> convertSatellitesMask();
/**
* Convert the signals mask to a list of signals.
* @return list of signals present in the MSM message
*/
public abstract List<RtcmMsmSignalId> convertSignalsMask();
}