use of org.orekit.frames.Transform in project Orekit by CS-SI.
the class FootprintOverlapDetector method g.
/**
* {@inheritDoc}
* <p>
* The g function value is the minimum offset among the region points
* with respect to the Field Of View boundary. It is positive if all region
* points are outside of the Field Of View, and negative if at least some
* of the region points are inside of the Field Of View. The minimum is
* computed by sampling the region, considering only the points for which
* the spacecraft is above the horizon. The accuracy of the detection
* depends on the linear sampling step set at detector construction. If
* the spacecraft is below horizon for all region points, an arbitrary
* positive value is returned.
* </p>
* <p>
* As per the previous definition, when the region enters the Field Of
* View, a decreasing event is generated, and when the region leaves
* the Field Of View, an increasing event is generated.
* </p>
*/
public double g(final SpacecraftState s) throws OrekitException {
// initial arbitrary positive value
double value = FastMath.PI;
// get spacecraft position in body frame
final Vector3D scBody = s.getPVCoordinates(body.getBodyFrame()).getPosition();
// map the point to a sphere
final GeodeticPoint gp = body.transform(scBody, body.getBodyFrame(), s.getDate());
final S2Point s2p = new S2Point(gp.getLongitude(), 0.5 * FastMath.PI - gp.getLatitude());
// for faster computation, we start using only the surrounding cap, to filter out
// far away points (which correspond to most of the points if the zone is small)
final Vector3D p = s2p.getVector();
final double dot = Vector3D.dotProduct(p, capCenter);
if (dot < capCos) {
// the spacecraft is outside of the cap, look for the closest cap point
final Vector3D t = p.subtract(dot, capCenter).normalize();
final Vector3D close = new Vector3D(capCos, capCenter, capSin, t);
if (Vector3D.dotProduct(p, close) < -0.01) {
// we can return the arbitrary initial positive value without performing further computation
return value;
}
}
// the spacecraft may be visible from some points in the zone, check them all
final Transform bodyToSc = new Transform(s.getDate(), body.getBodyFrame().getTransformTo(s.getFrame(), s.getDate()), s.toTransform());
for (final SamplingPoint point : sampledZone) {
final Vector3D lineOfSightBody = point.getPosition().subtract(scBody);
if (Vector3D.dotProduct(lineOfSightBody, point.getZenith()) <= 0) {
// spacecraft is above this sample point local horizon
// get line of sight in spacecraft frame
final double offset = fov.offsetFromBoundary(bodyToSc.transformVector(lineOfSightBody));
value = FastMath.min(value, offset);
}
}
return value;
}
use of org.orekit.frames.Transform 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 GeodeticPoint getIntersectionPoint(final Line lineInFrame, final Vector3D closeInFrame, final Frame frame, final AbsoluteDate date) throws OrekitException {
/*
* 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 Transform frameToBody = frame.getTransformTo(bodyFrame, date);
final Vector3D close = frameToBody.transformPosition(closeInFrame);
final Line lineInBodyFrame = frameToBody.transformLine(lineInFrame);
// set the line's direction so the solved for value is always positive
final Line line;
if (lineInBodyFrame.getAbscissa(close) < 0) {
line = lineInBodyFrame.revert();
} else {
line = lineInBodyFrame;
}
final ReferenceEllipsoid ellipsoid = this.getEllipsoid();
// calculate end points
// distance from line to center of earth, squared
final double d2 = line.pointAt(0.0).getNormSq();
// the minimum abscissa, squared
final double n = ellipsoid.getPolarRadius() + MIN_UNDULATION;
final double minAbscissa2 = n * n - d2;
// smaller end point of the interval = 0.0 or intersection with
// min_undulation sphere
final double lowPoint = FastMath.sqrt(FastMath.max(minAbscissa2, 0.0));
// the maximum abscissa, squared
final double x = ellipsoid.getEquatorialRadius() + MAX_UNDULATION;
final double maxAbscissa2 = x * x - d2;
// larger end point of the interval
final double highPoint = FastMath.sqrt(maxAbscissa2);
// line search function
final UnivariateFunction heightFunction = new UnivariateFunction() {
@Override
public double value(final double x) {
try {
final GeodeticPoint geodetic = transform(line.pointAt(x), bodyFrame, date);
return geodetic.getAltitude();
} catch (OrekitException e) {
// due to frame transform -> re-throw
throw new RuntimeException(e);
}
}
};
// compute answer
if (maxAbscissa2 < 0) {
// ray does not pierce bounding sphere -> no possible intersection
return null;
}
// solve line search problem to find the intersection
final UnivariateSolver solver = new BracketingNthOrderBrentSolver();
try {
final double abscissa = solver.solve(MAX_EVALUATIONS, heightFunction, lowPoint, highPoint);
// return intersection point
return this.transform(line.pointAt(abscissa), bodyFrame, date);
} catch (MathRuntimeException e) {
// no intersection
return null;
}
}
use of org.orekit.frames.Transform 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.frames.Transform in project Orekit by CS-SI.
the class DSSTTesseral method initializeStep.
/**
* {@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;
// 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();
}
use of org.orekit.frames.Transform in project Orekit by CS-SI.
the class ElevationExtremumDetector method g.
/**
* Compute the value of the detection function.
* <p>
* The value is the spacecraft elevation first time derivative.
* </p>
* @param s the current state information: date, kinematics, attitude
* @return spacecraft elevation first time derivative
* @exception OrekitException if some specific error occurs
*/
public double g(final SpacecraftState s) throws OrekitException {
// get position, velocity acceleration of spacecraft in topocentric frame
final Transform inertToTopo = s.getFrame().getTransformTo(topo, s.getDate());
final TimeStampedPVCoordinates pvTopo = inertToTopo.transformPVCoordinates(s.getPVCoordinates());
// convert the coordinates to DerivativeStructure based vector
// instead of having vector position, then vector velocity then vector acceleration
// we get one vector and each coordinate is a DerivativeStructure containing
// value, first time derivative (we don't need second time derivative here)
final FieldVector3D<DerivativeStructure> pvDS = pvTopo.toDerivativeStructureVector(1);
// compute elevation and its first time derivative
final DerivativeStructure elevation = pvDS.getZ().divide(pvDS.getNorm()).asin();
// return elevation first time derivative
return elevation.getPartialDerivative(1);
}
Aggregations