Beispiel #1
0
  /**
   * Compute line of sight intersection with body.
   *
   * @param scToBody transform from spacecraft frame to body frame
   * @return intersection point in body frame (only the position is set!)
   * @exception OrekitException if line of sight does not intersect body
   */
  private TimeStampedPVCoordinates losIntersectionWithBody(final Transform scToBody)
      throws OrekitException {

    // compute satellite pointing axis and position/velocity in body frame
    final Vector3D pointingBodyFrame = scToBody.transformVector(satPointingVector);
    final Vector3D pBodyFrame = scToBody.transformPosition(Vector3D.ZERO);

    // Line from satellite following pointing direction
    // we use arbitrarily the Earth radius as a scaling factor, it could be anything else
    final Line pointingLine =
        new Line(
            pBodyFrame,
            pBodyFrame.add(Constants.WGS84_EARTH_EQUATORIAL_RADIUS, pointingBodyFrame),
            1.0e-10);

    // Intersection with body shape
    final GeodeticPoint gpIntersection =
        shape.getIntersectionPoint(
            pointingLine, pBodyFrame, shape.getBodyFrame(), scToBody.getDate());
    final Vector3D pIntersection =
        (gpIntersection == null) ? null : shape.transform(gpIntersection);

    // Check there is an intersection and it is not in the reverse pointing direction
    if ((pIntersection == null)
        || (Vector3D.dotProduct(pIntersection.subtract(pBodyFrame), pointingBodyFrame) < 0)) {
      throw new OrekitException(OrekitMessages.ATTITUDE_POINTING_LAW_DOES_NOT_POINT_TO_GROUND);
    }

    return new TimeStampedPVCoordinates(
        scToBody.getDate(), pIntersection, Vector3D.ZERO, Vector3D.ZERO);
  }
Beispiel #2
0
  /**
   * Get the {@link TimeStampedPVCoordinates} in a specified frame.
   *
   * @param outputFrame frame in which the position/velocity coordinates shall be computed
   * @return pvCoordinates in the specified output frame
   * @exception OrekitException if transformation between frames cannot be computed
   * @see #getPVCoordinates()
   */
  public TimeStampedPVCoordinates getPVCoordinates(final Frame outputFrame) throws OrekitException {
    if (pvCoordinates == null) {
      pvCoordinates = initPVCoordinates();
    }

    // If output frame requested is the same as definition frame,
    // PV coordinates are returned directly
    if (outputFrame == frame) {
      return pvCoordinates;
    }

    // Else, PV coordinates are transformed to output frame
    final Transform t = frame.getTransformTo(outputFrame, date);
    return t.transformPVCoordinates(pvCoordinates);
  }
