/** * 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); }
/** * 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); }
/** {@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; // Χ = 1 / B chi = 1. / B; chi2 = chi * chi; // mean motion n meanMotion = aux.getMeanMotion(); }