CircularFieldOfViewDetector.java

  1. /* Copyright 2002-2019 CS Systèmes d'Information
  2.  * Licensed to CS Systèmes d'Information (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.propagation.events;

  18. import org.hipparchus.geometry.euclidean.threed.Vector3D;
  19. import org.hipparchus.ode.events.Action;
  20. import org.hipparchus.util.FastMath;
  21. import org.orekit.propagation.SpacecraftState;
  22. import org.orekit.propagation.events.handlers.EventHandler;
  23. import org.orekit.propagation.events.handlers.StopOnDecreasing;
  24. import org.orekit.utils.PVCoordinatesProvider;

  25. /** Finder for target entry/exit events with respect to a satellite sensor Field Of View.
  26.  * <p>This class handle fields of view with a circular boundary.</p>
  27.  * <p>The default implementation behavior is to {@link Action#CONTINUE continue}
  28.  * propagation at FOV entry and to {@link Action#STOP stop} propagation
  29.  * at FOV exit. This can be changed by calling
  30.  * {@link #withHandler(EventHandler)} after construction.</p>
  31.  * @see org.orekit.propagation.Propagator#addEventDetector(EventDetector)
  32.  * @see FieldOfViewDetector
  33.  * @see VisibilityTrigger
  34.  * @author V&eacute;ronique Pommier-Maurussane
  35.  */
  36. public class CircularFieldOfViewDetector extends AbstractDetector<CircularFieldOfViewDetector> {

  37.     /** Position/velocity provider of the considered target. */
  38.     private final PVCoordinatesProvider targetPVProvider;

  39.     /** Radius of the target, considered to be a spherical body (m). */
  40.     private final double radiusTarget;

  41.     /** Visibility trigger for spherical bodies. */
  42.     private final VisibilityTrigger trigger;

  43.     /** Direction of the FOV center. */
  44.     private final Vector3D center;

  45.     /** FOV half aperture angle. */
  46.     private final double halfAperture;

  47.     /** Build a new instance.
  48.      * <p>The maximal interval between distance to FOV boundary checks should
  49.      * be smaller than the half duration of the minimal pass to handle,
  50.      * otherwise some short passes could be missed.</p>
  51.      * @param maxCheck maximal interval in seconds
  52.      * @param pvTarget Position/velocity provider of the considered target
  53.      * @param center Direction of the FOV center, in spacecraft frame
  54.      * @param halfAperture FOV half aperture angle
  55.      */
  56.     public CircularFieldOfViewDetector(final double maxCheck,
  57.                                        final PVCoordinatesProvider pvTarget,
  58.                                        final Vector3D center,
  59.                                        final double halfAperture) {
  60.         this(maxCheck, pvTarget, 0.0, VisibilityTrigger.VISIBLE_AS_SOON_AS_PARTIALLY_IN_FOV, center, halfAperture);
  61.     }

  62.     /** Build a new instance.
  63.      * <p>The maximal interval between distance to FOV boundary checks should
  64.      * be smaller than the half duration of the minimal pass to handle,
  65.      * otherwise some short passes could be missed.</p>
  66.      * @param maxCheck maximal interval in seconds
  67.      * @param pvTarget Position/velocity provider of the considered target
  68.      * @param radiusTarget radius of the target, considered to be a spherical body (m)
  69.      * @param trigger visibility trigger for spherical bodie
  70.      * @param center Direction of the FOV center, in spacecraft frame
  71.      * @param halfAperture FOV half aperture angle
  72.      * @since 10.0
  73.      */
  74.     public CircularFieldOfViewDetector(final double maxCheck,
  75.                                        final PVCoordinatesProvider pvTarget, final double radiusTarget,
  76.                                        final VisibilityTrigger trigger,  final Vector3D center, final double halfAperture) {
  77.         this(maxCheck, 1.0e-3, DEFAULT_MAX_ITER, new StopOnDecreasing<CircularFieldOfViewDetector>(),
  78.              pvTarget, radiusTarget, trigger, center, halfAperture);
  79.     }

  80.     /** Private constructor with full parameters.
  81.      * <p>
  82.      * This constructor is private as users are expected to use the builder
  83.      * API with the various {@code withXxx()} methods to set up the instance
  84.      * in a readable manner without using a huge amount of parameters.
  85.      * </p>
  86.      * @param maxCheck maximum checking interval (s)
  87.      * @param threshold convergence threshold (s)
  88.      * @param maxIter maximum number of iterations in the event time search
  89.      * @param handler event handler to call at event occurrences
  90.      * @param pvTarget Position/velocity provider of the considered target
  91.      * @param radiusTarget radius of the target, considered to be a spherical body (m)
  92.      * @param trigger visibility trigger for spherical bodie
  93.      * @param center Direction of the FOV center, in spacecraft frame
  94.      * @param halfAperture FOV half aperture angle
  95.      * @since 6.1
  96.      */
  97.     private CircularFieldOfViewDetector(final double maxCheck, final double threshold,
  98.                                         final int maxIter, final EventHandler<? super CircularFieldOfViewDetector> handler,
  99.                                         final PVCoordinatesProvider pvTarget, final double radiusTarget,
  100.                                         final VisibilityTrigger trigger, final Vector3D center, final double halfAperture) {
  101.         super(maxCheck, threshold, maxIter, handler);
  102.         this.targetPVProvider = pvTarget;
  103.         this.radiusTarget     = radiusTarget;
  104.         this.trigger          = trigger;
  105.         this.center           = center;
  106.         this.halfAperture     = halfAperture;
  107.     }

  108.     /** {@inheritDoc} */
  109.     @Override
  110.     protected CircularFieldOfViewDetector create(final double newMaxCheck, final double newThreshold,
  111.                                                  final int newMaxIter, final EventHandler<? super CircularFieldOfViewDetector> newHandler) {
  112.         return new CircularFieldOfViewDetector(newMaxCheck, newThreshold, newMaxIter, newHandler,
  113.                                                targetPVProvider, radiusTarget, trigger, center, halfAperture);
  114.     }

  115.     /** Get the position/velocity provider of the target .
  116.      * @return the position/velocity provider of the target
  117.      */
  118.     public PVCoordinatesProvider getPVTarget() {
  119.         return targetPVProvider;
  120.     }

  121.     /** Get the direction of FOV center.
  122.      * @return the direction of FOV center
  123.      */
  124.     public Vector3D getCenter() {
  125.         return center;
  126.     }

  127.     /** Get FOV half aperture angle.
  128.      * @return the FOV half aperture angle
  129.      */
  130.     public double getHalfAperture() {
  131.         return halfAperture;
  132.     }

  133.     /** {@inheritDoc}
  134.      * <p>
  135.      * The g function value is the difference between FOV half aperture and the
  136.      * absolute value of the angle between target direction and field of view center,
  137.      * plus or minus the target angular radius depending on the {@link VisibilityTrigger}.
  138.      * It is positive inside the FOV and negative outside.
  139.      * </p>
  140.      */
  141.     public double g(final SpacecraftState s) {

  142.         // Compute target position/velocity at date in spacecraft frame
  143.         final Vector3D targetPosInert = new Vector3D(1, targetPVProvider.getPVCoordinates(s.getDate(), s.getFrame()).getPosition(),
  144.                                            -1, s.getPVCoordinates().getPosition());
  145.         final Vector3D targetPosSat = s.getAttitude().getRotation().applyTo(targetPosInert);
  146.         final double angularRadius = FastMath.asin(radiusTarget / targetPosSat.getNorm());

  147.         // Target is in the field of view if the absolute value that angle is smaller than FOV half aperture.
  148.         // g function value is the difference between FOV half aperture and the absolute value of the angle between
  149.         // target direction and field of view center. It is positive inside the FOV and negative outside.
  150.         return halfAperture - Vector3D.angle(targetPosSat, center) - FastMath.copySign(angularRadius, trigger.getSign());
  151.     }

  152. }