1 /* Copyright 2002-2025 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.gnss.attitude;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.util.FastMath;
21 import org.orekit.time.AbsoluteDate;
22 import org.orekit.time.FieldAbsoluteDate;
23 import org.orekit.time.TimeStamped;
24
25 /**
26 * Holder for time span of noon/night turns.
27 *
28 * <p>
29 * The boundaries estimated are updated as
30 * new points close to the span are evaluated.
31 * </p>
32 *
33 * @author Luc Maisonobe
34 * @since 9.3
35 */
36 class FieldTurnSpan<T extends CalculusFieldElement<T>> implements TimeStamped {
37
38 /** Margin in seconds after turn end. */
39 private final double endMargin;
40
41 /** Best estimate of the start of the turn. */
42 private FieldAbsoluteDate<T> start;
43
44 /** Best estimate of the start of the turn. */
45 private AbsoluteDate startDouble;
46
47 /** Best estimate of the end of the turn, excluding margin. */
48 private FieldAbsoluteDate<T> end;
49
50 /** Best estimate of the end of the turn, including margin. */
51 private AbsoluteDate endPlusMarginDouble;
52
53 /** Time between start and its estimation date. */
54 private double startProjection;
55
56 /** Time between end and its estimation date. */
57 private double endProjection;
58
59 /** Turn duration. */
60 private T duration;
61
62 /** Simple constructor.
63 * @param start estimate of the start of the turn
64 * @param end estimate of the end of the turn, excluding margin
65 * @param estimationDate date at which turn boundaries have been estimated
66 * @param endMargin margin in seconds after turn end
67 */
68 FieldTurnSpan(final FieldAbsoluteDate<T> start, final FieldAbsoluteDate<T> end,
69 final AbsoluteDate estimationDate, final double endMargin) {
70 final FieldAbsoluteDate<T> endPlusMargin = end.shiftedBy(endMargin);
71 this.endMargin = endMargin;
72 this.start = start;
73 this.startDouble = start.toAbsoluteDate();
74 this.end = end;
75 this.endPlusMarginDouble = endPlusMargin.toAbsoluteDate();
76 this.startProjection = FastMath.abs(start.durationFrom(estimationDate).getReal());
77 this.endProjection = FastMath.abs(endPlusMargin.durationFrom(estimationDate).getReal());
78 this.duration = end.durationFrom(start);
79 }
80
81 /** Update the estimate of the turn start.
82 * <p>
83 * Start boundary is updated only if it is estimated
84 * from a time closer to the boundary than the previous estimate.
85 * </p>
86 * @param newStart new estimate of the start of the turn
87 * @param estimationDate date at which turn start has been estimated
88 */
89 public void updateStart(final FieldAbsoluteDate<T> newStart, final AbsoluteDate estimationDate) {
90
91 // update the start date if this estimate is closer than the previous one
92 final double newStartProjection = FastMath.abs(newStart.toAbsoluteDate().durationFrom(estimationDate));
93 if (newStartProjection <= startProjection) {
94 this.start = newStart;
95 this.startDouble = newStart.toAbsoluteDate();
96 this.startProjection = newStartProjection;
97 this.duration = end.durationFrom(start);
98 }
99
100 }
101
102 /** Update the estimate of the turn end.
103 * <p>
104 * End boundary is updated only if it is estimated
105 * from a time closer to the boundary than the previous estimate.
106 * </p>
107 * @param newEnd new estimate of the end of the turn
108 * @param estimationDate date at which turn end has been estimated
109 */
110 public void updateEnd(final FieldAbsoluteDate<T> newEnd, final AbsoluteDate estimationDate) {
111
112 // update the end date if this estimate is closer than the previous one
113 final double newEndProjection = FastMath.abs(newEnd.toAbsoluteDate().durationFrom(estimationDate));
114 if (newEndProjection <= endProjection) {
115 final FieldAbsoluteDate<T> endPlusMargin = newEnd.shiftedBy(endMargin);
116 this.end = newEnd;
117 this.endPlusMarginDouble = endPlusMargin.toAbsoluteDate();
118 this.endProjection = newEndProjection;
119 this.duration = end.durationFrom(start);
120 }
121
122 }
123
124 /** {@inheritDoc} */
125 @Override
126 public AbsoluteDate getDate() {
127 return endPlusMarginDouble;
128 }
129
130 /** Get turn duration.
131 * @return turn duration
132 */
133 public T getTurnDuration() {
134 return duration;
135 }
136
137 /** Get turn start date.
138 * @return turn start date
139 */
140 public FieldAbsoluteDate<T> getTurnStartDate() {
141 return start;
142 }
143
144 /** Get turn end date (without margin).
145 * @return turn end date (without margin)
146 */
147 public FieldAbsoluteDate<T> getTurnEndDate() {
148 return end;
149 }
150
151 /** Check if a date is within range.
152 * @param date date to check
153 * @return true if date is within range extended by end margin,
154 * both start and end + margin dates are included
155 */
156 public boolean inTurnTimeRange(final AbsoluteDate date) {
157 return date.durationFrom(startDouble) >= 0 && date.durationFrom(endPlusMarginDouble) <= 0;
158 }
159
160 }