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