Beispiel #3
0
  /** {@inheritDoc} */
  protected TimeStampedPVCoordinates getTargetPV(
      final PVCoordinatesProvider pvProv, final AbsoluteDate date, final Frame frame)
      throws OrekitException {

    // transform from specified reference frame to spacecraft frame
    final Transform refToSc =
        new Transform(
            date,
            new Transform(date, pvProv.getPVCoordinates(date, frame).negate()),
            new Transform(date, attitudeLaw.getAttitude(pvProv, date, frame).getOrientation()));

    // transform from specified reference frame to body frame
    final Transform refToBody = frame.getTransformTo(shape.getBodyFrame(), date);

    // sample intersection points in current date neighborhood
    final Transform scToBody = new Transform(date, refToSc.getInverse(), refToBody);
    final double h = 0.1;
    final List<TimeStampedPVCoordinates> sample = new ArrayList<TimeStampedPVCoordinates>();
    sample.add(losIntersectionWithBody(scToBody.shiftedBy(-h)));
    sample.add(losIntersectionWithBody(scToBody));
    sample.add(losIntersectionWithBody(scToBody.shiftedBy(+h)));

    // use interpolation to compute properly the time-derivatives
    final TimeStampedPVCoordinates targetBody =
        TimeStampedPVCoordinates.interpolate(date, CartesianDerivativesFilter.USE_P, sample);

    // convert back to caller specified frame
    return refToBody.getInverse().transformPVCoordinates(targetBody);
  }
  /** {@inheritDoc} */
  @Override
  public double[] getShortPeriodicVariations(final AbsoluteDate date, final double[] meanElements)
      throws OrekitException {

    // Initialise the short periodic variations
    final double[] shortPeriodicVariation = new double[] {0., 0., 0., 0., 0., 0.};

    // Compute only if there is at least one non-resonant tesseral or
    // only the m-daily tesseral should be taken into account
    if (!nonResOrders.isEmpty() || mDailiesOnly) {

      // Build an Orbit object from the mean elements
      final Orbit meanOrbit =
          OrbitType.EQUINOCTIAL.mapArrayToOrbit(
              meanElements, PositionAngle.MEAN, date, provider.getMu(), this.frame);

      // Build an auxiliary object
      final AuxiliaryElements aux = new AuxiliaryElements(meanOrbit, I);

      // Central body rotation angle from equation 2.7.1-(3)(4).
      final Transform t = bodyFrame.getTransformTo(aux.getFrame(), aux.getDate());
      final Vector3D xB = t.transformVector(Vector3D.PLUS_I);
      final Vector3D yB = t.transformVector(Vector3D.PLUS_J);
      final double currentTheta =
          FastMath.atan2(
              -f.dotProduct(yB) + I * g.dotProduct(xB), f.dotProduct(xB) + I * g.dotProduct(yB));

      // Add the m-daily contribution
      for (int m = 1; m <= maxOrderMdailyTesseralSP; m++) {
        // Phase angle
        final double jlMmt = -m * currentTheta;
        final double sinPhi = FastMath.sin(jlMmt);
        final double cosPhi = FastMath.cos(jlMmt);

        // compute contribution for each element
        for (int i = 0; i < 6; i++) {
          shortPeriodicVariation[i] +=
              tesseralSPCoefs.getCijm(i, 0, m, date) * cosPhi
                  + tesseralSPCoefs.getSijm(i, 0, m, date) * sinPhi;
        }
      }

      // loop through all non-resonant (j,m) pairs
      for (final Map.Entry<Integer, List<Integer>> entry : nonResOrders.entrySet()) {
        final int m = entry.getKey();
        final List<Integer> listJ = entry.getValue();

        for (int j : listJ) {
          // Phase angle
          final double jlMmt = j * meanElements[5] - m * currentTheta;
          final double sinPhi = FastMath.sin(jlMmt);
          final double cosPhi = FastMath.cos(jlMmt);

          // compute contribution for each element
          for (int i = 0; i < 6; i++) {
            shortPeriodicVariation[i] +=
                tesseralSPCoefs.getCijm(i, j, m, date) * cosPhi
                    + tesseralSPCoefs.getSijm(i, j, m, date) * sinPhi;
          }
        }
      }
    }

    return shortPeriodicVariation;
  }
  /** {@inheritDoc} */
  @Override
  public void initializeStep(final AuxiliaryElements aux) throws OrekitException {

    // Equinoctial elements
    a = aux.getSma();
    k = aux.getK();
    h = aux.getH();
    q = aux.getQ();
    p = aux.getP();
    lm = aux.getLM();

    // Eccentricity
    ecc = aux.getEcc();
    e2 = ecc * ecc;

    // Retrograde factor
    I = aux.getRetrogradeFactor();

    // Equinoctial frame vectors
    f = aux.getVectorF();
    g = aux.getVectorG();

    // Central body rotation angle from equation 2.7.1-(3)(4).
    final Transform t = bodyFrame.getTransformTo(aux.getFrame(), aux.getDate());
    final Vector3D xB = t.transformVector(Vector3D.PLUS_I);
    final Vector3D yB = t.transformVector(Vector3D.PLUS_J);
    theta =
        FastMath.atan2(
            -f.dotProduct(yB) + I * g.dotProduct(xB), f.dotProduct(xB) + I * g.dotProduct(yB));

    // Direction cosines
    alpha = aux.getAlpha();
    beta = aux.getBeta();
    gamma = aux.getGamma();

    // Equinoctial coefficients
    // A = sqrt(μ * a)
    final double A = aux.getA();
    // B = sqrt(1 - h² - k²)
    final double B = aux.getB();
    // C = 1 + p² + q²
    final double C = aux.getC();
    // Common factors from equinoctial coefficients
    // 2 * a / A
    ax2oA = 2. * a / A;
    // B / A
    BoA = B / A;
    // 1 / AB
    ooAB = 1. / (A * B);
    // C / 2AB
    Co2AB = C * ooAB / 2.;
    // B / (A * (1 + B))
    BoABpo = BoA / (1. + B);
    // &mu / a
    moa = provider.getMu() / a;
    // R / a
    roa = provider.getAe() / a;

    // &Chi; = 1 / B
    chi = 1. / B;
    chi2 = chi * chi;

    // mean motion n
    meanMotion = aux.getMeanMotion();
  }