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