Skip to content
Snippets Groups Projects
Commit 9cddd18c authored by Bryan Cazabonne's avatar Bryan Cazabonne
Browse files

Added RTCM 1019 message.

parent 3681f899
No related branches found
No related tags found
No related merge requests found
Showing
with 1035 additions and 3 deletions
/* Copyright 2002-2021 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.gnss.metric.messages.rtcm;
/**
* Container for common data in RTCM message.
* @author Bryan Cazabonne
* @since 11.0
*/
public class RtcmData {
// No common data
}
/* Copyright 2002-2021 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.gnss.metric.messages.rtcm;
import java.util.Collections;
import java.util.List;
import org.orekit.gnss.metric.messages.ParsedMessage;
/**
* Base class for RTCM messages.
*
* @author Bryan Cazabonne
* @since 11.0
*
*/
public class RtcmMessage<D extends RtcmData> extends ParsedMessage {
/** Message data. */
private final List<D> rtcmData;
/**
* Constructor.
* @param typeCode message number
* @param rtcmData message data
*/
public RtcmMessage(final int typeCode, final List<D> rtcmData) {
super(typeCode);
this.rtcmData = rtcmData;
}
/**
* Get the data.
* @return data
*/
public List<D> getData() {
return Collections.unmodifiableList(rtcmData);
}
}
/* Copyright 2002-2021 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.gnss.metric.messages.rtcm.ephemeris;
/**
* RTCM 1019 message: GPS Satellite Ephemeris Data.
* @author Bryan Cazabonne
* @since 11.0
*/
public class Rtcm1019 extends RtcmEphemerisMessage<Rtcm1019Data> {
/**
* Constructor.
* @param typeCode message number
* @param rtcm1019Data RTCM 1019 message data
*/
public Rtcm1019(final int typeCode, final Rtcm1019Data rtcm1019Data) {
super(typeCode, rtcm1019Data);
}
}
/* Copyright 2002-2021 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.gnss.metric.messages.rtcm.ephemeris;
import org.orekit.annotation.DefaultDataContext;
import org.orekit.data.DataContext;
import org.orekit.gnss.SatelliteSystem;
import org.orekit.gnss.navigation.GPSNavigationMessage;
import org.orekit.propagation.analytical.gnss.GPSPropagator;
import org.orekit.time.GNSSDate;
import org.orekit.time.TimeScales;
/**
* Container for RTCM 1019 data.
* @author Bryan Cazabonne
* @since 11.0
*/
public class Rtcm1019Data extends RtcmEphemerisData {
/** GPS navigation message. */
private GPSNavigationMessage gpsNavigationMessage;
/** GPS Time of clock. */
private double gpsToc;
/** GPS code on L2. */
private int gpsCodeOnL2;
/** GPS L2 P data flag. */
private boolean gpsL2PDataFlag;
/** GPS fit interval. */
private int gpsFitInterval;
/** Constructor. */
public Rtcm1019Data() {
// Nothing to do ...
}
/**
* Get the GPS navigation message corresponding to the current RTCM data.
* <p>
* This object can be used to initialize a {@link GPSPropagator}
* <p>
* This method uses the {@link DataContext#getDefault()} to initialize
* the time scales used to configure the reference epochs of the navigation
* message.
*
* @return the GPS navigation message
*/
@DefaultDataContext
public GPSNavigationMessage getGpsNavigationMessage() {
return getGpsNavigationMessage(DataContext.getDefault().getTimeScales());
}
/**
* Get the GPS navigation message corresponding to the current RTCM data.
* <p>
* This object can be used to initialize a {@link GPSPropagator}
* <p>
* When calling this method, the reference epochs of the navigation message
* (i.e. ephemeris and clock epochs) are initialized using the provided time scales.
*
* @param timeScales time scales to use for initializing epochs
* @return the GPS navigation message
*/
public GPSNavigationMessage getGpsNavigationMessage(final TimeScales timeScales) {
// Satellite system
final SatelliteSystem system = SatelliteSystem.GPS;
// Week number and time of ephemeris
final int week = gpsNavigationMessage.getWeek();
final double toe = gpsNavigationMessage.getTime();
// Set the ephemeris reference data
gpsNavigationMessage.setDate(new GNSSDate(week, SEC_TO_MILLI * toe, system, timeScales).getDate());
gpsNavigationMessage.setEpochToc(new GNSSDate(week, SEC_TO_MILLI * gpsToc, system, timeScales).getDate());
// Return the navigation message
return gpsNavigationMessage;
}
/**
* Set the GPS navigation message.
* @param gpsNavigationMessage the GPS navigation message to set
*/
public void setGpsNavigationMessage(final GPSNavigationMessage gpsNavigationMessage) {
this.gpsNavigationMessage = gpsNavigationMessage;
}
/**
* Get the GPS time of clock.
* <p>
* The GPS time of clock is given in seconds since
* the beginning of the GPS week.
* </p>
* @return the GPS time of clock
*/
public double getGpsToc() {
return gpsToc;
}
/**
* Set the GPS time of clock.
* @param toc the time of clock to set
*/
public void setGpsToc(final double toc) {
this.gpsToc = toc;
}
/**
* Get the GPS code on L2.
* <ul>
* <li>0: Reserved</li>
* <li>1: P code on</li>
* <li>2: C/A code on</li>
* <li>3: L2C on</li>
* </ul>
* @return the GPS code on L2
*/
public int getGpsCodeOnL2() {
return gpsCodeOnL2;
}
/**
* Set the GPS code on L2.
* @param gpsCodeOnL2 the code to set
*/
public void setGpsCodeOnL2(final int gpsCodeOnL2) {
this.gpsCodeOnL2 = gpsCodeOnL2;
}
/**
* Get the GPS L2 P-Code data flag.
* @return true L2 P-Code NAV data ON
*/
public boolean getGpsL2PDataFlag() {
return gpsL2PDataFlag;
}
/**
* Set the GPS L2 P-code data flag.
* @param gpsL2PDataFlag the flag to set
*/
public void setGpsL2PDataFlag(final boolean gpsL2PDataFlag) {
this.gpsL2PDataFlag = gpsL2PDataFlag;
}
/**
* Get the GPS fit interval.
* @return the GPS fit interval
*/
public int getGpsFitInterval() {
return gpsFitInterval;
}
/**
* Set the GPS fit interval.
* @param gpsFitInterval
*/
public void setGpsFitInterval(final int gpsFitInterval) {
this.gpsFitInterval = gpsFitInterval;
}
}
/* Copyright 2002-2021 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.gnss.metric.messages.rtcm.ephemeris;
import org.orekit.gnss.metric.messages.rtcm.RtcmData;
import org.orekit.gnss.metric.messages.rtcm.ephemeris.utils.AccuracyProvider;
/**
* Container for common data in RTCM ephemeris message type.
* @author Bryan Cazabonne
* @since 11.0
*/
public class RtcmEphemerisData extends RtcmData {
/** Seconds to milliseconds converter. */
protected static final double SEC_TO_MILLI = 1000.0;
/** Satellite ID. */
private int rtcmSatelliteId;
/** Accuracy indicator. */
private AccuracyProvider accuracy;
/** Constructor. */
public RtcmEphemerisData() {
// Nothing to do ...
}
/**
* Get the satellite ID.
* @return the satellite ID
*/
public int getSatelliteID() {
return rtcmSatelliteId;
}
/**
* Set the satellite ID.
* @param satelliteID the ID to set
*/
public void setSatelliteID(final int satelliteID) {
this.rtcmSatelliteId = satelliteID;
}
/**
* Get the accuracy provider of the ephemeris message.
* @return the accuracy provider
*/
public AccuracyProvider getAccuracyProvider() {
return accuracy;
}
/**
* Set the accuracy provider of the ephemeris message.
* @param provider the provider to set
*/
public void setAccuracyProvider(final AccuracyProvider provider) {
this.accuracy = provider;
}
}
/* Copyright 2002-2021 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.gnss.metric.messages.rtcm.ephemeris;
import java.util.Collections;
import org.orekit.gnss.metric.messages.rtcm.RtcmMessage;
/**
* Base class for RTCM ephemeris messages.
* @author Bryan Cazabonne
* @since 11.0
*/
public class RtcmEphemerisMessage<D extends RtcmEphemerisData> extends RtcmMessage<D> {
/**
* Constructor.
* @param typeCode message number
* @param rtcmData message data
*/
public RtcmEphemerisMessage(final int typeCode, final D rtcmData) {
// Ephemeris messages contain only one entry
super(typeCode, Collections.singletonList(rtcmData));
}
/**
* Get the ephemeris data contain in the ephemeris message.
* @return the ephemeris data contain in the ephemeris message
*/
public D getEphemerisData() {
// Ephemeris data message contain only one entry
return getData().get(0);
}
}
/* Copyright 2002-2021 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.
*/
/**
*
* This package provides all supported RTCM ephemeris
* {@link org.orekit.gnss.metric.messages.ParsedMessage messages}.
*
* @author Bryan Cazabonne
* @since 11.0
*/
package org.orekit.gnss.metric.messages.rtcm.ephemeris;
/* Copyright 2002-2021 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.
*/
/**
*
* This package provides all supported RTCM {@link org.orekit.gnss.metric.messages.ParsedMessage
* messages}.
*
* @author Bryan Cazabonne
* @since 11.0
*/
package org.orekit.gnss.metric.messages.rtcm;
......@@ -18,6 +18,7 @@ package org.orekit.gnss.metric.parser;
import java.util.Locale;
import org.hipparchus.util.FastMath;
/** Enum containing all intermediate level data fields that can be parsed
* to build a RTCM message.
......@@ -33,6 +34,283 @@ public enum RtcmDataField implements DataField {
public String stringValue(final EncodedMessage message, final int n) {
return String.format(Locale.US, "%4s", DataType.U_INT_12.decode(message).intValue()).trim();
}
};
},
/** GPS Satellite ID. */
DF009 {
/** {@inheritDoc} */
@Override
public int intValue(final EncodedMessage message) {
return DataType.U_INT_6.decode(message).intValue();
}
},
/** GPS IODE (Issue Of Data, Ephemeris). */
DF071 {
/** {@inheritDoc} */
@Override
public int intValue(final EncodedMessage message) {
return DataType.BIT_8.decode(message).intValue();
}
},
/** GPS Week number. */
DF076 {
/** {@inheritDoc} */
@Override
public int intValue(final EncodedMessage message) {
return DataType.U_INT_10.decode(message).intValue();
}
},
/** GPS SV Accuracy. */
DF077 {
/** {@inheritDoc} */
@Override
public int intValue(final EncodedMessage message) {
return DataType.U_INT_4.decode(message).intValue();
}
},
/** GPS CODE ON L2. */
DF078 {
/** {@inheritDoc} */
@Override
public int intValue(final EncodedMessage message) {
return DataType.BIT_2.decode(message).intValue();
}
},
/** GPS Rate of Inclination Angle. */
DF079 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
// Returned value is in semi-circles/s
return FastMath.scalb(DataType.INT_14.decode(message).intValue(), -43);
}
},
/** GPS toc. */
DF081 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return DataType.U_INT_16.decode(message).intValue() * 16.0;
}
},
/** GPS a<sub>f2</sub>. */
DF082 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return FastMath.scalb(DataType.INT_8.decode(message).intValue(), -55);
}
},
/** GPS a<sub>f1</sub>. */
DF083 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return FastMath.scalb(DataType.INT_16.decode(message).intValue(), -43);
}
},
/** GPS a<sub>f0</sub>. */
DF084 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return FastMath.scalb(DataType.INT_22.decode(message).intValue(), -31);
}
},
/** GPS IODC (Issue Of Data, Clock). */
DF085 {
/** {@inheritDoc} */
@Override
public int intValue(final EncodedMessage message) {
return DataType.U_INT_10.decode(message).intValue();
}
},
/** GPS C<sub>rs</sub>. */
DF086 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return FastMath.scalb(DataType.INT_16.decode(message).intValue(), -5);
}
},
/** GPS Δn (DELTA n). */
DF087 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
// Returned value is in semi-circles/s
return FastMath.scalb(DataType.INT_16.decode(message).intValue(), -43);
}
},
/** GPS M<sub>0</sub>. */
DF088 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
// Returned value is in semi-circles
return FastMath.scalb(DataType.INT_32.decode(message).intValue(), -31);
}
},
/** GPS C<sub>uc</sub>. */
DF089 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return FastMath.scalb(DataType.INT_16.decode(message).intValue(), -29);
}
},
/** GPS Eccentricity (e). */
DF090 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return FastMath.scalb(DataType.U_INT_32.decode(message).longValue(), -33);
}
},
/** GPS C<sub>us</sub>. */
DF091 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return FastMath.scalb(DataType.INT_16.decode(message).intValue(), -29);
}
},
/** GPS A<sup>1/2</sup>. */
DF092 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return FastMath.scalb(DataType.U_INT_32.decode(message).longValue(), -19);
}
},
/** GPS t<sub>oe</sub>. */
DF093 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return DataType.U_INT_16.decode(message).intValue() * 16.0;
}
},
/** GPS C<sub>ic</sub>. */
DF094 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return FastMath.scalb(DataType.INT_16.decode(message).intValue(), -29);
}
},
/** GPS Ω<sub>0</sub> (OMEGA)<sub>0</sub>. */
DF095 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
// Returned value is in semi-circles
return FastMath.scalb(DataType.INT_32.decode(message).intValue(), -31);
}
},
/** GPS C<sub>is</sub>. */
DF096 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return FastMath.scalb(DataType.INT_16.decode(message).intValue(), -29);
}
},
/** GPS i<sub>0</sub>. */
DF097 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
// Returned value is in semi-circles
return FastMath.scalb(DataType.INT_32.decode(message).intValue(), -31);
}
},
/** GPS C<sub>rc</sub>. */
DF098 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return FastMath.scalb(DataType.INT_16.decode(message).intValue(), -5);
}
},
/** GPS ω (Argument of Perigee). */
DF099 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
// Returned value is in semi-circles
return FastMath.scalb(DataType.INT_32.decode(message).intValue(), -31);
}
},
/** GPS OMEGADOT (Rate of Right Ascension). */
DF100 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
// Returned value is in semi-circles/s
return FastMath.scalb(DataType.INT_24.decode(message).intValue(), -43);
}
},
/** GPS t<sub>GD</sub>. */
DF101 {
/** {@inheritDoc} */
@Override
public double doubleValue(final EncodedMessage message) {
return FastMath.scalb(DataType.INT_8.decode(message).intValue(), -31);
}
},
/** GPS SV HEALTH. */
DF102 {
/** {@inheritDoc} */
@Override
public int intValue(final EncodedMessage message) {
return DataType.U_INT_6.decode(message).intValue();
}
},
/** GPS L2 P data flag. */
DF103 {
/** {@inheritDoc} */
@Override
public boolean booleanValue(final EncodedMessage message) {
return DataType.BIT_1.decode(message) == 0;
}
},
/** GPS Fit Interval. */
DF137 {
/** {@inheritDoc} */
@Override
public int intValue(final EncodedMessage message) {
return DataType.BIT_1.decode(message).intValue();
}
},
}
......@@ -24,6 +24,12 @@ import java.util.regex.Pattern;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.gnss.metric.messages.ParsedMessage;
import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1019;
import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1019Data;
import org.orekit.gnss.metric.messages.rtcm.ephemeris.utils.AccuracyProvider;
import org.orekit.gnss.metric.messages.rtcm.ephemeris.utils.UserRangeAccuracy;
import org.orekit.gnss.navigation.GPSNavigationMessage;
import org.orekit.propagation.analytical.gnss.GPSOrbitalElements;
/** Enum containing the supported RTCM messages types.
*
......@@ -36,8 +42,74 @@ import org.orekit.gnss.metric.messages.ParsedMessage;
*/
public enum RtcmMessageType implements MessageType {
// RTCM messages are not currently supported in Orekit
// Contributions are welcome
/** GPS Ephemeris message. */
RTCM_1019("1019") {
/** {@inheritDoc} */
@Override
public ParsedMessage parse(final EncodedMessage encodedMessage,
final int messageNumber) {
// Initialize data container and navigation message
final Rtcm1019Data rtcm1019Data = new Rtcm1019Data();
final GPSNavigationMessage gpsNavMessage = new GPSNavigationMessage();
// Set the satellite ID
final int gpsId = RtcmDataField.DF009.intValue(encodedMessage);
rtcm1019Data.setSatelliteID(gpsId);
// Week number
final int gpsWeekNumber = RtcmDataField.DF076.intValue(encodedMessage);
gpsNavMessage.setWeek(gpsWeekNumber);
// Accuracy provider
final AccuracyProvider gpsProvider = new UserRangeAccuracy(RtcmDataField.DF077.intValue(encodedMessage));
rtcm1019Data.setAccuracyProvider(gpsProvider);
gpsNavMessage.setSvAccuracy(gpsProvider.getAccuracy());
// GPS Code on L2
rtcm1019Data.setGpsCodeOnL2(RtcmDataField.DF078.intValue(encodedMessage));
// Fill navigation message
gpsNavMessage.setPRN(gpsId);
gpsNavMessage.setIDot(RtcmDataField.DF079.doubleValue(encodedMessage) * GPSOrbitalElements.GPS_PI);
gpsNavMessage.setIODE(RtcmDataField.DF071.intValue(encodedMessage));
rtcm1019Data.setGpsToc(RtcmDataField.DF081.doubleValue(encodedMessage));
gpsNavMessage.setAf2(RtcmDataField.DF082.doubleValue(encodedMessage));
gpsNavMessage.setAf1(RtcmDataField.DF083.doubleValue(encodedMessage));
gpsNavMessage.setAf0(RtcmDataField.DF084.doubleValue(encodedMessage));
gpsNavMessage.setIODC(RtcmDataField.DF085.intValue(encodedMessage));
gpsNavMessage.setCrs(RtcmDataField.DF086.doubleValue(encodedMessage));
gpsNavMessage.setDeltaN(RtcmDataField.DF087.doubleValue(encodedMessage) * GPSOrbitalElements.GPS_PI);
gpsNavMessage.setM0(RtcmDataField.DF088.doubleValue(encodedMessage) * GPSOrbitalElements.GPS_PI);
gpsNavMessage.setCuc(RtcmDataField.DF089.doubleValue(encodedMessage));
gpsNavMessage.setE(RtcmDataField.DF090.doubleValue(encodedMessage));
gpsNavMessage.setCus(RtcmDataField.DF091.doubleValue(encodedMessage));
gpsNavMessage.setSqrtA(RtcmDataField.DF092.doubleValue(encodedMessage));
gpsNavMessage.setToe(RtcmDataField.DF093.doubleValue(encodedMessage));
gpsNavMessage.setCic(RtcmDataField.DF094.doubleValue(encodedMessage));
gpsNavMessage.setOmega0(RtcmDataField.DF095.doubleValue(encodedMessage) * GPSOrbitalElements.GPS_PI);
gpsNavMessage.setCis(RtcmDataField.DF096.doubleValue(encodedMessage));
gpsNavMessage.setI0(RtcmDataField.DF097.doubleValue(encodedMessage) * GPSOrbitalElements.GPS_PI);
gpsNavMessage.setCrc(RtcmDataField.DF098.doubleValue(encodedMessage));
gpsNavMessage.setPa(RtcmDataField.DF099.doubleValue(encodedMessage) * GPSOrbitalElements.GPS_PI);
gpsNavMessage.setOmegaDot(RtcmDataField.DF100.doubleValue(encodedMessage) * GPSOrbitalElements.GPS_PI);
gpsNavMessage.setTGD(RtcmDataField.DF101.doubleValue(encodedMessage));
gpsNavMessage.setSvHealth(RtcmDataField.DF102.intValue(encodedMessage));
// Set the navigation message
rtcm1019Data.setGpsNavigationMessage(gpsNavMessage);
// L2 P data flag and fit interval
rtcm1019Data.setGpsL2PDataFlag(RtcmDataField.DF103.booleanValue(encodedMessage));
rtcm1019Data.setGpsFitInterval(RtcmDataField.DF137.intValue(encodedMessage));
// Return the parsed message
return new Rtcm1019(1019, rtcm1019Data);
}
},
/** Null message. */
NULL_MESSAGE("9999") {
......
/* Copyright 2002-2021 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.gnss.metric.messages.rtcm;
import java.util.ArrayList;
import org.hipparchus.util.FastMath;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.orekit.Utils;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.gnss.SatelliteSystem;
import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1019;
import org.orekit.gnss.metric.messages.rtcm.ephemeris.Rtcm1019Data;
import org.orekit.gnss.metric.parser.ByteArrayEncodedMessages;
import org.orekit.gnss.metric.parser.EncodedMessage;
import org.orekit.gnss.metric.parser.RtcmMessagesParser;
import org.orekit.gnss.navigation.GPSNavigationMessage;
import org.orekit.propagation.analytical.gnss.GPSPropagator;
import org.orekit.time.GNSSDate;
public class Rtcm1019Test {
private double eps = 1.0e-15;
@Before
public void setUp() {
Utils.setDataRoot("gnss");
}
@Test
public void testParseMessage() {
final String m = "001111111011" + // Message number: 1019
"001100" + // Satellite ID
"1111111011" + // Week Number
"0001" + // SV Accuracy
"11" + // GPS CODE ON L2
"01011101111101" + // IDOT
"10000100" + // IODE
"0000111101101111" + // toc
"01111111" + // af2
"0000101011111101" + // af1
"0100101011111101111111" + // af0
"1010110111" + // IODC
"0000000000000000" + // Crs
"0111111011001111" + // DELTA n
"00000110110011111011100110011011" + // M0
"0000000000000000" + // Cuc
"00010011111101111000111000011001" + // ecc
"0000000000000000" + // Cus
"10100001000011000111111111111111" + // A^(1/2)
"1000100011100011" + // toe
"0000000000000000" + // Cic
"00011100011100000111111000111111" + // OMEGA0
"0000000000000000" + // Cis
"00101000001111100011110011110000" + // i0
"0000000000000000" + // Crc
"00001100001111100011110011110000" + // Argument of perigee
"111111111011111111110100" + // OMEGADOT
"00000011" + // tGD
"000000" + // SV Health
"0" + // L2 P data flag
"0"; // Fit Interval
final EncodedMessage message = new ByteArrayEncodedMessages(byteArrayFromBinary(m));
message.start();
ArrayList<Integer> messages = new ArrayList<>();
messages.add(1019);
final Rtcm1019 rtcm1019 = (Rtcm1019) new RtcmMessagesParser(messages).parse(message, false);
final Rtcm1019Data ephemerisData = rtcm1019.getEphemerisData();
final GPSNavigationMessage gpsMessage = ephemerisData.getGpsNavigationMessage();
// Verify propagator initialization
final GPSPropagator propagator = new GPSPropagator.Builder(gpsMessage).build();
Assert.assertNotNull(propagator);
Assert.assertEquals(0.0, gpsMessage.getDate().
durationFrom(new GNSSDate(gpsMessage.getWeek(), 1000.0 * gpsMessage.getTime(), SatelliteSystem.GPS).getDate()), eps);
// Verify message number
Assert.assertEquals(1019, rtcm1019.getTypeCode());
Assert.assertEquals(1, rtcm1019.getData().size());
// Verify navigation message
Assert.assertEquals(12, gpsMessage.getPRN());
Assert.assertEquals(1019, gpsMessage.getWeek());
Assert.assertEquals(2.1475894557210572E-9, gpsMessage.getIDot(), eps);
Assert.assertEquals(132, gpsMessage.getIODE(), eps);
Assert.assertEquals(3.524958E-15, gpsMessage.getAf2(), eps);
Assert.assertEquals(3.1980107E-10, gpsMessage.getAf1(), eps);
Assert.assertEquals(5.721445195376873E-4, gpsMessage.getAf0(), eps);
Assert.assertEquals(695, gpsMessage.getIODC());
Assert.assertEquals(0.0, gpsMessage.getCrs(), eps);
Assert.assertEquals(1.4587497595315308E-4, gpsMessage.getMeanMotion(), eps);
Assert.assertEquals(0.16717753824407455, gpsMessage.getM0(), eps);
Assert.assertEquals(0.0, gpsMessage.getCuc(), eps);
Assert.assertEquals(0.0389980711042881, gpsMessage.getE(), eps);
Assert.assertEquals(0.0, gpsMessage.getCus(), eps);
Assert.assertEquals(5153.5625, FastMath.sqrt(gpsMessage.getSma()), eps);
Assert.assertEquals(560688.0, gpsMessage.getTime(), eps);
Assert.assertEquals(0.0, gpsMessage.getCic(), eps);
Assert.assertEquals(0.0, gpsMessage.getCis(), eps);
Assert.assertEquals(0.9877147247285952, gpsMessage.getI0(), eps);
Assert.assertEquals(0.0, gpsMessage.getCrc(), eps);
Assert.assertEquals(0.30049130834913723, gpsMessage.getPa(), eps);
Assert.assertEquals(-5.855958209879004E-9, gpsMessage.getOmegaDot(), eps);
Assert.assertEquals(0.6980085400002902, gpsMessage.getOmega0(), eps);
Assert.assertEquals(1.3969839E-9, gpsMessage.getTGD(), eps);
Assert.assertEquals(0.0, gpsMessage.getSvHealth(), eps);
// Verify other data
Assert.assertEquals(12, ephemerisData.getSatelliteID());
Assert.assertEquals(63216, ephemerisData.getGpsToc(), eps);
Assert.assertEquals(3, ephemerisData.getGpsCodeOnL2());
Assert.assertEquals(0, ephemerisData.getGpsFitInterval());
Assert.assertTrue(ephemerisData.getGpsL2PDataFlag());
Assert.assertEquals(ephemerisData.getAccuracyProvider().getAccuracy(), gpsMessage.getSvAccuracy(), eps);
}
@Test
public void testNullMessage() {
final String m = "001111111011" + // Message number: 1019
"001100" + // Satellite ID
"1111111011" + // Week Number
"0001" + // SV Accuracy
"11" + // GPS CODE ON L2
"01011101111101" + // IDOT
"10000100" + // IODE
"0000111101101111" + // toc
"01111111" + // af2
"0000101011111101" + // af1
"0100101011111101111111" + // af0
"1010110111" + // IODC
"0000000000000000" + // Crs
"0111111011001111" + // DELTA n
"00000110110011111011100110011011" + // M0
"0000000000000000" + // Cuc
"00010011111101111000111000011001" + // ecc
"0000000000000000" + // Cus
"10100001000011000111111111111111" + // A^(1/2)
"1000100011100011" + // toe
"0000000000000000" + // Cic
"00011100011100000111111000111111" + // OMEGA0
"0000000000000000" + // Cis
"00101000001111100011110011110000" + // i0
"0000000000000000" + // Crc
"00001100001111100011110011110000" + // Argument of perigee
"111111111011111111110100" + // OMEGADOT
"00000011" + // tGD
"000000" + // SV Health
"0" + // L2 P data flag
"0"; // Fit Interval
final EncodedMessage message = new ByteArrayEncodedMessages(byteArrayFromBinary(m));
message.start();
ArrayList<Integer> messages = new ArrayList<>();
messages.add(9999999);
final Rtcm1019 rtcm1019 = (Rtcm1019) new RtcmMessagesParser(messages).parse(message, false);
Assert.assertNull(rtcm1019);
}
@Test
public void testEmptyMessage() {
try {
final byte[] array = new byte[0];
final EncodedMessage emptyMessage = new ByteArrayEncodedMessages(array);
new RtcmMessagesParser(new ArrayList<Integer>()).parse(emptyMessage, false);
Assert.fail("an exception should have been thrown");
} catch (OrekitException oe) {
Assert.assertEquals(OrekitMessages.END_OF_ENCODED_MESSAGE, oe.getSpecifier());
}
}
private byte[] byteArrayFromBinary(String radix2Value) {
final byte[] array = new byte[radix2Value.length() / 8];
for (int i = 0; i < array.length; ++i) {
for (int j = 0; j < 8; ++j) {
if (radix2Value.charAt(8 * i + j) != '0') {
array[i] |= 0x1 << (7 - j);
}
}
}
return array;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment