AggregateBoundedAttitudeProvider.java

  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.attitudes;

  18. import java.util.Collection;
  19. import java.util.Map.Entry;
  20. import java.util.ArrayList;
  21. import java.util.NavigableMap;
  22. import java.util.List;
  23. import java.util.TreeMap;
  24. import java.util.stream.Stream;

  25. import org.hipparchus.CalculusFieldElement;
  26. import org.hipparchus.Field;
  27. import org.hipparchus.geometry.euclidean.threed.FieldRotation;
  28. import org.hipparchus.geometry.euclidean.threed.Rotation;
  29. import org.orekit.errors.OrekitException;
  30. import org.orekit.errors.OrekitMessages;
  31. import org.orekit.frames.Frame;
  32. import org.orekit.propagation.events.DateDetector;
  33. import org.orekit.propagation.events.EventDetector;
  34. import org.orekit.propagation.events.FieldDateDetector;
  35. import org.orekit.propagation.events.FieldEventDetector;
  36. import org.orekit.time.AbsoluteDate;
  37. import org.orekit.time.FieldAbsoluteDate;
  38. import org.orekit.utils.FieldPVCoordinatesProvider;
  39. import org.orekit.utils.PVCoordinatesProvider;
  40. import org.orekit.utils.ParameterDriver;

  41. /**
  42.  * A {@link BoundedAttitudeProvider} that covers a larger time span from several constituent
  43.  * attitude providers that cover shorter time spans.
  44.  *
  45.  * @author Bryan Cazabonne
  46.  * @since 10.3
  47.  */
  48. public class AggregateBoundedAttitudeProvider implements BoundedAttitudeProvider {

  49.     /** Constituent attitude provider. */
  50.     private final NavigableMap<AbsoluteDate, BoundedAttitudeProvider> providers;

  51.     /**
  52.      * Constructor.
  53.      * @param providers attitude providers that provide the backing data for this instance.
  54.      *                  There must be at least one attitude provider in the collection.
  55.      *                  If there are gaps between the {@link BoundedAttitudeProvider#getMaxDate()}
  56.      *                  of one attitude provider and the {@link BoundedAttitudeProvider#getMinDate()}
  57.      *                  of the next attitude provider an exception may be thrown by any method of
  58.      *                  this class at any time. If there are overlaps between the the {@link
  59.      *                  BoundedAttitudeProvider#getMaxDate()} of one attitude provider and the {@link
  60.      *                  BoundedAttitudeProvider#getMinDate()} of the next attitude provider then the
  61.      *                  attitude provider with the latest {@link BoundedAttitudeProvider#getMinDate()}
  62.      *                  is used.
  63.      */
  64.     public AggregateBoundedAttitudeProvider(final Collection<? extends BoundedAttitudeProvider> providers) {

  65.         // Check if the collection is empty
  66.         if (providers.isEmpty()) {
  67.             throw new OrekitException(OrekitMessages.NOT_ENOUGH_ATTITUDE_PROVIDERS);
  68.         }

  69.         // Initialize map
  70.         this.providers = new TreeMap<>();

  71.         // Loop on providers
  72.         for (final BoundedAttitudeProvider provider : providers) {
  73.             // Fill collection
  74.             this.providers.put(provider.getMinDate(), provider);
  75.         }

  76.     }

  77.     /** {@inheritDoc} */
  78.     @Override
  79.     public Attitude getAttitude(final PVCoordinatesProvider pvProv, final AbsoluteDate date,
  80.                                 final Frame frame) {

  81.         // Get the attitude provider for the given date
  82.         final BoundedAttitudeProvider provider = getAttitudeProvider(date);

  83.         // Build attitude
  84.         return provider.getAttitude(pvProv, date, frame);

  85.     }

  86.     /** {@inheritDoc} */
  87.     @Override
  88.     public <T extends CalculusFieldElement<T>> FieldAttitude<T> getAttitude(final FieldPVCoordinatesProvider<T> pvProv,
  89.                                                                             final FieldAbsoluteDate<T> date,
  90.                                                                             final Frame frame) {

  91.         // Get the attitude provider for the given date
  92.         final BoundedAttitudeProvider provider = getAttitudeProvider(date.toAbsoluteDate());

  93.         // Build attitude
  94.         return provider.getAttitude(pvProv, date, frame);

  95.     }

  96.     /** {@inheritDoc} */
  97.     @Override
  98.     public Rotation getAttitudeRotation(final PVCoordinatesProvider pvProv, final AbsoluteDate date, final Frame frame) {
  99.         return getAttitudeProvider(date).getAttitudeRotation(pvProv, date, frame);
  100.     }

  101.     /** {@inheritDoc} */
  102.     @Override
  103.     public <T extends CalculusFieldElement<T>> FieldRotation<T> getAttitudeRotation(final FieldPVCoordinatesProvider<T> pvProv,
  104.                                                                                     final FieldAbsoluteDate<T> date,
  105.                                                                                     final Frame frame) {
  106.         return getAttitudeProvider(date.toAbsoluteDate()).getAttitudeRotation(pvProv, date, frame);
  107.     }

  108.     @Override
  109.     public AbsoluteDate getMinDate() {
  110.         return providers.firstEntry().getValue().getMinDate();
  111.     }

  112.     /** {@inheritDoc} */
  113.     @Override
  114.     public AbsoluteDate getMaxDate() {
  115.         return providers.lastEntry().getValue().getMaxDate();
  116.     }

  117.     /**
  118.      * Get the attitude provider to use for the given date.
  119.      * @param date of query
  120.      * @return attitude provider to use on date.
  121.      */
  122.     private BoundedAttitudeProvider getAttitudeProvider(final AbsoluteDate date) {
  123.         final Entry<AbsoluteDate, BoundedAttitudeProvider> attitudeEntry = providers.floorEntry(date);
  124.         if (attitudeEntry != null) {
  125.             return attitudeEntry.getValue();
  126.         } else {
  127.             // Let the first attitude provider throw the exception
  128.             return providers.firstEntry().getValue();
  129.         }
  130.     }

  131.     /** {@inheritDoc} */
  132.     @Override
  133.     public Stream<EventDetector> getEventDetectors() {
  134.         final List<AbsoluteDate> dates = new ArrayList<>(providers.navigableKeySet());
  135.         final DateDetector detector = getDateDetector(dates.toArray(new AbsoluteDate[0]));
  136.         return Stream.concat(Stream.of(detector), getEventDetectors(getParametersDrivers()));
  137.     }

  138.     /** {@inheritDoc} */
  139.     @Override
  140.     public <T extends CalculusFieldElement<T>> Stream<FieldEventDetector<T>> getFieldEventDetectors(final Field<T> field) {
  141.         final List<AbsoluteDate> dates = new ArrayList<>(providers.navigableKeySet());
  142.         final FieldDateDetector<T> detector = getFieldDateDetector(field, dates.toArray(new AbsoluteDate[0]));
  143.         return Stream.concat(Stream.of(detector), getFieldEventDetectors(field, getParametersDrivers()));
  144.     }

  145.     /** {@inheritDoc} */
  146.     @Override
  147.     public List<ParameterDriver> getParametersDrivers() {
  148.         final List<ParameterDriver> drivers = new ArrayList<>();
  149.         providers.values().forEach(provider -> drivers.addAll(provider.getParametersDrivers()));
  150.         return drivers;
  151.     }
  152. }