1 /* Copyright 2002-2024 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.attitudes;
18
19 import java.util.Collection;
20 import java.util.Map.Entry;
21 import java.util.NavigableMap;
22 import java.util.TreeMap;
23
24 import org.hipparchus.CalculusFieldElement;
25 import org.hipparchus.geometry.euclidean.threed.FieldRotation;
26 import org.hipparchus.geometry.euclidean.threed.Rotation;
27 import org.orekit.errors.OrekitException;
28 import org.orekit.errors.OrekitMessages;
29 import org.orekit.frames.Frame;
30 import org.orekit.time.AbsoluteDate;
31 import org.orekit.time.FieldAbsoluteDate;
32 import org.orekit.utils.FieldPVCoordinatesProvider;
33 import org.orekit.utils.PVCoordinatesProvider;
34
35 /**
36 * A {@link BoundedAttitudeProvider} that covers a larger time span from several constituent
37 * attitude providers that cover shorter time spans.
38 *
39 * @author Bryan Cazabonne
40 * @since 10.3
41 */
42 public class AggregateBoundedAttitudeProvider implements BoundedAttitudeProvider {
43
44 /** Constituent attitude provider. */
45 private final NavigableMap<AbsoluteDate, BoundedAttitudeProvider> providers;
46
47 /**
48 * Constructor.
49 * @param providers attitude providers that provide the backing data for this instance.
50 * There must be at least one attitude provider in the collection.
51 * If there are gaps between the {@link BoundedAttitudeProvider#getMaxDate()}
52 * of one attitude provider and the {@link BoundedAttitudeProvider#getMinDate()}
53 * of the next attitude provider an exception may be thrown by any method of
54 * this class at any time. If there are overlaps between the the {@link
55 * BoundedAttitudeProvider#getMaxDate()} of one attitude provider and the {@link
56 * BoundedAttitudeProvider#getMinDate()} of the next attitude provider then the
57 * attitude provider with the latest {@link BoundedAttitudeProvider#getMinDate()}
58 * is used.
59 */
60 public AggregateBoundedAttitudeProvider(final Collection<? extends BoundedAttitudeProvider> providers) {
61
62 // Check if the collection is empty
63 if (providers.isEmpty()) {
64 throw new OrekitException(OrekitMessages.NOT_ENOUGH_ATTITUDE_PROVIDERS);
65 }
66
67 // Initialize map
68 this.providers = new TreeMap<>();
69
70 // Loop on providers
71 for (final BoundedAttitudeProvider provider : providers) {
72 // Fill collection
73 this.providers.put(provider.getMinDate(), provider);
74 }
75
76 }
77
78 /** {@inheritDoc} */
79 @Override
80 public Attitude getAttitude(final PVCoordinatesProvider pvProv, final AbsoluteDate date,
81 final Frame frame) {
82
83 // Get the attitude provider for the given date
84 final BoundedAttitudeProvider provider = getAttitudeProvider(date);
85
86 // Build attitude
87 return provider.getAttitude(pvProv, date, frame);
88
89 }
90
91 /** {@inheritDoc} */
92 @Override
93 public <T extends CalculusFieldElement<T>> FieldAttitude<T> getAttitude(final FieldPVCoordinatesProvider<T> pvProv,
94 final FieldAbsoluteDate<T> date, final Frame frame) {
95
96 // Get the attitude provider for the given date
97 final BoundedAttitudeProvider provider = getAttitudeProvider(date.toAbsoluteDate());
98
99 // Build attitude
100 return provider.getAttitude(pvProv, date, frame);
101
102 }
103
104 /** {@inheritDoc} */
105 @Override
106 public Rotation getAttitudeRotation(final PVCoordinatesProvider pvProv, final AbsoluteDate date, final Frame frame) {
107 return getAttitudeProvider(date).getAttitudeRotation(pvProv, date, frame);
108 }
109
110 /** {@inheritDoc} */
111 @Override
112 public <T extends CalculusFieldElement<T>> FieldRotation<T> getAttitudeRotation(final FieldPVCoordinatesProvider<T> pvProv,
113 final FieldAbsoluteDate<T> date,
114 final Frame frame) {
115 return getAttitudeProvider(date.toAbsoluteDate()).getAttitudeRotation(pvProv, date, frame);
116 }
117
118 @Override
119 public AbsoluteDate getMinDate() {
120 return providers.firstEntry().getValue().getMinDate();
121 }
122
123 /** {@inheritDoc} */
124 @Override
125 public AbsoluteDate getMaxDate() {
126 return providers.lastEntry().getValue().getMaxDate();
127 }
128
129 /**
130 * Get the attitude provider to use for the given date.
131 * @param date of query
132 * @return attitude provider to use on date.
133 */
134 private BoundedAttitudeProvider getAttitudeProvider(final AbsoluteDate date) {
135 final Entry<AbsoluteDate, BoundedAttitudeProvider> attitudeEntry = providers.floorEntry(date);
136 if (attitudeEntry != null) {
137 return attitudeEntry.getValue();
138 } else {
139 // Let the first attitude provider throw the exception
140 return providers.firstEntry().getValue();
141 }
142 }
143
144 }