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