1   /* Copyright 2022-2026 Thales Alenia Space
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.time.clocks;
18  
19  import org.orekit.errors.OrekitException;
20  import org.orekit.errors.OrekitMessages;
21  import org.orekit.time.AbsoluteDate;
22  import org.orekit.time.TimeStamped;
23  
24  /**
25   * Container for time stamped clock offset.
26   * <p>
27   * Instances of this class are immutable
28   * </p>
29   *
30   * @author Luc Maisonobe
31   * @since 12.1
32   */
33  public class ClockOffset implements TimeStamped {
34  
35      /** Date. */
36      private final AbsoluteDate date;
37  
38      /** Clock bias. */
39      private final double bias;
40  
41      /** Clock rate. */
42      private final double rate;
43  
44      /** Clock acceleration. */
45      private final double acceleration;
46  
47      /**
48       * Simple constructor.
49       *
50       * @param date date
51       * @param bias clock bias
52       * @param rate clock rate (can be set to {@code Double.NaN} if unknown)
53       * @param acceleration clock acceleration (can be set to {@code Double.NaN}
54       *        if unknown)
55       */
56      public ClockOffset(final AbsoluteDate date, final double bias,
57                         final double rate, final double acceleration) {
58          this.date = date;
59          this.bias =         bias;
60          this.rate =         rate;
61          this.acceleration = acceleration;
62      }
63  
64      /**
65       * Simple constructor.
66       *
67       * @param date date
68       * @param terms the clock terms, up to 3 values for bias, drift, and acceleration
69       */
70      public ClockOffset(final AbsoluteDate date, final double[] terms) {
71          this.date = date;
72          if (terms.length >= 1) {
73              this.bias = terms[0];
74          } else {
75              this.bias = 0;
76          }
77          if (terms.length >= 2) {
78              this.rate = terms[1];
79          } else {
80              this.rate = 0;
81          }
82          if (terms.length == 3) {
83              this.acceleration = terms[2];
84          } else {
85              this.acceleration = 0;
86          }
87          if (terms.length > 3) {
88              throw new OrekitException(OrekitMessages.CANNOT_PARSE_DATA);
89          }
90      }
91  
92      /**
93       * Add another offset to the instance.
94       * <p>
95       * The instance is not modified, a new instance is created
96       * </p>
97       *
98       * @param other offset to add (date part will be ignored)
99       * @return instance + other, at instance date
100      * @since 14.0
101      */
102     public ClockOffset add(final ClockOffset other) {
103         return new ClockOffset(date,
104                                bias + other.bias,
105                                rate + other.rate,
106                                acceleration + other.acceleration);
107     }
108 
109     /**
110      * Subtract another offset from the instance.
111      * <p>
112      * The instance is not modified, a new instance is created
113      * </p>
114      *
115      * @param other offset to subtract (date part will be ignored)
116      * @return instance - other, at instance date
117      * @since 14.0
118      */
119     public ClockOffset subtract(final ClockOffset other) {
120         return new ClockOffset(date, bias - other.bias, rate - other.rate,
121                                acceleration - other.acceleration);
122     }
123 
124     /** {@inheritDoc} */
125     @Override
126     public AbsoluteDate getDate() {
127         return date;
128     }
129 
130     /** Get bias.
131      * @return bias
132      * @since 14.0
133      */
134     public double getBias() {
135         return bias;
136     }
137 
138     /** Get rate.
139      * @return rate ({@code Double.NaN} if unknown)
140      */
141     public double getRate() {
142         return rate;
143     }
144 
145     /** Get acceleration.
146      * @return acceleration ({@code Double.NaN} if unknown)
147      */
148     public double getAcceleration() {
149         return acceleration;
150     }
151 
152     /** Get the value of the clock offset at a given time.
153      * @param givenDate the date at which to evaluate the clock offset
154      * @return The value of the clock in seconds from the given date
155      */
156     public double getValue(final AbsoluteDate givenDate) {
157         final double dt = givenDate.durationFrom(date);
158         return dt * ((dt * getAcceleration()) + getRate()) + getBias();
159 
160     }
161 
162 }