1   /* Copyright 2022-2026 Luc Maisonobe
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 civilian navigation message.
31   * @author Luc Maisonobe
32   * @since 12.0
33   */
34  public class BeidouCivilianNavigationMessage extends AbstractNavigationMessage<BeidouCivilianNavigationMessage> {
35  
36      /** Beidou civilian message type.
37       * @since 14.0
38       */
39      private final BeidouCivilianType beidouType;
40  
41      /** Issue of Data, Ephemeris. */
42      private final int iode;
43  
44      /** Issue of Data, Clock. */
45      private final int iodc;
46  
47      /** Inter Signal Delay for B1 CD. */
48      private final double iscB1CD;
49  
50      /** Inter Signal Delay for B1 CP. */
51      private final double iscB1CP;
52  
53      /** Inter Signal Delay for B2 AD. */
54      private final double iscB2AD;
55  
56      /** Signal In Space Accuracy Index (along track and across track). */
57      private final int sisaiOe;
58  
59      /** Signal In Space Accuracy Index (radial and clock). */
60      private final int sisaiOcb;
61  
62      /** Signal In Space Accuracy Index (clock drift accuracy). */
63      private final int sisaiOc1;
64  
65      /** Signal In Space Accuracy Index (clock drift rate accuracy). */
66      private final int sisaiOc2;
67  
68      /** Signal In Space Monitoring Accuracy Index. */
69      private final int sismai;
70  
71      /** Health. */
72      private final int health;
73  
74      /** Integrity flags. */
75      private final int integrityFlags;
76  
77      /** B1/B3 Group Delay Differential (s). */
78      private final double tgdB1Cp;
79  
80      /** B2 AP Group Delay Differential (s). */
81      private final double tgdB2ap;
82  
83      /** B2B_i / B3I Group Delay Differential (s). */
84      private final double tgdB2bI;
85  
86      /** Satellite type. */
87      private final BeidouSatelliteType satelliteType;
88  
89      /**
90       * Constructor.
91       * @param beidouType       Beidou civilian message type
92       * @param timeScales       known time scales
93       * @param prn              PRN number of the satellite
94       * @param toe              time of ephemeris (<em>must</em> be consistent with {@code orbit})
95       * @param orbit            Keplerian orbit in Earth-frozen frame
96       * @param aDot             change rate in semi-major axis (m/s)
97       * @param deltaN0          delta of satellite mean motion
98       * @param deltaN0Dot       change rate in Δn₀
99       * @param iDot             inclination rate (rad/s)
100      * @param omegaDot         rate of right ascension (rad/s)
101      * @param cuc              amplitude of the cosine harmonic correction term to the argument of latitude
102      * @param cus              amplitude of the sine harmonic correction term to the argument of latitude
103      * @param crc              amplitude of the cosine harmonic correction term to the orbit radius
104      * @param crs              amplitude of the sine harmonic correction term to the orbit radius
105      * @param cic              amplitude of the cosine harmonic correction term to the inclination
106      * @param cis              amplitude of the sine harmonic correction term to the inclination
107      * @param af0              zero-th order clock correction (s)
108      * @param af1              first order clock correction (s/s)
109      * @param af2              second order clock correction (s/s²)
110      * @param tgd              group delay differential TGD for L1-L2 correction
111      * @param toc              time of clock
112      * @param transmissionTime transmission time
113      * @param iode             issue of data, ephemeris
114      * @param iodc             issue of data, clock
115      * @param iscB1CD          inter signal delay for B1 CD
116      * @param iscB1CP          inter signal delay for B1 CP
117      * @param iscB2AD          inter signal delay for B2 AD
118      * @param sisaiOe          signal in space accuracy index (along track and across track)
119      * @param sisaiOcb         signal in space accuracy index (radial and clock)
120      * @param sisaiOc1         signal in space accuracy index (clock drift accuracy)
121      * @param sisaiOc2         signal in space accuracy index (clock drift rate accuracy)
122      * @param sismai           signal in space monitoring accuracy index
123      * @param health           health
124      * @param integrityFlags   integrity flags
125      * @param tgdB1Cp          B1/B3 Group Delay Differential (s)
126      * @param tgdB2ap          B2 AP Group Delay Differential (s)
127      * @param tgdB2bI          B2B_i / B3I Group Delay Differential (s)
128      * @param satelliteType    satellite type
129      */
130     public BeidouCivilianNavigationMessage(final BeidouCivilianType beidouType,
131                                            final TimeScales timeScales,  final int prn,
132                                            final GNSSDate toe, final KeplerianOrbit orbit,
133                                            final double aDot, final double deltaN0, final double deltaN0Dot,
134                                            final double iDot, final double omegaDot,
135                                            final double cuc, final double cus,
136                                            final double crc, final double crs,
137                                            final double cic, final double cis,
138                                            final double af0, final double af1, final double af2,
139                                            final double tgd, final GNSSDate toc, final GNSSDate  transmissionTime,
140                                            final int iode, final int iodc,
141                                            final double iscB1CD, final double iscB1CP, final double iscB2AD,
142                                            final int sisaiOe, final int sisaiOcb,
143                                            final int sisaiOc1, final int sisaiOc2,
144                                            final int sismai, final int health, final int integrityFlags,
145                                            final double tgdB1Cp, final double tgdB2ap, final double tgdB2bI,
146                                            final BeidouSatelliteType satelliteType) {
147         super(GNSSConstants.BEIDOU_AV, GNSSConstants.BEIDOU_WEEK_NB,
148               timeScales, beidouType.name(), prn, toe, orbit,
149               aDot, deltaN0, deltaN0Dot, iDot, omegaDot, cuc, cus, crc, crs, cic, cis,
150               af0, af1, af2, tgd, toc, transmissionTime);
151         this.beidouType = beidouType;
152         this.iode           = iode;
153         this.iodc           = iodc;
154         this.iscB1CD        = iscB1CD;
155         this.iscB1CP        = iscB1CP;
156         this.iscB2AD        = iscB2AD;
157         this.sisaiOe        = sisaiOe;
158         this.sisaiOcb       = sisaiOcb;
159         this.sisaiOc1       = sisaiOc1;
160         this.sisaiOc2       = sisaiOc2;
161         this.sismai         = sismai;
162         this.health         = health;
163         this.integrityFlags = integrityFlags;
164         this.tgdB1Cp        = tgdB1Cp;
165         this.tgdB2ap        = tgdB2ap;
166         this.tgdB2bI        = tgdB2bI;
167         this.satelliteType  = satelliteType;
168     }
169 
170     /** Constructor from field instance.
171      * @param <T> type of the field elements
172      * @param original regular field instance
173      */
174     public <T extends CalculusFieldElement<T>> BeidouCivilianNavigationMessage(final FieldBeidouCivilianNavigationMessage<T> original) {
175         super(original);
176         this.beidouType     = original.getBeidouType();
177         this.iode           = original.getIODE();
178         this.iodc           = original.getIODC();
179         this.iscB1CD        = original.getIscB1CD().getReal();
180         this.iscB1CP        = original.getIscB1CP().getReal();
181         this.iscB2AD        = original.getIscB2AD().getReal();
182         this.sisaiOe        = original.getSisaiOe();
183         this.sisaiOcb       = original.getSisaiOcb();
184         this.sisaiOc1       = original.getSisaiOc1();
185         this.sisaiOc2       = original.getSisaiOc2();
186         this.sismai         = original.getSismai();
187         this.health         = original.getHealth();
188         this.integrityFlags = original.getIntegrityFlags();
189         this.tgdB1Cp        = original.getTgdB1Cp().getReal();
190         this.tgdB2ap        = original.getTgdB2ap().getReal();
191         this.tgdB2bI        = original.getTgdB2bI().getReal();
192         this.satelliteType  = original.getSatelliteType();
193 
194     }
195 
196     /** Get the Beidou civilian message type.
197      * @return Beidou civilian message type
198      * @since 14.0
199      */
200     public BeidouCivilianType getBeidouType() {
201         return beidouType;
202     }
203 
204     /** {@inheritDoc} */
205     @Override
206     public boolean isCivilianMessage() {
207         return true;
208     }
209 
210     /** {@inheritDoc} */
211     @Override
212     public <T extends CalculusFieldElement<T>>
213         FieldBeidouCivilianNavigationMessage<T> toField(final FieldKeplerianOrbit<T> orbit,
214                                                         final T[] nonKeplerian,
215                                                         final DoubleFunction<T> converter) {
216         return new FieldBeidouCivilianNavigationMessage<>(getBeidouType(),
217                                                           getAngularVelocity(), getWeeksInCycle(), getTimeScales(),
218                                                           getType(), getPrn(),
219                                                           new FieldGNSSDate<>(orbit.getDate().getField(), getTimeOfEphemeris()),
220                                                           orbit, nonKeplerian,
221                                                           converter.apply(getTgd()),
222                                                           new FieldGNSSDate<>(orbit.getDate().getField(), getTimeOfClock()),
223                                                           new FieldGNSSDate<>(orbit.getDate().getField(), getTransmissionTime()),
224                                                           getIODE(), getIODC(),
225                                                           converter.apply(getIscB1CD()),
226                                                           converter.apply(getIscB1CP()),
227                                                           converter.apply(getIscB2AD()),
228                                                           getSisaiOe(), getSisaiOcb(),
229                                                           getSisaiOc1(), getSisaiOc2(),
230                                                           getSismai(), getHealth(), getIntegrityFlags(),
231                                                           converter.apply(getTgdB1Cp()),
232                                                           converter.apply(getTgdB2ap()),
233                                                           converter.apply(getTgdB2bI()),
234                                                           getSatelliteType());
235     }
236 
237     /** Get the Issue Of Data Ephemeris (IODE).
238      * @return the Issue Of Data Ephemeris (IODE)
239      */
240     public int getIODE() {
241         return iode;
242     }
243 
244     /** Get the Issue Of Data Clock (IODC).
245      * @return the Issue Of Data Clock (IODC)
246      */
247     public int getIODC() {
248         return iodc;
249     }
250 
251     /** Get inter Signal Delay for B1 CD.
252      * @return inter signal delay
253      */
254     public double getIscB1CD() {
255         return iscB1CD;
256     }
257 
258     /** Get inter Signal Delay for B2 AD.
259      * @return inter signal delay
260      */
261     public double getIscB2AD() {
262         return iscB2AD;
263     }
264 
265     /** Get inter Signal Delay for B1 CP.
266      * @return inter signal delay
267      */
268     public double getIscB1CP() {
269         return iscB1CP;
270     }
271 
272     /** Get Signal In Space Accuracy Index (along track and across track).
273      * @return Signal In Space Accuracy Index (along track and across track)
274      */
275     public int getSisaiOe() {
276         return sisaiOe;
277     }
278 
279     /** Get Signal In Space Accuracy Index (radial and clock).
280      * @return Signal In Space Accuracy Index (radial and clock)
281      */
282     public int getSisaiOcb() {
283         return sisaiOcb;
284     }
285 
286     /** Get Signal In Space Accuracy Index (clock drift accuracy).
287      * @return Signal In Space Accuracy Index (clock drift accuracy)
288      */
289     public int getSisaiOc1() {
290         return sisaiOc1;
291     }
292 
293     /** Get Signal In Space Accuracy Index (clock drift rate accuracy).
294      * @return Signal In Space Accuracy Index (clock drift rate accuracy)
295      */
296     public int getSisaiOc2() {
297         return sisaiOc2;
298     }
299 
300     /** Get Signal In Space Monitoring Accuracy Index.
301      * @return Signal In Space Monitoring Accuracy Index
302      */
303     public int getSismai() {
304         return sismai;
305     }
306 
307     /** Get health.
308      * @return health
309      */
310     public int getHealth() {
311         return health;
312     }
313 
314     /** Get B1C integrity flags.
315      * @return B1C integrity flags
316      */
317     public int getIntegrityFlags() {
318         return integrityFlags;
319     }
320 
321     /** Get B1/B3 Group Delay Differential (s).
322      * @return B1/B3 Group Delay Differential (s)
323      */
324     public double getTgdB1Cp() {
325         return tgdB1Cp;
326     }
327 
328     /** Get B2 AP Group Delay Differential (s).
329      * @return B2 AP Group Delay Differential (s)
330      */
331     public double getTgdB2ap() {
332         return tgdB2ap;
333     }
334 
335     /** Get B2B_i / B3I Group Delay Differential (s).
336      * @return B2B_i / B3I Group Delay Differential (s)
337      */
338     public double getTgdB2bI() {
339         return tgdB2bI;
340     }
341 
342     /** Get satellite type.
343      * @return satellite type
344      */
345     public BeidouSatelliteType getSatelliteType() {
346         return satelliteType;
347     }
348 
349     /** {@inheritDoc} */
350     @Override
351     public BeidouCivilianNavigationMessageFactory baseFactory(final Frame inertial, final Frame bodyFixed) {
352         return new BeidouCivilianNavigationMessageFactory(getTimeScales(), getTimeOfEphemeris().getSystem(), getType(),
353                                                           inertial, bodyFixed, getBeidouType(), getSatelliteType());
354     }
355 
356 }