1   /* Copyright 2002-2026 CS GROUP
2    * Licensed to CS GROUP (CS) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * CS licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *   http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.orekit.propagation.analytical.gnss.data;
18  
19  import org.hipparchus.CalculusFieldElement;
20  import org.orekit.frames.Frame;
21  import org.orekit.orbits.FieldKeplerianOrbit;
22  import org.orekit.orbits.KeplerianOrbit;
23  import org.orekit.time.FieldGNSSDate;
24  import org.orekit.time.GNSSDate;
25  import org.orekit.time.TimeScales;
26  
27  import java.util.function.DoubleFunction;
28  
29  /**
30   * Container for data contained in a BeiDou navigation message.
31   * @author Bryan Cazabonne
32   * @since 11.0
33   */
34  public class BeidouLegacyNavigationMessage extends AbstractNavigationMessage<BeidouLegacyNavigationMessage> {
35  
36      /** Identifier for message type. */
37      public static final String D1 = "D1";
38  
39      /** Identifier for message type. */
40      public static final String D2 = "D2";
41  
42      /** Indicator for D2 messages.
43       * @since 14.0
44       */
45      private final boolean d2;
46  
47      /** Age of Data, Ephemeris. */
48      private final int aode;
49  
50      /** Age of Data, Clock. */
51      private final int aodc;
52  
53      /** Health identifier.
54       * @since 14.0
55       */
56      private final int satH1;
57  
58      /** B1/B3 Group Delay Differential (s). */
59      private final double tgd1;
60  
61      /** B2/B3 Group Delay Differential (s). */
62      private final double tgd2;
63  
64      /** The user SV accuracy (m). */
65      private final double svAccuracy;
66  
67      /** Constructor.
68       * @param d2               indicator for D2 messages
69       * @param timeScales       known time scales
70       * @param type             message type
71       * @param prn              PRN number of the satellite
72       * @param toe              time of ephemeris (<em>must</em> be consistent with {@code orbit})
73       * @param orbit            Keplerian orbit in Earth-frozen frame
74       * @param aDot             change rate in semi-major axis (m/s)
75       * @param deltaN0          delta of satellite mean motion
76       * @param deltaN0Dot       change rate in Δn₀
77       * @param iDot             inclination rate (rad/s)
78       * @param omegaDot         rate of right ascension (rad/s)
79       * @param cuc              amplitude of the cosine harmonic correction term to the argument of latitude
80       * @param cus              amplitude of the sine harmonic correction term to the argument of latitude
81       * @param crc              amplitude of the cosine harmonic correction term to the orbit radius
82       * @param crs              amplitude of the sine harmonic correction term to the orbit radius
83       * @param cic              amplitude of the cosine harmonic correction term to the inclination
84       * @param cis              amplitude of the sine harmonic correction term to the inclination
85       * @param af0              zero-th order clock correction (s)
86       * @param af1              first order clock correction (s/s)
87       * @param af2              second order clock correction (s/s²)
88       * @param tgd              group delay differential TGD for L1-L2 correction
89       * @param toc              time of clock
90       * @param transmissionTime transmission time
91       * @param aode             age of data, ephemeris
92       * @param aodc             age of data, clock
93       * @param satH1            health identifier
94       * @param tgd1             B1/B3 Group Delay Differential (s)
95       * @param tgd2             B2/B3 Group Delay Differential (s)
96       * @param svAccuracy       user SV accuracy (m)
97       */
98      public BeidouLegacyNavigationMessage(final boolean d2,
99                                           final TimeScales timeScales, final String type,
100                                          final int prn, final GNSSDate toe, final KeplerianOrbit orbit,
101                                          final double aDot, final double deltaN0, final double deltaN0Dot,
102                                          final double iDot, final double omegaDot,
103                                          final double cuc, final double cus,
104                                          final double crc, final double crs,
105                                          final double cic, final double cis,
106                                          final double af0, final double af1, final double af2,
107                                          final double tgd, final GNSSDate toc, final GNSSDate  transmissionTime,
108                                          final int aode, final int aodc, final int satH1,
109                                          final double tgd1, final double tgd2, final double svAccuracy) {
110         super(GNSSConstants.BEIDOU_AV, GNSSConstants.BEIDOU_WEEK_NB,
111               timeScales, type, prn, toe, orbit,
112               aDot, deltaN0, deltaN0Dot, iDot, omegaDot, cuc, cus, crc, crs, cic, cis,
113               af0, af1, af2, tgd, toc, transmissionTime);
114         this.d2         = d2;
115         this.aode       = aode;
116         this.aodc       = aodc;
117         this.satH1      = satH1;
118         this.tgd1       = tgd1;
119         this.tgd2       = tgd2;
120         this.svAccuracy = svAccuracy;
121     }
122 
123     /** Constructor from field instance.
124      * @param <T> type of the field elements
125      * @param original regular field instance
126      */
127     public <T extends CalculusFieldElement<T>> BeidouLegacyNavigationMessage(final FieldBeidouLegacyNavigationMessage<T> original) {
128         super(original);
129         d2         = original.isD2();
130         aode       = original.getAODE();
131         aodc       = original.getAODC();
132         satH1      = original.getSatH1();
133         tgd1       = original.getTGD1().getReal();
134         tgd2       = original.getTGD2().getReal();
135         svAccuracy = original.getSvAccuracy().getReal();
136     }
137 
138     /** {@inheritDoc} */
139     @Override
140     public <T extends CalculusFieldElement<T>>
141         FieldBeidouLegacyNavigationMessage<T> toField(final FieldKeplerianOrbit<T> orbit,
142                                                       final T[] nonKeplerian,
143                                                       final DoubleFunction<T> converter) {
144         return new FieldBeidouLegacyNavigationMessage<>(isD2(),
145                                                         getAngularVelocity(), getWeeksInCycle(), getTimeScales(),
146                                                         getType(), getPrn(),
147                                                         new FieldGNSSDate<>(orbit.getDate().getField(), getTimeOfEphemeris()),
148                                                         orbit, nonKeplerian,
149                                                         converter.apply(getTgd()),
150                                                         new FieldGNSSDate<>(orbit.getDate().getField(), getTimeOfClock()),
151                                                         new FieldGNSSDate<>(orbit.getDate().getField(), getTransmissionTime()),
152                                                         getAODE(), getAODC(), getSatH1(),
153                                                         converter.apply( getTGD1()),
154                                                         converter.apply(getTGD2()),
155                                                         converter.apply(getSvAccuracy()));
156     }
157 
158     /**
159      * Check if message is a D2 message.
160      * @return true if message is a D2 message
161      * @since 14.0
162      */
163     public boolean isD2() {
164         return d2;
165     }
166 
167     /**
168      * Getter for the Age Of Data Clock (AODC).
169      * @return the Age Of Data Clock (AODC)
170      */
171     public int getAODC() {
172         return aodc;
173     }
174 
175     /**
176      * Getter for the Age Of Data Ephemeris (AODE).
177      * @return the Age Of Data Ephemeris (AODE)
178      */
179     public int getAODE() {
180         return aode;
181     }
182 
183     /**
184      * Getter for the estimated group delay differential TGD1 for B1I signal.
185      * @return the estimated group delay differential TGD1 for B1I signal (s)
186      */
187     public double getTGD1() {
188         return tgd1;
189     }
190 
191     /**
192      * Getter for the estimated group delay differential TGD for B2I signal.
193      * @return the estimated group delay differential TGD2 for B2I signal (s)
194      */
195     public double getTGD2() {
196         return tgd2;
197     }
198 
199     /**
200      * Getter for the user SV accuray (meters).
201      * @return the user SV accuracy
202      */
203     public double getSvAccuracy() {
204         return svAccuracy;
205     }
206 
207     /** Get the health identifier.
208      * @return health identifier
209      * @since 14.0
210      */
211     public int getSatH1() {
212         return satH1;
213     }
214 
215     /** {@inheritDoc} */
216     @Override
217     public BeidouLegacyNavigationMessageFactory baseFactory(final Frame inertial, final Frame bodyFixed) {
218         return new BeidouLegacyNavigationMessageFactory(getTimeScales(), getTimeOfEphemeris().getSystem(), getType(),
219                                                         inertial, bodyFixed, isD2());
220     }
221 
222 }