use of org.orekit.bodies.GeodeticPoint in project Orekit by CS-SI.
the class OrbitDetermination method createStationsData.
/**
* Set up stations.
* @param parser input file parser
* @param body central body
* @return name to station data map
* @exception OrekitException if some frame transforms cannot be computed
* @throws NoSuchElementException if input parameters are missing
*/
private Map<String, StationData> createStationsData(final KeyValueFileParser<ParameterKey> parser, final OneAxisEllipsoid body) throws OrekitException, NoSuchElementException {
final Map<String, StationData> stations = new HashMap<String, StationData>();
final String[] stationNames = parser.getStringArray(ParameterKey.GROUND_STATION_NAME);
final double[] stationLatitudes = parser.getAngleArray(ParameterKey.GROUND_STATION_LATITUDE);
final double[] stationLongitudes = parser.getAngleArray(ParameterKey.GROUND_STATION_LONGITUDE);
final double[] stationAltitudes = parser.getDoubleArray(ParameterKey.GROUND_STATION_ALTITUDE);
final boolean[] stationPositionEstimated = parser.getBooleanArray(ParameterKey.GROUND_STATION_POSITION_ESTIMATED);
final double[] stationRangeSigma = parser.getDoubleArray(ParameterKey.GROUND_STATION_RANGE_SIGMA);
final double[] stationRangeBias = parser.getDoubleArray(ParameterKey.GROUND_STATION_RANGE_BIAS);
final double[] stationRangeBiasMin = parser.getDoubleArray(ParameterKey.GROUND_STATION_RANGE_BIAS_MIN);
final double[] stationRangeBiasMax = parser.getDoubleArray(ParameterKey.GROUND_STATION_RANGE_BIAS_MAX);
final boolean[] stationRangeBiasEstimated = parser.getBooleanArray(ParameterKey.GROUND_STATION_RANGE_BIAS_ESTIMATED);
final double[] stationRangeRateSigma = parser.getDoubleArray(ParameterKey.GROUND_STATION_RANGE_RATE_SIGMA);
final double[] stationRangeRateBias = parser.getDoubleArray(ParameterKey.GROUND_STATION_RANGE_RATE_BIAS);
final double[] stationRangeRateBiasMin = parser.getDoubleArray(ParameterKey.GROUND_STATION_RANGE_RATE_BIAS_MIN);
final double[] stationRangeRateBiasMax = parser.getDoubleArray(ParameterKey.GROUND_STATION_RANGE_RATE_BIAS_MAX);
final boolean[] stationRangeRateBiasEstimated = parser.getBooleanArray(ParameterKey.GROUND_STATION_RANGE_RATE_BIAS_ESTIMATED);
final double[] stationAzimuthSigma = parser.getAngleArray(ParameterKey.GROUND_STATION_AZIMUTH_SIGMA);
final double[] stationAzimuthBias = parser.getAngleArray(ParameterKey.GROUND_STATION_AZIMUTH_BIAS);
final double[] stationAzimuthBiasMin = parser.getAngleArray(ParameterKey.GROUND_STATION_AZIMUTH_BIAS_MIN);
final double[] stationAzimuthBiasMax = parser.getAngleArray(ParameterKey.GROUND_STATION_AZIMUTH_BIAS_MAX);
final double[] stationElevationSigma = parser.getAngleArray(ParameterKey.GROUND_STATION_ELEVATION_SIGMA);
final double[] stationElevationBias = parser.getAngleArray(ParameterKey.GROUND_STATION_ELEVATION_BIAS);
final double[] stationElevationBiasMin = parser.getAngleArray(ParameterKey.GROUND_STATION_ELEVATION_BIAS_MIN);
final double[] stationElevationBiasMax = parser.getAngleArray(ParameterKey.GROUND_STATION_ELEVATION_BIAS_MAX);
final boolean[] stationAzElBiasesEstimated = parser.getBooleanArray(ParameterKey.GROUND_STATION_AZ_EL_BIASES_ESTIMATED);
final boolean[] stationElevationRefraction = parser.getBooleanArray(ParameterKey.GROUND_STATION_ELEVATION_REFRACTION_CORRECTION);
final boolean[] stationRangeTropospheric = parser.getBooleanArray(ParameterKey.GROUND_STATION_RANGE_TROPOSPHERIC_CORRECTION);
for (int i = 0; i < stationNames.length; ++i) {
// the station itself
final GeodeticPoint position = new GeodeticPoint(stationLatitudes[i], stationLongitudes[i], stationAltitudes[i]);
final TopocentricFrame topo = new TopocentricFrame(body, position, stationNames[i]);
final GroundStation station = new GroundStation(topo);
station.getEastOffsetDriver().setSelected(stationPositionEstimated[i]);
station.getNorthOffsetDriver().setSelected(stationPositionEstimated[i]);
station.getZenithOffsetDriver().setSelected(stationPositionEstimated[i]);
// range
final double rangeSigma = stationRangeSigma[i];
final Bias<Range> rangeBias;
if (FastMath.abs(stationRangeBias[i]) >= Precision.SAFE_MIN || stationRangeBiasEstimated[i]) {
rangeBias = new Bias<Range>(new String[] { stationNames[i] + "/range bias" }, new double[] { stationRangeBias[i] }, new double[] { rangeSigma }, new double[] { stationRangeBiasMin[i] }, new double[] { stationRangeBiasMax[i] });
rangeBias.getParametersDrivers().get(0).setSelected(stationRangeBiasEstimated[i]);
} else {
// bias fixed to zero, we don't need to create a modifier for this
rangeBias = null;
}
// range rate
final double rangeRateSigma = stationRangeRateSigma[i];
final Bias<RangeRate> rangeRateBias;
if (FastMath.abs(stationRangeRateBias[i]) >= Precision.SAFE_MIN || stationRangeRateBiasEstimated[i]) {
rangeRateBias = new Bias<RangeRate>(new String[] { stationNames[i] + "/range rate bias" }, new double[] { stationRangeRateBias[i] }, new double[] { rangeRateSigma }, new double[] { stationRangeRateBiasMin[i] }, new double[] { stationRangeRateBiasMax[i] });
rangeRateBias.getParametersDrivers().get(0).setSelected(stationRangeRateBiasEstimated[i]);
} else {
// bias fixed to zero, we don't need to create a modifier for this
rangeRateBias = null;
}
// angular biases
final double[] azELSigma = new double[] { stationAzimuthSigma[i], stationElevationSigma[i] };
final Bias<AngularAzEl> azELBias;
if (FastMath.abs(stationAzimuthBias[i]) >= Precision.SAFE_MIN || FastMath.abs(stationElevationBias[i]) >= Precision.SAFE_MIN || stationAzElBiasesEstimated[i]) {
azELBias = new Bias<AngularAzEl>(new String[] { stationNames[i] + "/az bias", stationNames[i] + "/el bias" }, new double[] { stationAzimuthBias[i], stationElevationBias[i] }, azELSigma, new double[] { stationAzimuthBiasMin[i], stationElevationBiasMin[i] }, new double[] { stationAzimuthBiasMax[i], stationElevationBiasMax[i] });
azELBias.getParametersDrivers().get(0).setSelected(stationAzElBiasesEstimated[i]);
azELBias.getParametersDrivers().get(1).setSelected(stationAzElBiasesEstimated[i]);
} else {
// bias fixed to zero, we don't need to create a modifier for this
azELBias = null;
}
// Refraction correction
final AngularRadioRefractionModifier refractionCorrection;
if (stationElevationRefraction[i]) {
final double altitude = station.getBaseFrame().getPoint().getAltitude();
final AtmosphericRefractionModel refractionModel = new EarthITU453AtmosphereRefraction(altitude);
refractionCorrection = new AngularRadioRefractionModifier(refractionModel);
} else {
refractionCorrection = null;
}
// Tropospheric correction
final RangeTroposphericDelayModifier rangeTroposphericCorrection;
if (stationRangeTropospheric[i]) {
final SaastamoinenModel troposphericModel = SaastamoinenModel.getStandardModel();
rangeTroposphericCorrection = new RangeTroposphericDelayModifier(troposphericModel);
} else {
rangeTroposphericCorrection = null;
}
stations.put(stationNames[i], new StationData(station, rangeSigma, rangeBias, rangeRateSigma, rangeRateBias, azELSigma, azELBias, refractionCorrection, rangeTroposphericCorrection));
}
return stations;
}
use of org.orekit.bodies.GeodeticPoint in project Orekit by CS-SI.
the class DOPComputation method run.
private void run(final OneAxisEllipsoid shape, final List<GeodeticPoint> zone, final double meshSize, final double minElevation, final AbsoluteDate tStart, final AbsoluteDate tStop, final double tStep) throws IOException, OrekitException, ParseException {
// Gets the GPS almanacs from the SEM file
final SEMParser reader = new SEMParser(null);
reader.loadData();
final List<GPSAlmanac> almanacs = reader.getAlmanacs();
// Creates the GPS propagators from the almanacs
final List<Propagator> propagators = new ArrayList<Propagator>();
for (GPSAlmanac almanac : almanacs) {
// Only keeps almanac with health status ok
if (almanac.getHealth() == 0) {
propagators.add(new GPSPropagator.Builder(almanac).build());
} else {
System.out.println("GPS PRN " + almanac.getPRN() + " is not OK (Health status = " + almanac.getHealth() + ").");
}
}
// Meshes the area of interest into a grid of geodetic points.
final List<List<GeodeticPoint>> points = sample(shape, zone, meshSize);
// Creates the DOP computers for all the locations of the sampled geographic zone
final List<DOPComputer> computers = new ArrayList<DOPComputer>();
for (List<GeodeticPoint> row : points) {
for (GeodeticPoint point : row) {
computers.add(DOPComputer.create(shape, point).withMinElevation(minElevation));
}
}
// Computes the DOP for each point over the period
final List<List<DOP>> allDop = new ArrayList<List<DOP>>();
// Loops on the period
AbsoluteDate tc = tStart;
while (tc.compareTo(tStop) != 1) {
// Loops on the grid points
final List<DOP> dopAtDate = new ArrayList<DOP>();
for (DOPComputer computer : computers) {
try {
final DOP dop = computer.compute(tc, propagators);
dopAtDate.add(dop);
} catch (OrekitException oe) {
System.out.println(oe.getLocalizedMessage());
}
}
allDop.add(dopAtDate);
tc = tc.shiftedBy(tStep);
}
// Post-processing: gets the statistics of PDOP over the zone at each time
System.out.println(" PDOP");
System.out.println(" Date min max");
for (List<DOP> dopAtDate : allDop) {
final StreamingStatistics pDoP = new StreamingStatistics();
for (DOP dopAtLoc : dopAtDate) {
pDoP.addValue(dopAtLoc.getPdop());
}
final AbsoluteDate date = dopAtDate.get(0).getDate();
System.out.format(Locale.ENGLISH, "%s %.2f %.2f%n", date.toString(), pDoP.getMin(), pDoP.getMax());
}
}
use of org.orekit.bodies.GeodeticPoint in project Orekit by CS-SI.
the class AlongTrackAiming method alongTileDirection.
/**
* {@inheritDoc}
*/
@Override
public Vector3D alongTileDirection(final Vector3D point, final GeodeticPoint gp) throws OrekitException {
final double lStart = halfTrack.get(0).getFirst().getLatitude();
final double lEnd = halfTrack.get(halfTrack.size() - 1).getFirst().getLatitude();
// check the point can be reached
if (gp.getLatitude() < FastMath.min(lStart, lEnd) || gp.getLatitude() > FastMath.max(lStart, lEnd)) {
throw new OrekitException(OrekitMessages.OUT_OF_RANGE_LATITUDE, FastMath.toDegrees(gp.getLatitude()), FastMath.toDegrees(FastMath.min(lStart, lEnd)), FastMath.toDegrees(FastMath.max(lStart, lEnd)));
}
// bracket the point in the half track sample
int iInf = 0;
int iSup = halfTrack.size() - 1;
while (iSup - iInf > 1) {
final int iMiddle = (iSup + iInf) / 2;
if ((lStart < lEnd) ^ (halfTrack.get(iMiddle).getFirst().getLatitude() > gp.getLatitude())) {
// the specified latitude is in the second half
iInf = iMiddle;
} else {
// the specified latitude is in the first half
iSup = iMiddle;
}
}
// ensure we can get points at iStart, iStart + 1, iStart + 2 and iStart + 3
final int iStart = FastMath.max(0, FastMath.min(iInf - 1, halfTrack.size() - 4));
// interpolate ground sliding point at specified latitude
final HermiteInterpolator interpolator = new HermiteInterpolator();
for (int i = iStart; i < iStart + 4; ++i) {
final Vector3D position = halfTrack.get(i).getSecond().getPosition();
final Vector3D velocity = halfTrack.get(i).getSecond().getVelocity();
interpolator.addSamplePoint(halfTrack.get(i).getFirst().getLatitude(), new double[] { position.getX(), position.getY(), position.getZ(), velocity.getX(), velocity.getY(), velocity.getZ() });
}
final DerivativeStructure[] p = interpolator.value(factory.variable(0, gp.getLatitude()));
// extract interpolated ground position/velocity
final Vector3D position = new Vector3D(p[0].getValue(), p[1].getValue(), p[2].getValue());
final Vector3D velocity = new Vector3D(p[3].getValue(), p[4].getValue(), p[5].getValue());
// adjust longitude to match the specified one
final Rotation rotation = new Rotation(Vector3D.PLUS_K, position, Vector3D.PLUS_K, point);
final Vector3D fixedVelocity = rotation.applyTo(velocity);
// the tile direction is aligned with sliding point velocity
return fixedVelocity.normalize();
}
use of org.orekit.bodies.GeodeticPoint in project Orekit by CS-SI.
the class HalfTrackSampler method handleStep.
/**
* {@inheritDoc}
*/
@Override
public void handleStep(final SpacecraftState currentState, final boolean isLast) throws OrekitException {
// find the sliding ground point below spacecraft
final TimeStampedPVCoordinates pv = currentState.getPVCoordinates(ellipsoid.getBodyFrame());
final TimeStampedPVCoordinates groundPV = ellipsoid.projectToGround(pv, ellipsoid.getBodyFrame());
// geodetic coordinates
final GeodeticPoint gp = ellipsoid.transform(groundPV.getPosition(), ellipsoid.getBodyFrame(), currentState.getDate());
halfTrack.add(new Pair<GeodeticPoint, TimeStampedPVCoordinates>(gp, groundPV));
}
use of org.orekit.bodies.GeodeticPoint in project Orekit by CS-SI.
the class Tile method getInterpolatedPoint.
/**
* Get an interpolated point inside the tile.
* <p>
* The interpolated point is based on bilinear interpolations
* along the body surface assumed to be <em>spherical</em>,
* and along the vertical axis.
* </p>
* <p>
* The interpolation parameters are chosen such that
* (u = 0, v = 0) maps to vertex v0, (u = 1, v = 0) maps
* to vertex v1, (u = 1, v = 1) maps to vertex v2 and
* (u = 0, v = 1) maps to vertex v3.
* </p>
* @param u first interpolation parameter (should be between
* 0 and 1 to remain inside the tile)
* @param v second interpolation parameter (should be between
* 0 and 1 to remain inside the tile)
* @return interpolated point
*/
public GeodeticPoint getInterpolatedPoint(final double u, final double v) {
// bilinear interpolation along a spherical shape
final Vector3D pu0 = interpolate(v0.getZenith(), v1.getZenith(), u);
final Vector3D pu1 = interpolate(v3.getZenith(), v2.getZenith(), u);
final Vector3D puv = interpolate(pu0, pu1, v);
// bilinear interpolation of altitude
final double hu0 = v1.getAltitude() * u + v0.getAltitude() * (1 - u);
final double hu1 = v2.getAltitude() * u + v3.getAltitude() * (1 - u);
final double huv = hu1 * v + hu0 * (1 - v);
// create interpolated point
return new GeodeticPoint(puv.getDelta(), puv.getAlpha(), huv);
}
Aggregations