FieldTurnSpan.java
/* Copyright 2002-2024 CS GROUP
* Licensed to CS GROUP (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.gnss.attitude;
import org.hipparchus.CalculusFieldElement;
import org.hipparchus.util.FastMath;
import org.orekit.time.AbsoluteDate;
import org.orekit.time.FieldAbsoluteDate;
import org.orekit.time.TimeStamped;
/**
* Holder for time span of noon/night turns.
*
* <p>
* The boundaries estimated are updated as
* new points close to the span are evaluated.
* </p>
*
* @author Luc Maisonobe
* @since 9.3
*/
class FieldTurnSpan<T extends CalculusFieldElement<T>> implements TimeStamped {
/** Margin in seconds after turn end. */
private final double endMargin;
/** Best estimate of the start of the turn. */
private FieldAbsoluteDate<T> start;
/** Best estimate of the start of the turn. */
private AbsoluteDate startDouble;
/** Best estimate of the end of the turn, excluding margin. */
private FieldAbsoluteDate<T> end;
/** Best estimate of the end of the turn, including margin. */
private AbsoluteDate endPlusMarginDouble;
/** Time between start and its estimation date. */
private double startProjection;
/** Time between end and its estimation date. */
private double endProjection;
/** Turn duration. */
private T duration;
/** Simple constructor.
* @param start estimate of the start of the turn
* @param end estimate of the end of the turn, excluding margin
* @param estimationDate date at which turn boundaries have been estimated
* @param endMargin margin in seconds after turn end
*/
FieldTurnSpan(final FieldAbsoluteDate<T> start, final FieldAbsoluteDate<T> end,
final AbsoluteDate estimationDate, final double endMargin) {
final FieldAbsoluteDate<T> endPlusMargin = end.shiftedBy(endMargin);
this.endMargin = endMargin;
this.start = start;
this.startDouble = start.toAbsoluteDate();
this.end = end;
this.endPlusMarginDouble = endPlusMargin.toAbsoluteDate();
this.startProjection = FastMath.abs(start.durationFrom(estimationDate).getReal());
this.endProjection = FastMath.abs(endPlusMargin.durationFrom(estimationDate).getReal());
this.duration = end.durationFrom(start);
}
/** Update the estimate of the turn start.
* <p>
* Start boundary is updated only if it is estimated
* from a time closer to the boundary than the previous estimate.
* </p>
* @param newStart new estimate of the start of the turn
* @param estimationDate date at which turn start has been estimated
*/
public void updateStart(final FieldAbsoluteDate<T> newStart, final AbsoluteDate estimationDate) {
// update the start date if this estimate is closer than the previous one
final double newStartProjection = FastMath.abs(newStart.toAbsoluteDate().durationFrom(estimationDate));
if (newStartProjection <= startProjection) {
this.start = newStart;
this.startDouble = newStart.toAbsoluteDate();
this.startProjection = newStartProjection;
this.duration = end.durationFrom(start);
}
}
/** Update the estimate of the turn end.
* <p>
* End boundary is updated only if it is estimated
* from a time closer to the boundary than the previous estimate.
* </p>
* @param newEnd new estimate of the end of the turn
* @param estimationDate date at which turn end has been estimated
*/
public void updateEnd(final FieldAbsoluteDate<T> newEnd, final AbsoluteDate estimationDate) {
// update the end date if this estimate is closer than the previous one
final double newEndProjection = FastMath.abs(newEnd.toAbsoluteDate().durationFrom(estimationDate));
if (newEndProjection <= endProjection) {
final FieldAbsoluteDate<T> endPlusMargin = newEnd.shiftedBy(endMargin);
this.end = newEnd;
this.endPlusMarginDouble = endPlusMargin.toAbsoluteDate();
this.endProjection = newEndProjection;
this.duration = end.durationFrom(start);
}
}
/** {@inheritDoc} */
@Override
public AbsoluteDate getDate() {
return endPlusMarginDouble;
}
/** Get turn duration.
* @return turn duration
*/
public T getTurnDuration() {
return duration;
}
/** Get turn start date.
* @return turn start date
*/
public FieldAbsoluteDate<T> getTurnStartDate() {
return start;
}
/** Get turn end date (without margin).
* @return turn end date (without margin)
*/
public FieldAbsoluteDate<T> getTurnEndDate() {
return end;
}
/** Check if a date is within range.
* @param date date to check
* @return true if date is within range extended by end margin,
* both start and end + margin dates are included
*/
public boolean inTurnTimeRange(final AbsoluteDate date) {
return date.durationFrom(startDouble) >= 0 && date.durationFrom(endPlusMarginDouble) <= 0;
}
}