use of org.orekit.bodies.FieldGeodeticPoint in project Orekit by CS-SI.
the class DTM2000 method getDensity.
/**
* {@inheritDoc}
*/
@Override
public <T extends RealFieldElement<T>> T getDensity(final FieldAbsoluteDate<T> date, final FieldVector3D<T> position, final Frame frame) throws OrekitException {
// check if data are available :
final AbsoluteDate dateD = date.toAbsoluteDate();
if ((dateD.compareTo(inputParams.getMaxDate()) > 0) || (dateD.compareTo(inputParams.getMinDate()) < 0)) {
throw new OrekitException(OrekitMessages.NO_SOLAR_ACTIVITY_AT_DATE, dateD, inputParams.getMinDate(), inputParams.getMaxDate());
}
// compute day number in current year
final Calendar cal = new GregorianCalendar();
cal.setTime(date.toDate(TimeScalesFactory.getUTC()));
final int day = cal.get(Calendar.DAY_OF_YEAR);
// position in ECEF so we only have to do the transform once
final Frame ecef = earth.getBodyFrame();
final FieldVector3D<T> pEcef = frame.getTransformTo(ecef, date).transformPosition(position);
// compute geodetic position
final FieldGeodeticPoint<T> inBody = earth.transform(pEcef, ecef, date);
final T alti = inBody.getAltitude();
final T lon = inBody.getLongitude();
final T lat = inBody.getLatitude();
// compute local solar time
final Vector3D sunPos = sun.getPVCoordinates(dateD, ecef).getPosition();
final T y = pEcef.getY().multiply(sunPos.getX()).subtract(pEcef.getX().multiply(sunPos.getY()));
final T x = pEcef.getX().multiply(sunPos.getX()).add(pEcef.getY().multiply(sunPos.getY()));
final T hl = y.atan2(x).add(FastMath.PI);
// get current solar activity data and compute
return getDensity(day, alti, lon, lat, hl, inputParams.getInstantFlux(dateD), inputParams.getMeanFlux(dateD), inputParams.getThreeHourlyKP(dateD), inputParams.get24HoursKp(dateD));
}
use of org.orekit.bodies.FieldGeodeticPoint in project Orekit by CS-SI.
the class Geoid method getIntersectionPoint.
/**
* {@inheritDoc}
*
* <p> The intersection point is computed using a line search along the
* specified line. This is accurate when the geoid is slowly varying.
*/
@Override
public <T extends RealFieldElement<T>> FieldGeodeticPoint<T> getIntersectionPoint(final FieldLine<T> lineInFrame, final FieldVector3D<T> closeInFrame, final Frame frame, final FieldAbsoluteDate<T> date) throws OrekitException {
final Field<T> field = date.getField();
/*
* It is assumed that the geoid is slowly varying over it's entire
* surface. Therefore there will one local intersection.
*/
// transform to body frame
final Frame bodyFrame = this.getBodyFrame();
final FieldTransform<T> frameToBody = frame.getTransformTo(bodyFrame, date);
final FieldVector3D<T> close = frameToBody.transformPosition(closeInFrame);
final FieldLine<T> lineInBodyFrame = frameToBody.transformLine(lineInFrame);
// set the line's direction so the solved for value is always positive
final FieldLine<T> line;
if (lineInBodyFrame.getAbscissa(close).getReal() < 0) {
line = lineInBodyFrame.revert();
} else {
line = lineInBodyFrame;
}
final ReferenceEllipsoid ellipsoid = this.getEllipsoid();
// calculate end points
// distance from line to center of earth, squared
final T d2 = line.pointAt(0.0).getNormSq();
// the minimum abscissa, squared
final double n = ellipsoid.getPolarRadius() + MIN_UNDULATION;
final T minAbscissa2 = d2.negate().add(n * n);
// smaller end point of the interval = 0.0 or intersection with
// min_undulation sphere
final T lowPoint = minAbscissa2.getReal() < 0 ? field.getZero() : minAbscissa2.sqrt();
// the maximum abscissa, squared
final double x = ellipsoid.getEquatorialRadius() + MAX_UNDULATION;
final T maxAbscissa2 = d2.negate().add(x * x);
// larger end point of the interval
final T highPoint = maxAbscissa2.sqrt();
// line search function
final RealFieldUnivariateFunction<T> heightFunction = z -> {
try {
final FieldGeodeticPoint<T> geodetic = transform(line.pointAt(z), bodyFrame, date);
return geodetic.getAltitude();
} catch (OrekitException e) {
// due to frame transform -> re-throw
throw new RuntimeException(e);
}
};
// compute answer
if (maxAbscissa2.getReal() < 0) {
// ray does not pierce bounding sphere -> no possible intersection
return null;
}
// solve line search problem to find the intersection
final FieldBracketingNthOrderBrentSolver<T> solver = new FieldBracketingNthOrderBrentSolver<>(field.getZero().add(1.0e-14), field.getZero().add(1.0e-6), field.getZero().add(1.0e-15), 5);
try {
final T abscissa = solver.solve(MAX_EVALUATIONS, heightFunction, lowPoint, highPoint, AllowedSolution.ANY_SIDE);
// return intersection point
return this.transform(line.pointAt(abscissa), bodyFrame, date);
} catch (MathRuntimeException e) {
// no intersection
return null;
}
}
use of org.orekit.bodies.FieldGeodeticPoint in project Orekit by CS-SI.
the class Geoid method transform.
/**
* {@inheritDoc}
*
* @param point The surface relative point to transform. Altitude is
* orthometric height, that is height above the {@link Geoid}.
* Latitude and longitude are both geodetic and defined with
* respect to the {@link #getEllipsoid() reference ellipsoid}.
* @param <T> type of the field elements
* @return point at the same location but as a Cartesian point in the {@link
* #getBodyFrame() body frame}.
* @see #transform(Vector3D, Frame, AbsoluteDate)
* @since 9.0
*/
@Override
public <T extends RealFieldElement<T>> FieldVector3D<T> transform(final FieldGeodeticPoint<T> point) {
try {
// convert orthometric height to height above ellipsoid using undulation
// TODO pass in date to allow user to specify
final double undulation = this.getUndulation(point.getLatitude().getReal(), point.getLongitude().getReal(), this.defaultDate);
final FieldGeodeticPoint<T> ellipsoidal = new FieldGeodeticPoint<>(point.getLatitude(), point.getLongitude(), point.getAltitude().add(undulation));
// transform using reference ellipsoid
return this.getEllipsoid().transform(ellipsoidal);
} catch (OrekitException e) {
// an OrekitException, so wrap in an exception we can throw.
throw new RuntimeException(e);
}
}
use of org.orekit.bodies.FieldGeodeticPoint in project Orekit by CS-SI.
the class NRLMSISE00 method getDensity.
/**
* {@inheritDoc}
*/
@Override
public <T extends RealFieldElement<T>> T getDensity(final FieldAbsoluteDate<T> date, final FieldVector3D<T> position, final Frame frame) throws OrekitException {
// check if data are available :
final AbsoluteDate dateD = date.toAbsoluteDate();
if ((dateD.compareTo(inputParams.getMaxDate()) > 0) || (dateD.compareTo(inputParams.getMinDate()) < 0)) {
throw new OrekitException(OrekitMessages.NO_SOLAR_ACTIVITY_AT_DATE, dateD, inputParams.getMinDate(), inputParams.getMaxDate());
}
// compute day number in current year and the seconds within the day
final TimeScale ut1 = TimeScalesFactory.getUT1(IERSConventions.IERS_2010, true);
final DateTimeComponents dtc = dateD.getComponents(ut1);
final int doy = dtc.getDate().getDayOfYear();
final T sec = date.durationFrom(new AbsoluteDate(dtc.getDate(), TimeComponents.H00, ut1));
// compute geodetic position (km and °)
final FieldGeodeticPoint<T> inBody = earth.transform(position, frame, date);
final T alt = inBody.getAltitude().divide(1000.);
final T lon = inBody.getLongitude().multiply(180.0 / FastMath.PI);
final T lat = inBody.getLatitude().multiply(180.0 / FastMath.PI);
// compute local solar time
final T lst = localSolarTime(dateD, position, frame);
// get solar activity data and compute
final FieldOutput<T> out = new FieldOutput<>(doy, sec, lat, lon, lst, inputParams.getAverageFlux(dateD), inputParams.getDailyFlux(dateD), inputParams.getAp(dateD));
out.gtd7d(alt);
// return the local density
return out.getDensity(TOTAL_MASS);
}
Aggregations