...
 
Commits (230)
......@@ -24,6 +24,9 @@ pipeline {
if ( env.BRANCH_NAME ==~ /^release-[.0-9]+$/ ) {
sh 'mvn verify assembly:single'
}
else if ( env.BRANCH_NAME ==~ /^develop$/ ) {
sh 'mvn install site'
}
else {
sh 'mvn verify site'
}
......
......@@ -33,7 +33,7 @@ __Note:__ Our official repository is
## Documentation
Project overview, architecture and development, detailed features list,
tutorials, Javadoc and a lot of other information is available on the
Javadoc and a lot of other information is available on the
[Maven site](https://www.orekit.org/site-orekit-development/).
## Getting help
......
......@@ -35,7 +35,6 @@
</module>
<module name="JavadocMethod">
<property name="allowUndeclaredRTE" value="true"/>
<property name="allowMissingPropertyJavadoc" value="true"/>
<property name="validateThrows" value="false"/>
</module>
<module name="JavadocStyle"/>
......@@ -46,7 +45,11 @@
<property name="ignoreStringsRegexp" value='^(("")|(".")|("\\\\"))$'/>
</module>
<module name="MultipleVariableDeclarations"/>
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceAfter">
<property name="tokens"
value="AT, INC, DEC, UNARY_MINUS, UNARY_PLUS, BNOT, LNOT, DOT,
ARRAY_DECLARATOR, INDEX_OP"/>
</module>
<module name="NoWhitespaceBefore"/>
<module name="OperatorWrap">
<property name="option" value="eol"/>
......@@ -57,12 +60,13 @@
<property name="severity" value="warning"/>
</module>
<module name="UnnecessaryParentheses"/>
<module name="NeedBraces"/>
<module name="UnusedImports"/>
<module name="VisibilityModifier"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround">
<property name="tokens"
value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN,
value="ASSIGN, ARRAY_INIT, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN,
BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, EQUAL, GE, GT,
LAND, LCURLY, LE, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE,
LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN,
......
......@@ -5,7 +5,7 @@
<groupId>org.orekit</groupId>
<artifactId>orekit</artifactId>
<packaging>jar</packaging>
<version>10.0</version>
<version>10.1-SNAPSHOT</version>
<name>ORbit Extrapolation KIT</name>
<url>http://www.orekit.org/</url>
......@@ -46,7 +46,9 @@
<orekit.nexus-staging-maven-plugin.version>1.6.8</orekit.nexus-staging-maven-plugin.version>
<orekit.maven-gpg-plugin.version>1.6</orekit.maven-gpg-plugin.version>
<orekit.maven-install-plugin.version>3.0.0-M1</orekit.maven-install-plugin.version>
<orekit.hipparchus.version>1.5</orekit.hipparchus.version>
<orekit.mathjax.config>&lt;script type=&quot;text/x-mathjax-config&quot;&gt;MathJax.Hub.Config({ TeX: { extensions: [&quot;autoload.js&quot;]}});&lt;/script&gt;</orekit.mathjax.config>
<orekit.mathjax.enable>&lt;script type=&quot;text/javascript&quot; src=&quot;https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-AMS_CHTML&quot;&gt;&lt;/script&gt;</orekit.mathjax.enable>
<orekit.hipparchus.version>1.6-SNAPSHOT</orekit.hipparchus.version>
<orekit.junit.version>4.12</orekit.junit.version>
<orekit.compiler.source>1.8</orekit.compiler.source>
<orekit.compiler.target>1.8</orekit.compiler.target>
......@@ -158,6 +160,13 @@
<role>developer</role>
</roles>
</developer>
<developer>
<name>Yannick Jeandroz</name>
<id>yannick</id>
<roles>
<role>developer</role>
</roles>
</developer>
</developers>
<contributors>
......@@ -206,9 +215,6 @@
<contributor>
<name>James Housden</name>
</contributor>
<contributor>
<name>Yannick Jeandroz</name>
</contributor>
<contributor>
<name>Fran&#231;ois-Xavier Laffont</name>
</contributor>
......@@ -239,6 +245,12 @@
<contributor>
<name>Michael Turner</name>
</contributor>
<contributor>
<name>Gabriele Serafini</name>
</contributor>
<contributor>
<name>Shiva Iyer</name>
</contributor>
</contributors>
<organization>
......@@ -430,6 +442,7 @@
<version>${orekit.maven-javadoc-plugin.version}</version>
<configuration>
<overview>${basedir}/src/main/java/org/orekit/overview.html</overview>
<additionalOptions>--allow-script-in-comments -header &apos;${orekit.mathjax.config} ${orekit.mathjax.enable}&apos;</additionalOptions>
<bottom><![CDATA[Copyright &copy; ${project.inceptionYear}-{currentYear} <a href="http://www.c-s.fr">CS Syst&egrave;mes d&apos;information</a>. All rights reserved.]]></bottom>
<links>
<link>https://docs.oracle.com/javase/8/docs/api/</link>
......@@ -664,6 +677,7 @@
<version>${orekit.maven-javadoc-plugin.version}</version>
<configuration>
<overview>${basedir}/src/main/java/org/orekit/overview.html</overview>
<additionalOptions>--allow-script-in-comments -header &apos;${orekit.mathjax.config} ${orekit.mathjax.enable}&apos;</additionalOptions>
<bottom><![CDATA[Copyright &copy; ${project.inceptionYear}-{currentYear} <a href="http://www.c-s.fr">CS Syst&egrave;mes d&apos;information</a>. All rights reserved.]]></bottom>
<links>
<link>https://docs.oracle.com/javase/8/docs/api/</link>
......@@ -833,6 +847,29 @@
</plugins>
</build>
</profile>
<profile>
<id>continuous-integration</id>
<activation>
<property>
<!-- Var Env set by GitLab-CI -->
<name>env.CI</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${orekit.maven-surefire-plugin.version}</version>
<configuration>
<!-- Orekit is mostly a computational library. -->
<!-- As there is not a lot of I/O it is better to not overide the number of CPU. -->
<forkCount>1C</forkCount>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>eclipse</id>
<activation>
......
This diff is collapsed.
......@@ -20,6 +20,151 @@
<title>Orekit Changes</title>
</properties>
<body>
<release version="10.1" date="TBD" description="TBD">
<action dev="bryan" type="fix" issue="617">
Fixed null pointer exception in MultiplexedMeasurement.
</action>
<action dev="luc" type="fix" issue="575">
Allow users to provide custom convergence checkers for
batch least squares orbit determination.
</action>
<action dev="luc" type="add" issue="614">
Added multiplexed measurements.
</action>
<action dev="luc" type="fix" issue="616">
Fixed missed changes updates in ParameterDriversList embedding
other ParameterDriversList instances.
</action>
<action dev="luc" type="update">
Moved tutorials to a separate sister project.
</action>
<action dev="bryan" type="add" due-to="Shiva Iyer">
Added Laplace method for initial orbit determination.
</action>
<action dev="bryan" type="fix" issue="612">
Fixed DSST orbit determination tutorial.
</action>
<action dev="bryan" type="add" issue="610">
Added IRNSS orbit propagator.
</action>
<action dev="bryan" type="add" issue="608">
Added support for RINEX 3.04 files.
</action>
<action dev="gabb" type="fix" issue="533">
Fixed bugs in the derivatives computation in IodGooding.
Fixed bugs in IodLambert when there's more than an half revolution
between start and final position.
</action>
<action dev="bryan" type="fix" issue="604">
Fixed parsing of compact RINEX files with wrong key in header
produced by some Septentrio receivers.
</action>
<action dev="luc" type="fix" issue="603">
Fixed parsing of compact RINEX files with missing types in header
produced by some Septentrio receivers.
</action>
<action dev="evan" type="fix" issue="589">
Improve performance of AggregateBoundedPropagator by factor of 2.
</action>
<action dev="luc" type="fix" issue="600">
Fixed parsing of compact RINEX files with many observation types.
</action>
<action dev="bryan" type="fix">
Fixed poor design of GLONASS numerical propagator.
</action>
<action dev="luc" type="fix" issue="599">
Fixed an issue in projection to flat ellipse.
</action>
<action dev="bryan" type="fix" issue="598">
Added lazily addition of Newtonian attraction to the DSST and
numerical propagator builders.
</action>
<action dev="luc" type="add" issue="595">
Added EllipticalFieldOfView (with two different ways to define the
ellipticity constraint) that can be used in FieldOfViewDetector,
GroundFieldOfViewDetector and FootprintOverlapDetector.
</action>
<action dev="luc" type="add">
Fields of view with regular polygonal shape can now be built either
based on a defining cone inside the Fov and touching it at edges
middle points, or based on a defining cone outside the Fov and touching
it at vertices.
</action>
<action dev="luc" type="add" issue="594">
Added CircularFieldOfView that can be used in FieldOfViewDetector,
GroundFieldOfViewDetector and FootprintOverlapDetector.
</action>
<action dev="luc" type="add">
Set up a general hierarchy for Field Of View with various shapes. At
start, it includes DoubleDihedraFieldOfView and PolygonalFieldOfView.
</action>
<action dev="luc" type="add" issue="592">
Added FilesListCrawler to load files from an explicit list.
</action>
<action dev="evan" type="fix" issue="583">
Fix AbsoluteDate.compareTo() for future/past infinity.
</action>
<action dev="luc" type="fix" issue="588">
Fixed wrong handling of spacecraft states in multi-satellites orbit determination
and multi-satellite measurements generation.
</action>
<action dev="bryan" type="fix" issue="585">
Improved contributing guide.
</action>
<action dev="petrus" type="fix" issue="570">
Make FieldOfView.getFootprint public.
</action>
<action dev="bryan" type="add">
Added combination of measurements.
</action>
<action dev="bryan" type="fix">
Fix values of GPS C2D, L2D, D2D and S2D frequencies.
</action>
<action dev="bryan" type="add">
Add Nequick ionospheric model.
</action>
<action dev="luc" type="fix" issue="581">
Fixed spurious empty line insertion during Rinex 2 decompression
when the number of observations per satellite is a multiple of 5
</action>
<action dev="luc" type="fix" issue="580">
Fixed decompression of very small negative values in Hatanaka
Compact RINEX format.
</action>
<action dev="luc" type="fix" issue="578">
Orbit determination tutorials (and tests too) now supports compressed
measurement files (gzip, Unix compress, Hatanaka Compact RINEX).
</action>
<action dev="luc" type="fix" issue="579">
Handle properly special events flags in Hatanaka Compact RINEX format.
</action>
<action dev="luc" type="fix" issue="483">
Reset additional state changed by event handlers and not managed by any
additional state providers.
</action>
<action dev="luc" type="add" issue="472">
Added support for Hatanaka Compact RINEX format.
</action>
<action dev="luc" type="fix" issue="574">
Cope with input stream readers that keep asking for new bytes after end
of Unix compressed files has been reached.
</action>
<action dev="luc" type="fix" issue="573">
Added detection of some corrupted Unix-compressed files.
</action>
<action dev="bryan" type="fix" issue="572">
Fixed the Saastamoinen model when station altitude is bigger than 5000.0 meters.
</action>
<action dev="luc" type="fix" issue="568">
Fixed too fast step increase in a bracketing attempt.
</action>
<action dev="luc" type="add">
Added phase measurement builder.
</action>
<action dev="luc" type="add">
Added getWavelength in GNSS Frequency.
</action>
</release>
<release version="10.0" date="2019-06-24"
description="Orekit 10.0 is a major new release. It includes DSST OD,
propagation in non-inertial frames, specialized propagators for GNSS
......
......@@ -221,31 +221,42 @@ public class Ellipse implements Serializable {
FastMath.copySign(g * FastMath.sqrt(a2 - rEllipse * rEllipse), y));
} else {
final double k = FastMath.hypot(x / a, y / b);
double projectedX = x / k;
double projectedY = y / k;
double deltaX = Double.POSITIVE_INFINITY;
double deltaY = Double.POSITIVE_INFINITY;
// initial point at evolute cusp along major axis
double omegaX = a * e2;
double omegaY = 0.0;
double projectedX = x;
double projectedY = y;
double deltaX = Double.POSITIVE_INFINITY;
double deltaY = Double.POSITIVE_INFINITY;
int count = 0;
final double threshold = ANGULAR_THRESHOLD * ANGULAR_THRESHOLD * a2;
while ((deltaX * deltaX + deltaY * deltaY) > threshold && count++ < 100) { // this loop usually converges in 3 iterations
final double omegaX = evoluteFactorX * projectedX * projectedX * projectedX;
final double omegaY = evoluteFactorY * projectedY * projectedY * projectedY;
// find point at the intersection of ellipse and line going from query point to evolute point
final double dx = x - omegaX;
final double dy = y - omegaY;
final double alpha = b2 * dx * dx + a2 * dy * dy;
final double beta = b2 * omegaX * dx + a2 * omegaY * dy;
final double betaPrime = b2 * omegaX * dx + a2 * omegaY * dy;
final double gamma = b2 * omegaX * omegaX + a2 * omegaY * omegaY - a2 * b2;
final double deltaPrime = MathArrays.linearCombination(beta, beta, -alpha, gamma);
final double ratio = (beta <= 0) ?
(FastMath.sqrt(deltaPrime) - beta) / alpha :
-gamma / (FastMath.sqrt(deltaPrime) + beta);
final double deltaPrime = MathArrays.linearCombination(betaPrime, betaPrime, -alpha, gamma);
final double ratio = (betaPrime <= 0) ?
(FastMath.sqrt(deltaPrime) - betaPrime) / alpha :
-gamma / (FastMath.sqrt(deltaPrime) + betaPrime);
final double previousX = projectedX;
final double previousY = projectedY;
projectedX = omegaX + ratio * dx;
projectedY = omegaY + ratio * dy;
// find new evolute point
omegaX = evoluteFactorX * projectedX * projectedX * projectedX;
omegaY = evoluteFactorY * projectedY * projectedY * projectedY;
// compute convergence parameters
deltaX = projectedX - previousX;
deltaY = projectedY - previousY;
}
return new Vector2D(FastMath.copySign(projectedX, p.getX()), projectedY);
}
......
......@@ -44,6 +44,7 @@ import org.orekit.utils.TimeStampedPVCoordinates;
* axis is the rotation or polar axis.</p>
* @author Luc Maisonobe
* @author Guylaine Prat
*/
public class OneAxisEllipsoid extends Ellipsoid implements BodyShape {
......@@ -88,6 +89,15 @@ public class OneAxisEllipsoid extends Ellipsoid implements BodyShape {
* <tr><td style="background-color:#c9d5c9;">WGS84</td>
* <td>{@link org.orekit.utils.Constants#WGS84_EARTH_EQUATORIAL_RADIUS Constants.WGS84_EARTH_EQUATORIAL_RADIUS}</td>
* <td>{@link org.orekit.utils.Constants#WGS84_EARTH_FLATTENING Constants.WGS84_EARTH_FLATTENING}</td></tr>
* <tr><td style="background-color:#c9d5c9;">IERS96</td>
* <td>{@link org.orekit.utils.Constants#IERS96_EARTH_EQUATORIAL_RADIUS Constants.IERS96_EARTH_EQUATORIAL_RADIUS}</td>
* <td>{@link org.orekit.utils.Constants#IERS96_EARTH_FLATTENING Constants.IERS96_EARTH_FLATTENING}</td></tr>
* <tr><td style="background-color:#c9d5c9;">IERS2003</td>
* <td>{@link org.orekit.utils.Constants#IERS2003_EARTH_EQUATORIAL_RADIUS Constants.IERS2003_EARTH_EQUATORIAL_RADIUS}</td>
* <td>{@link org.orekit.utils.Constants#IERS2003_EARTH_FLATTENING Constants.IERS2003_EARTH_FLATTENING}</td></tr>
* <tr><td style="background-color:#c9d5c9;">IERS2010</td>
* <td>{@link org.orekit.utils.Constants#IERS2010_EARTH_EQUATORIAL_RADIUS Constants.IERS2010_EARTH_EQUATORIAL_RADIUS}</td>
* <td>{@link org.orekit.utils.Constants#IERS2010_EARTH_FLATTENING Constants.IERS2010_EARTH_FLATTENING}</td></tr>
* </table>
* @param ae equatorial radius
* @param f the flattening (f = (a-b)/a)
......
/* Copyright 2002-2019 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.data;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.hipparchus.exception.DummyLocalizable;
import org.orekit.errors.OrekitException;
/** Provider for data files defined in a list.
* <p>
* All {@link DataProvidersManager#addFilter(DataFilter) registered}
* {@link DataFilter filters} are applied.
* </p>
* <p>
* Zip archives entries are supported recursively.
* </p>
* @since 10.1
* @see DataProvidersManager
* @see NetworkCrawler
* @see FilesListCrawler
* @author Luc Maisonobe
*/
public abstract class AbstractListCrawler<T> implements DataProvider {
/** Inputs list. */
private final List<T> inputs;
/** Build a data classpath crawler.
* @param inputs list of inputs (may be empty if {@link #addInput(Object) addInput} is called later)
*/
@SafeVarargs
protected AbstractListCrawler(final T... inputs) {
this.inputs = Arrays.stream(inputs).collect(Collectors.toList());
}
/** Add an input to the supported list.
* @param input input to add
*/
public void addInput(final T input) {
inputs.add(input);
}
/** Get the list of inputs supported by the instance.
* @return unmodifiable view of the list of inputs supported by the instance
*/
public List<T> getInputs() {
return Collections.unmodifiableList(inputs);
}
/** Get the complete name of a input.
* @param input input to consider
* @return complete name of the input
*/
protected abstract String getCompleteName(T input);
/** Get the base name of an input.
* @param input input to consider
* @return base name of the input
*/
protected abstract String getBaseName(T input);
/** Get a zip/jar crawler for an input.
* @param input input to consider
* @return zip/jar crawler for an input
*/
protected abstract ZipJarCrawler getZipJarCrawler(T input);
/** Get the stream to read from an input.
* @param input input to read from
* @return stream to read the content of the input
* @throws IOException if the input cannot be opened for reading
*/
protected abstract InputStream getStream(T input) throws IOException;
/** {@inheritDoc} */
public boolean feed(final Pattern supported, final DataLoader visitor) {
try {
OrekitException delayedException = null;
boolean loaded = false;
for (T input : inputs) {
try {
if (visitor.stillAcceptsData()) {
final String name = getCompleteName(input);
final String fileName = getBaseName(input);
if (ZIP_ARCHIVE_PATTERN.matcher(fileName).matches()) {
// browse inside the zip/jar file
getZipJarCrawler(input).feed(supported, visitor);
loaded = true;
} else {
// apply all registered filters
NamedData data = new NamedData(fileName, () -> getStream(input));
data = DataProvidersManager.getInstance().applyAllFilters(data);
if (supported.matcher(data.getName()).matches()) {
// visit the current file
try (InputStream is = data.getStreamOpener().openStream()) {
visitor.loadData(is, name);
loaded = true;
}
}
}
}
} catch (OrekitException oe) {
// maybe the next path component will be able to provide data
// wait until all components have been tried
delayedException = oe;
}
}
if (!loaded && delayedException != null) {
throw delayedException;
}
return loaded;
} catch (IOException | ParseException e) {
throw new OrekitException(e, new DummyLocalizable(e.getMessage()));
}
}
}
......@@ -46,7 +46,8 @@ import org.orekit.errors.OrekitMessages;
* data and another one for system-wide or general data.
* </p>
* <p>
* Gzip-compressed files are supported.
* All {@link DataProvidersManager#addFilter(DataFilter) registered}
* {@link DataFilter filters} are applied.
* </p>
* <p>
* Zip archives entries are supported recursively.
......
......@@ -31,7 +31,7 @@ import java.util.regex.Pattern;
* providers manager singleton}, or to let this manager use its default
* configuration. Once registered, they will be used automatically whenever
* some data needs to be loaded. This allow high level applications developers
* to customize Orekit data loading mechanism and get a tighter intergation of
* to customize Orekit data loading mechanism and get a tighter integration of
* the library within their application.
* </p>
* @see DataLoader
......
......@@ -30,6 +30,7 @@ import java.util.regex.Pattern;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.gnss.HatanakaCompressFilter;
/** Singleton class managing all supported {@link DataProvider data providers}.
......@@ -102,6 +103,7 @@ public class DataProvidersManager {
// set up predefined filters
addFilter(new GzipFilter());
addFilter(new UnixCompressFilter());
addFilter(new HatanakaCompressFilter());
predefinedFilters = filters.size();
......
......@@ -39,7 +39,8 @@ import org.orekit.errors.OrekitMessages;
* files are checked for loading.
* </p>
* <p>
* Gzip-compressed files are supported.
* All {@link DataProvidersManager#addFilter(DataFilter) registered}
* {@link DataFilter filters} are applied.
* </p>
* <p>
* Zip archives entries are supported recursively.
......
/* Copyright 2002-2019 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.orekit.data;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
/** Provider for data files in an explicit list.
* <p>
* Zip archives entries are supported recursively.
* </p>
* <p>
* This is a simple application of the <code>visitor</code> design pattern for
* list browsing.
* </p>
* @see DataProvidersManager
* @since 10.1
* @author Luc Maisonobe
*/
public class FilesListCrawler extends AbstractListCrawler<File> {
/** Build a data classpath crawler.
* <p>The default timeout is set to 10 seconds.</p>
* @param inputs list of input files
*/
public FilesListCrawler(final File... inputs) {
super(inputs);
}
/** {@inheritDoc} */
@Override
protected String getCompleteName(final File input) {
return input.getPath();
}
/** {@inheritDoc} */
@Override
protected String getBaseName(final File input) {
return input.getName();
}
/** {@inheritDoc} */
@Override
protected ZipJarCrawler getZipJarCrawler(final File input) {
return new ZipJarCrawler(input);
}
/** {@inheritDoc} */
@Override
protected InputStream getStream(final File input) throws IOException {
return new FileInputStream(input);
}
}
......@@ -21,6 +21,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
......@@ -179,7 +180,7 @@ public class FundamentalNutationArguments implements Serializable {
final DefinitionParser definitionParser = new DefinitionParser();
// setup the reader
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
int lineNumber = 0;
// look for the reference date and the 14 polynomials
......
......@@ -22,10 +22,6 @@ import java.io.InputStream;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLConnection;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import org.hipparchus.exception.DummyLocalizable;
import org.orekit.errors.OrekitException;
......@@ -59,7 +55,8 @@ import org.orekit.errors.OrekitException;
* </pre>
*
* <p>
* Gzip-compressed files are supported.
* All {@link DataProvidersManager#addFilter(DataFilter) registered}
* {@link DataFilter filters} are applied.
* </p>
* <p>
* Zip archives entries are supported recursively.
......@@ -71,27 +68,18 @@ import org.orekit.errors.OrekitException;
* @see DataProvidersManager
* @author Luc Maisonobe
*/
public class NetworkCrawler implements DataProvider {
/** URLs list. */
private final List<URL> urls;
public class NetworkCrawler extends AbstractListCrawler<URL> {
/** Connection timeout (milliseconds). */
private int timeout;
/** Build a data classpath crawler.
* <p>The default timeout is set to 10 seconds.</p>
* @param urls list of data file URLs
* @param inputs list of input file URLs
*/
public NetworkCrawler(final URL... urls) {
this.urls = new ArrayList<URL>();
for (final URL url : urls) {
this.urls.add(url);
}
public NetworkCrawler(final URL... inputs) {
super(inputs);
timeout = 10000;
}
/** Set the timeout for connection.
......@@ -102,66 +90,31 @@ public class NetworkCrawler implements DataProvider {
}
/** {@inheritDoc} */
public boolean feed(final Pattern supported, final DataLoader visitor) {
@Override
protected String getCompleteName(final URL input) {
try {
OrekitException delayedException = null;
boolean loaded = false;
for (URL url : urls) {
try {
if (visitor.stillAcceptsData()) {
final String name = url.toURI().toString();
final String fileName = new File(url.getPath()).getName();
if (ZIP_ARCHIVE_PATTERN.matcher(fileName).matches()) {
// browse inside the zip/jar file
new ZipJarCrawler(url).feed(supported, visitor);
loaded = true;
} else {
// apply all registered filters
NamedData data = new NamedData(fileName, () -> getStream(url));
data = DataProvidersManager.getInstance().applyAllFilters(data);
if (supported.matcher(data.getName()).matches()) {
// visit the current file
try (InputStream input = data.getStreamOpener().openStream()) {
visitor.loadData(input, name);
loaded = true;
}
}
}
}
} catch (OrekitException oe) {
// maybe the next path component will be able to provide data
// wait until all components have been tried
delayedException = oe;
}
}
if (!loaded && delayedException != null) {
throw delayedException;
}
return loaded;
} catch (URISyntaxException | IOException | ParseException e) {
throw new OrekitException(e, new DummyLocalizable(e.getMessage()));
return input.toURI().toString();
} catch (URISyntaxException ue) {
throw new OrekitException(ue, new DummyLocalizable(ue.getMessage()));
}
}
/** {@inheritDoc} */
@Override
protected String getBaseName(final URL input) {
return new File(input.getPath()).getName();
}
/** Get the stream to read from the remote URL.
* @param url url to read from
* @return stream to read the content of the URL
* @throws IOException if the URL cannot be opened for reading
*/
private InputStream getStream(final URL url) throws IOException {
final URLConnection connection = url.openConnection();
/** {@inheritDoc} */
@Override
protected ZipJarCrawler getZipJarCrawler(final URL input) {
return new ZipJarCrawler(input);
}
/** {@inheritDoc} */
@Override
protected InputStream getStream(final URL input) throws IOException {
final URLConnection connection = input.openConnection();
connection.setConnectTimeout(timeout);
return connection.getInputStream();
}
......
......@@ -20,6 +20,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
......@@ -524,7 +525,7 @@ public class PoissonSeriesParser {
try {
// setup the reader
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
int lineNumber = 0;
int expectedIndex = -1;
int nTerms = -1;
......
......@@ -20,6 +20,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
......@@ -93,7 +94,7 @@ public class SimpleTimeStampedTableParser<T extends TimeStamped> {
try {
// setup the reader
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, "UTF-8"));
final BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
final List<T> table = new ArrayList<T>();
......
......@@ -75,6 +75,9 @@ public class UnixCompressFilter implements DataFilter {
/** Underlying compressed stream. */
private final InputStream input;
/** Indicator for end of input. */
private boolean endOfInput;
/** Common sequences table. */
private final UncompressedSequence[] table;
......@@ -119,9 +122,9 @@ public class UnixCompressFilter implements DataFilter {
ZInputStream(final String name, final InputStream input)
throws IOException {
this.name = name;
this.input = input;
this.name = name;
this.input = input;
this.endOfInput = false;
// check header
if (input.read() != MAGIC_HEADER_1 || input.read() != MAGIC_HEADER_2) {
......@@ -232,7 +235,14 @@ public class UnixCompressFilter implements DataFilter {
if (previousSequence != null && available < table.length) {
// update the table with the next uncompressed byte appended to previous sequence
final byte nextByte = (key == available) ? previousSequence.getByte(0) : table[key].getByte(0);
final byte nextByte;
if (key == available) {
nextByte = previousSequence.getByte(0);
} else if (table[key] != null) {
nextByte = table[key].getByte(0);
} else {
throw new OrekitIOException(OrekitMessages.CORRUPTED_FILE, name);
}
table[available++] = new UncompressedSequence(previousSequence, nextByte);
if (available > currentMaxKey && currentWidth < maxWidth) {
// we need to increase the key size
......@@ -258,8 +268,9 @@ public class UnixCompressFilter implements DataFilter {
public int read() throws IOException {
if (currentSequence == null) {
if (!selectNext()) {
if (endOfInput || !selectNext()) {
// we have reached end of data
endOfInput = true;
return -1;
}
}
......
......@@ -46,7 +46,8 @@ import org.orekit.errors.OrekitException;
* loader, all of them will be loaded.
* </p>
* <p>
* Gzip-compressed files are supported.
* All {@link DataProvidersManager#addFilter(DataFilter) registered}
* {@link DataFilter filters} are applied.
* </p>
* <p>
* Zip archives entries are supported recursively.
......
......@@ -21,6 +21,7 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.PropertyResourceBundle;
......@@ -236,7 +237,14 @@ public enum OrekitMessages implements Localizable {
"prefix that is matched against the name of each loaded file. It should " +
"not contain any regular expression syntax or directory components, i.e. " +
"\"/\" or \"\\\". Actual value: \"{0}\"."),
CANNOT_COMPUTE_AIMING_AT_SINGULAR_POINT("cannot compute aiming direction at singular point: latitude = {0}, longitude = {1}");
CANNOT_COMPUTE_AIMING_AT_SINGULAR_POINT("cannot compute aiming direction at singular point: latitude = {0}, longitude = {1}"),
STEC_INTEGRATION_DID_NOT_CONVERGE("STEC integration did not converge"),
MODIP_GRID_NOT_LOADED("MODIP grid not be loaded from {0}"),
NEQUICK_F2_FM3_NOT_LOADED("NeQuick coefficient f2 or fm3 not be loaded from {0}"),
NOT_A_SUPPORTED_HATANAKA_COMPRESSED_FILE("file {0} is not a supported Hatanaka-compressed file"),
INVALID_MEASUREMENT_TYPES_FOR_COMBINATION_OF_MEASUREMENTS("invalid measurement types {0} and {1} for the combination of measurements {2}"),
INCOMPATIBLE_FREQUENCIES_FOR_COMBINATION_OF_MEASUREMENTS("frequencies {0} and {1} are incompatibles for the {2} combination"),
NON_CHRONOLOGICAL_DATES_FOR_OBSERVATIONS("observations {0} and {1} are not in chronological dates");
// CHECKSTYLE: resume JavadocVariable check
......@@ -319,7 +327,7 @@ public enum OrekitMessages implements Localizable {
if (stream != null) {
try {
// Only this line is changed to make it to read properties files as UTF-8.
bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
bundle = new PropertyResourceBundle(new InputStreamReader(stream, StandardCharsets.UTF_8));
} finally {
stream.close();
}
......
......@@ -118,6 +118,24 @@ public class IodGibbs {
final AbsoluteDate date = date2;
// compute the equivalent Keplerian orbit
return new KeplerianOrbit(pv, frame, date, mu);
final KeplerianOrbit orbit = new KeplerianOrbit(pv, frame, date, mu);
//define the reverse orbit
final PVCoordinates pv2 = new PVCoordinates(r2, vlEci.scalarMultiply(-1));
final KeplerianOrbit orbit2 = new KeplerianOrbit(pv2, frame, date, mu);
//check which orbit is correct
final Vector3D estP3 = orbit.shiftedBy(date3.durationFrom(date2)).
getPVCoordinates().getPosition();
final double dist = estP3.subtract(r3).getNorm();
final Vector3D estP3_2 = orbit2.shiftedBy(date3.durationFrom(date2)).
getPVCoordinates().getPosition();
final double dist2 = estP3_2.subtract(r3).getNorm();
if (dist <= dist2) {
return orbit;
} else {
return orbit2;
}
}
}
......@@ -135,18 +135,21 @@ public class IodGooding {
* @param lineOfSight1 line of sight 1
* @param dateObs1 date of observation 1
* @param lineOfSight2 line of sight 2
* @param dateObs2 date of observation 1
* @param dateObs2 date of observation 2
* @param lineOfSight3 line of sight 3
* @param dateObs3 date of observation 1
* @param dateObs3 date of observation 3
* @param rho1init initial guess of the range problem. range 1, in meters
* @param rho3init initial guess of the range problem. range 3, in meters
* @param nRev number of complete revolutions between observation1 and 3
* @param direction true if posigrade (short way)
* @return an estimate of the Keplerian orbit
*/
public KeplerianOrbit estimate(final Vector3D O1, final Vector3D O2, final Vector3D O3,
final Vector3D lineOfSight1, final AbsoluteDate dateObs1,
final Vector3D lineOfSight2, final AbsoluteDate dateObs2,
final Vector3D lineOfSight3, final AbsoluteDate dateObs3,
final double rho1init, final double rho3init) {
final double rho1init, final double rho3init, final int nRev,
final boolean direction) {
this.date1 = dateObs1;
......@@ -167,8 +170,8 @@ public class IodGooding {
// solve the range problem
solveRangeProblem(rho1init / R, rho3init / R,
dateObs3.durationFrom(dateObs1) / T, dateObs2.durationFrom(dateObs1) / T,
0,
true,
nRev,
direction,
lineOfSight1, lineOfSight2, lineOfSight3,
maxiter);
......@@ -180,6 +183,32 @@ public class IodGooding {
return gibbs.estimate(frame, p1, dateObs1, p2, dateObs2, p3, dateObs3);
}
/** Orbit got from Observed Three Lines of Sight (angles only).
* assuming there was less than an half revolution between start and final date
*
* @param O1 Observer position 1
* @param O2 Observer position 2
* @param O3 Observer position 3
* @param lineOfSight1 line of sight 1
* @param dateObs1 date of observation 1
* @param lineOfSight2 line of sight 2
* @param dateObs2 date of observation 1
* @param lineOfSight3 line of sight 3
* @param dateObs3 date of observation 1
* @param rho1init initial guess of the range problem. range 1, in meters
* @param rho3init initial guess of the range problem. range 3, in meters
* @return an estimate of the Keplerian orbit
*/
public KeplerianOrbit estimate(final Vector3D O1, final Vector3D O2, final Vector3D O3,
final Vector3D lineOfSight1, final AbsoluteDate dateObs1,
final Vector3D lineOfSight2, final AbsoluteDate dateObs2,
final Vector3D lineOfSight3, final AbsoluteDate dateObs3,
final double rho1init, final double rho3init) {
return this.estimate(O1, O2, O3, lineOfSight1, dateObs1, lineOfSight2, dateObs2,
lineOfSight3, dateObs3, rho1init, rho3init, 0, true);
}
/** Solve the range problem when three line of sight are given.
*
* @param rho1init initial value for range R1, in meters
......@@ -248,14 +277,17 @@ public class IodGooding {
// They should be zero when line of sight 2 and current direction for 2 from O2 are aligned.
final Vector3D u = lineOfSight2.crossProduct(C);
final Vector3D P = (u.crossProduct(lineOfSight2)).normalize();
final Vector3D EN = (lineOfSight2.crossProduct(P)).normalize();
final Vector3D ENt = lineOfSight2.crossProduct(P);
// if EN is zero we have a solution!
final double ENR = EN.getNorm();
// if ENt is zero we have a solution!
final double ENR = ENt.getNorm();
if (ENR == 0.) {
return true;
}