<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="fr">
	<id>https://patrius.cnes.fr/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin+tsn</id>
	<title>Patrius - Contributions [fr]</title>
	<link rel="self" type="application/atom+xml" href="https://patrius.cnes.fr/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Admin+tsn"/>
	<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php/Sp%C3%A9cial:Contributions/Admin_tsn"/>
	<updated>2026-07-01T05:42:38Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Accueil&amp;diff=4181</id>
		<title>Accueil</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Accueil&amp;diff=4181"/>
		<updated>2026-06-30T08:11:30Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
== WHERE TO GET IT? ==&lt;br /&gt;
&lt;br /&gt;
Just go [https://www.connectbycnes.fr/en/patrius there] ...&lt;br /&gt;
&lt;br /&gt;
== WHY PATRIUS? ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; is a core space dynamics &amp;lt;font color=#FF8C00&amp;gt;Java&amp;lt;/font&amp;gt; library that enables to quickly develop high level algorithms such as orbit extrapolator. &amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; contains several low level classes (i.e.: such as matrix, vectors, orbits parameters) as well as high level classes and interfaces (i.e.: numerical propagators, attitude laws, manoeuvers sequences).&lt;br /&gt;
&lt;br /&gt;
== MAIN ADVANTAGES ==&lt;br /&gt;
&lt;br /&gt;
All the main domains of space dynamics are available: &lt;br /&gt;
* Analysis, algebra &amp;amp; geometry (quaternions, derivable functions, integrators …)&lt;br /&gt;
* Core objects for space dynamics (dates, orbits, frames...)&lt;br /&gt;
* Orbit propagation: analytical, semi-analytical and numerical propagators, a full set of force models&lt;br /&gt;
* Maneuvers: impulsive or continuous thrust, sequences&lt;br /&gt;
* Attitude: extensible set of attitude laws, sequences and guidance framework&lt;br /&gt;
* Events: event detection (orbital, sensor events, etc.) and post-processing (chronograms)&lt;br /&gt;
* Spacecraft: characteristics of mass, geometry (drag force), sensors field of view, etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; got a deep validation by comparison with precise orbitography tools. Moreover, it is now fully used by CNES tools, in particular for operational flight dynamics subsystem (&amp;lt;font color=#FF8C00 title=&amp;quot;Flight Dynamics Subsystem&amp;quot;&amp;gt;FDS&amp;lt;/font&amp;gt;). For that reason the criticity level is “&#039;&#039;&#039;C&#039;&#039;&#039;”.&lt;br /&gt;
&lt;br /&gt;
Furthermore, &amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; design relies on extensible &amp;lt;font color=#FF8C00&amp;gt;Java&amp;lt;/font&amp;gt; interfaces and robust design patterns.&lt;br /&gt;
&lt;br /&gt;
== REMARKS ==&lt;br /&gt;
&lt;br /&gt;
A data package ([https://www.connectbycnes.fr/en/patriusdataset PATRIUS_DATASET]) is also provided in addition allowing access to some data models.&lt;br /&gt;
&lt;br /&gt;
Tutorials are available in specific tutorials pages.&lt;br /&gt;
&lt;br /&gt;
== CURRENT VERSION: 4.18 ==&lt;br /&gt;
&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; V4.18 is a release adding a few features as well as correcting some bugs (see [[Main_differences_between_V4.18_and_V4.17|here]]).&lt;br /&gt;
&lt;br /&gt;
== PREVIOUS VERSIONS (available on the Web site) ==&lt;br /&gt;
&lt;br /&gt;
* Version 4.17&lt;br /&gt;
* Version 4.16&lt;br /&gt;
* Version 4.15&lt;br /&gt;
* Version 4.14&lt;br /&gt;
* Version 4.13&lt;br /&gt;
* Version 4.12&lt;br /&gt;
* Version 4.11&lt;br /&gt;
* Version 4.10&lt;br /&gt;
* Version 4.9&lt;br /&gt;
* Version 4.8&lt;br /&gt;
* Version 4.7&lt;br /&gt;
* Version 4.6.1&lt;br /&gt;
* Version 4.5.1&lt;br /&gt;
* Version 4.4&lt;br /&gt;
* Version 4.3&lt;br /&gt;
* Version 4.2&lt;br /&gt;
* Version 4.1.1&lt;br /&gt;
* Version 4.1&lt;br /&gt;
* Version 4.0&lt;br /&gt;
* Version 3.4.1&lt;br /&gt;
* Version 3.3&lt;br /&gt;
* Version 3.2&lt;br /&gt;
&lt;br /&gt;
== DEPENDENCIES ==&lt;br /&gt;
&lt;br /&gt;
See when the different PATRIUS versions were released and what JAVA version each is compatible with [[Patrius_Versions_and_Dependencies|here]]&lt;br /&gt;
&lt;br /&gt;
== JAVA DOC ==&lt;br /&gt;
&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.18 Current Java Doc]&lt;br /&gt;
&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.17 Java Doc 4.17]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.16 Java Doc 4.16]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.15 Java Doc 4.15]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.14 Java Doc 4.14]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.13 Java Doc 4.13]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.12 Java Doc 4.12]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.11 Java Doc 4.11]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.10.2 Java Doc 4.10.2]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.9.1 Java Doc 4.9.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.8 Java Doc 4.8]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.7 Java Doc 4.7]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.6.1 Java Doc 4.6.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.5.1 Java Doc 4.5.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.4 Java Doc 4.4]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.3 Java Doc 4.3]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.2 Java Doc 4.2]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.1.1 Java Doc 4.1.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.1 Java Doc 4.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.0 Java Doc 4.0]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V3.4.1 Java Doc 3.4.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V3.3 Java Doc 3.3]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V3.2 Java Doc 3.2]&amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Accueil&amp;diff=4180</id>
		<title>Accueil</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Accueil&amp;diff=4180"/>
		<updated>2026-06-30T08:10:59Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
== WHERE TO GET IT? ==&lt;br /&gt;
&lt;br /&gt;
Just go [https://www.connectbycnes.fr/en/patrius there] ...&lt;br /&gt;
&lt;br /&gt;
== WHY PATRIUS? ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; is a core space dynamics &amp;lt;font color=#FF8C00&amp;gt;Java&amp;lt;/font&amp;gt; library that enables to quickly develop high level algorithms such as orbit extrapolator. &amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; contains several low level classes (i.e.: such as matrix, vectors, orbits parameters) as well as high level classes and interfaces (i.e.: numerical propagators, attitude laws, manoeuvers sequences).&lt;br /&gt;
&lt;br /&gt;
== MAIN ADVANTAGES ==&lt;br /&gt;
&lt;br /&gt;
All the main domains of space dynamics are available: &lt;br /&gt;
* Analysis, algebra &amp;amp; geometry (quaternions, derivable functions, integrators …)&lt;br /&gt;
* Core objects for space dynamics (dates, orbits, frames...)&lt;br /&gt;
* Orbit propagation: analytical, semi-analytical and numerical propagators, a full set of force models&lt;br /&gt;
* Maneuvers: impulsive or continuous thrust, sequences&lt;br /&gt;
* Attitude: extensible set of attitude laws, sequences and guidance framework&lt;br /&gt;
* Events: event detection (orbital, sensor events, etc.) and post-processing (chronograms)&lt;br /&gt;
* Spacecraft: characteristics of mass, geometry (drag force), sensors field of view, etc.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; got a deep validation by comparison with precise orbitography tools. Moreover, it is now fully used by CNES tools, in particular for operational flight dynamics subsystem (&amp;lt;font color=#FF8C00 title=&amp;quot;Flight Dynamics Subsystem&amp;quot;&amp;gt;FDS&amp;lt;/font&amp;gt;). For that reason the criticity level is “&#039;&#039;&#039;C&#039;&#039;&#039;”.&lt;br /&gt;
&lt;br /&gt;
Furthermore, &amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; design relies on extensible &amp;lt;font color=#FF8C00&amp;gt;Java&amp;lt;/font&amp;gt; interfaces and robust design patterns.&lt;br /&gt;
&lt;br /&gt;
== REMARKS ==&lt;br /&gt;
&lt;br /&gt;
A data package ([https://www.connectbycnes.fr/en/patriusdataset PATRIUS_DATASET]) is also provided in addition allowing access to some data models.&lt;br /&gt;
&lt;br /&gt;
Tutorials are available in specific tutorials pages.&lt;br /&gt;
&lt;br /&gt;
== CURRENT VERSION: 4.18 ==&lt;br /&gt;
&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; V4.18 is a release adding a few features as well as correcting some bugs (see [[Main_differences_between_V4.18_and_V4.17|here]]).&lt;br /&gt;
&lt;br /&gt;
== PREVIOUS VERSIONS (available on the Web site) ==&lt;br /&gt;
&lt;br /&gt;
* Version 4.17&lt;br /&gt;
* Version 4.16&lt;br /&gt;
* Version 4.15&lt;br /&gt;
* Version 4.14&lt;br /&gt;
* Version 4.13&lt;br /&gt;
* Version 4.12&lt;br /&gt;
* Version 4.11&lt;br /&gt;
* Version 4.10&lt;br /&gt;
* Version 4.9&lt;br /&gt;
* Version 4.8&lt;br /&gt;
* Version 4.7&lt;br /&gt;
* Version 4.6.1&lt;br /&gt;
* Version 4.5.1&lt;br /&gt;
* Version 4.4&lt;br /&gt;
* Version 4.3&lt;br /&gt;
* Version 4.2&lt;br /&gt;
* Version 4.1.1&lt;br /&gt;
* Version 4.1&lt;br /&gt;
* Version 4.0&lt;br /&gt;
* Version 3.4.1&lt;br /&gt;
* Version 3.3&lt;br /&gt;
* Version 3.2&lt;br /&gt;
&lt;br /&gt;
== DEPENDENCIES ==&lt;br /&gt;
&lt;br /&gt;
See when the different PATRIUS versions were released and what JAVA version each is compatible with [[Patrius_Versions_and_Dependencies|here]]&lt;br /&gt;
&lt;br /&gt;
== JAVA DOC ==&lt;br /&gt;
&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.18 Current Java Doc]&lt;br /&gt;
&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.17 Java Doc 4.16]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.16 Java Doc 4.16]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.15 Java Doc 4.15]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.14 Java Doc 4.14]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.13 Java Doc 4.13]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.12 Java Doc 4.12]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.11 Java Doc 4.11]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.10.2 Java Doc 4.10.2]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.9.1 Java Doc 4.9.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.8 Java Doc 4.8]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.7 Java Doc 4.7]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.6.1 Java Doc 4.6.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.5.1 Java Doc 4.5.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.4 Java Doc 4.4]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.3 Java Doc 4.3]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.2 Java Doc 4.2]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.1.1 Java Doc 4.1.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.1 Java Doc 4.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V4.0 Java Doc 4.0]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V3.4.1 Java Doc 3.4.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V3.3 Java Doc 3.3]&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://patrius.cnes.fr/images/upload/JavaDocs/V3.2 Java Doc 3.2]&amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Main_differences_between_V4.18_and_V4.17&amp;diff=4179</id>
		<title>Main differences between V4.18 and V4.17</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Main_differences_between_V4.18_and_V4.17&amp;diff=4179"/>
		<updated>2026-06-10T14:04:05Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; V4.18 is a major release adding some new features and correcting some bugs.&lt;br /&gt;
&lt;br /&gt;
== New functionalities ==&lt;br /&gt;
* Added a new atmospheric model NRLMSIS 2.0, in addition from the existing NRLMSIS 1.0 model. The solar flux and geomagnetic activity inputs are the same for both versions of the MSIS models. Note that the FORTRAN reference model excludes the NO (Nitric Oxide) element. The same applies to the implemented model in PATRIUS, as it is based on the reference model. Other elements (He, O, N2, etc.), as well as pressure and temperature, are however taken into account.&lt;br /&gt;
&lt;br /&gt;
* Added to the ThirdBodyAttraction constructors the ability to provide a specific gravity model for the indirect terms. If none is provided, the gravity model already supplied for the third-body attraction calculation is used to compute the indirect terms (backward compatibility). To disable the computation of indirect terms, a gravity model that does not include harmonics must be provided.&lt;br /&gt;
* Added a service to the ApparentRadiusProvider interface to calculate the maximum apparent radius of a body as seen by a satellite. This radius, expressed in meters, corresponds to the maximum distance from the body&#039;s center to any point on its surface belonging to the limb ellipse (contour ellipse) viewed by the satellite.&lt;br /&gt;
* Added new constructors to the ModelFunction class to enable the optimization of various function types: ℝⁿ → ℝ : MultivariateFunction, ℝ → ℝ : UnivariateFunction and ℝ → ℝⁿ : UnivariateVectorFunction.&lt;br /&gt;
* Added support of the method StrictLegsSequence#addAll&lt;br /&gt;
* Added systematic acceleration calculation in BSP ephemerides (previously not calculated at all) via Chebyshev polynomial expansion. No regression expected on positions and velocities.&lt;br /&gt;
* Added a class SafetyMarginDetector to detect escape limits crossings. User can choose between two methods to compute escape limit: either at the satellite position or at the orbit’s pericenter.&lt;br /&gt;
* New AstronomicalNightDetector detector allowing to find for astronomical dawn and dusk events (independent of the actual spacecraft state).&lt;br /&gt;
* Improved matrix toString display: Systematic display of row x column dimensions and large/small numbers are shown in scientific notation without numerical approximation for computing formats (JAVA, OCTAVE, SCILAB and NUMPY).&lt;br /&gt;
* Added support for the Alpha-5 TLE numbering format, extending the range of supported satellite catalog numbers from [0; 99,999] to [0; 339,999].&lt;br /&gt;
* Fixed excessive memory consumption in detectors inheriting from &amp;lt;code&amp;gt;AbstractSignalPropagationDetector&amp;lt;/code&amp;gt;. This issue occurred when detecting a large number of events, particularly during long propagation analyses. Implementing date caching, fully transparent to the user, resolves this issue.&lt;br /&gt;
&lt;br /&gt;
== Bugs fixes ==&lt;br /&gt;
* In BSPEphemerisLoader, fix the TDB offset extraction by applying a “/ 1000” conversion, fix an error message that could lead to an infinite loop, update the getTDBModel() method so it can be called directly without having to call before the loadCelestialBodyEphemeris method.&lt;br /&gt;
* Fix the method FacetBodyShape#getIntersectionPoint which was using a line defined in the wrong coordinate system to compute the closest triangles.&lt;br /&gt;
* Fix for reading .bsp files when the binary file format is not declared at the correct index (more robust DafHandleManager method).&lt;br /&gt;
* Correction in the AbstractEllipsoidBodyShape#getApparentRadiusDirection method: using the observer&#039;s PVCoordinatesProvider instead of the body&#039;s (this) as the origin for the first direction vector. This incorrect behavior had an impact when the input direction depended on the observer&#039;s trajectory (for example, with a VelocityDirection linked to the observing satellite).&lt;br /&gt;
* Added a cache system to store and manage the “other dates” in AbstractSignalPropagationDetector instead of storing them indefinitely in a Map, which could cause large memory consumption during long propagations.&lt;br /&gt;
* Added validation checks during orbital parameter construction to prevent the creation of physically inconsistent ApsisOrbit, EquatorialOrbit, or KeplerianOrbit objects:&lt;br /&gt;
** KeplerianParameters / EquatorialParameters: the condition “e &amp;gt;= 0” must be satisfied&lt;br /&gt;
** ApsisAltitudeParameters / ApsisRadiusParameters: the condition “periapsis &amp;gt; 0” must be satisfied&lt;br /&gt;
* Fixed an issue related to the static initialization of certain dates from the TDB time scale (which is user-configurable). These dates are now dynamically initialized within the constructors of the affected classes: &amp;lt;code&amp;gt;UserIAUPole&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;BSPEphemerisLoader&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;PosVelChebyshev&amp;lt;/code&amp;gt;. As a result, the user must configure the desired TDB scale before instantiating these classes.&lt;br /&gt;
* Fixed an error message returned by orbital parameters that could indicate an incorrect class name.&lt;br /&gt;
* Fixed the nomenclature of the VacuumSignalPropagationModel.ConvergenceAlgorithm.FIXE_POINT enum, which has been renamed to FIXED_POINT.&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Main_differences_between_V4.18_and_V4.17&amp;diff=4178</id>
		<title>Main differences between V4.18 and V4.17</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Main_differences_between_V4.18_and_V4.17&amp;diff=4178"/>
		<updated>2026-06-10T13:17:43Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; V4.18 is a major release adding some new features and correcting some bugs.&lt;br /&gt;
&lt;br /&gt;
== New functionalities ==&lt;br /&gt;
* Added a new atmospheric model NRLMSIS 2.0, in addition from the existing NRLMSIS 1.0 model. The solar flux and geomagnetic activity inputs are the same for both versions of the MSIS models. Note that the FORTRAN reference model excludes the NO (Nitric Oxide) element. The same applies to the implemented model in PATRIUS, as it is based on the reference model. Other elements (He, O, N2, etc.), as well as pressure and temperature, are however taken into account.&lt;br /&gt;
&lt;br /&gt;
* Added to the ThirdBodyAttraction constructors the ability to provide a specific gravity model for the indirect terms. If none is provided, the gravity model already supplied for the third-body attraction calculation is used to compute the indirect terms (backward compatibility). To disable the computation of indirect terms, a gravity model that does not include harmonics must be provided.&lt;br /&gt;
* Added a service to the ApparentRadiusProvider interface to calculate the maximum apparent radius of a body as seen by a satellite. This radius, expressed in meters, corresponds to the maximum distance from the body&#039;s center to any point on its surface belonging to the limb ellipse (contour ellipse) viewed by the satellite.&lt;br /&gt;
* Added new constructors to the ModelFunction class to enable the optimization of various function types: ℝⁿ → ℝ : MultivariateFunction, ℝ → ℝ : UnivariateFunction and ℝ → ℝⁿ : UnivariateVectorFunction.&lt;br /&gt;
* Added support of the method StrictLegsSequence#addAll&lt;br /&gt;
* Added systematic acceleration calculation in BSP ephemerides (previously not calculated at all) via Chebyshev polynomial expansion. No regression expected on positions and velocities.&lt;br /&gt;
* Added a class SafetyMarginDetector to detect escape limits crossings. User can choose between two methods to compute escape limit: either at the satellite position or at the orbit’s pericenter.&lt;br /&gt;
* New AstronomicalNightDetector detector allowing to find for astronomical dawn and dusk events (independent of the actual spacecraft state).&lt;br /&gt;
* Improved matrix toString display: Systematic display of row x column dimensions and large/small numbers are shown in scientific notation without numerical approximation for computing formats (JAVA, OCTAVE, SCILAB and NUMPY).&lt;br /&gt;
* Added support for the Alpha-5 TLE numbering format, extending the range of supported satellite catalog numbers from [0; 99,999] to [0; 339,999].&lt;br /&gt;
* Fixed excessive memory consumption in detectors inheriting from &amp;lt;code&amp;gt;AbstractSignalPropagationDetector&amp;lt;/code&amp;gt;. This issue occurred when detecting a large number of events, particularly during long propagation analyses. Implementing date caching, fully transparent to the user, resolves this issue.&lt;br /&gt;
&lt;br /&gt;
== Bugs fixes ==&lt;br /&gt;
* In BSPEphemerisLoader, fix the TDB offset extraction by applying a “/ 1000” conversion, fix an error message that could lead to an infinite loop, update the getTDBModel() method so it can be called directly without having to call before the loadCelestialBodyEphemeris method.&lt;br /&gt;
* Fix the method FacetBodyShape#getIntersectionPoint which was using a line defined in the wrong coordinate system to compute the closest triangles.&lt;br /&gt;
* Fix for reading .bsp files when the binary file format is not declared at the correct index (more robust DafHandleManager method).&lt;br /&gt;
* Correction in the AbstractEllipsoidBodyShape#getApparentRadiusDirection method: using the observer&#039;s PVCoordinatesProvider instead of the body&#039;s (this) as the origin for the first direction vector. This incorrect behavior had an impact when the input direction depended on the observer&#039;s trajectory (for example, with a VelocityDirection linked to the observing satellite).&lt;br /&gt;
* Added a cache system to store and manage the “other dates” in AbstractSignalPropagationDetector instead of storing them indefinitely in a Map, which could cause large memory consumption during long propagations.&lt;br /&gt;
* Added validation checks during orbital parameter construction to prevent the creation of physically inconsistent ApsisOrbit, EquatorialOrbit, or KeplerianOrbit objects:&lt;br /&gt;
** KeplerianParameters / EquatorialParameters: the condition “e &amp;gt;= 0” must be satisfied&lt;br /&gt;
** ApsisAltitudeParameters / ApsisRadiusParameters: the condition “periapsis &amp;gt; 0” must be satisfied&lt;br /&gt;
* Fixed an issue related to the static initialization of certain dates from the TDB time scale (which is user-configurable). These dates are now dynamically initialized within the constructors of the affected classes: &amp;lt;code&amp;gt;UserIAUPole&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;BSPEphemerisLoader&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;PosVelChebyshev&amp;lt;/code&amp;gt;. As a result, the user must configure the desired TDB scale before instantiating these classes.&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Main_differences_between_V4.18_and_V4.17&amp;diff=4177</id>
		<title>Main differences between V4.18 and V4.17</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Main_differences_between_V4.18_and_V4.17&amp;diff=4177"/>
		<updated>2026-06-10T13:02:38Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; V4.18 is a major release adding some new features and correcting some bugs.&lt;br /&gt;
&lt;br /&gt;
== New functionalities ==&lt;br /&gt;
* Added a new atmospheric model NRLMSIS 2.0, in addition from the existing NRLMSIS 1.0 model. The solar flux and geomagnetic activity inputs are the same for both versions of the MSIS models. Note that the FORTRAN reference model excludes the NO (Nitric Oxide) element. The same applies to the implemented model in PATRIUS, as it is based on the reference model. Other elements (He, O, N2, etc.), as well as pressure and temperature, are however taken into account.&lt;br /&gt;
&lt;br /&gt;
* Added to the ThirdBodyAttraction constructors the ability to provide a specific gravity model for the indirect terms. If none is provided, the gravity model already supplied for the third-body attraction calculation is used to compute the indirect terms (backward compatibility). To disable the computation of indirect terms, a gravity model that does not include harmonics must be provided.&lt;br /&gt;
* Added a service to the ApparentRadiusProvider interface to calculate the maximum apparent radius of a body as seen by a satellite. This radius, expressed in meters, corresponds to the maximum distance from the body&#039;s center to any point on its surface belonging to the limb ellipse (contour ellipse) viewed by the satellite.&lt;br /&gt;
* Added new constructors to the ModelFunction class to enable the optimization of various function types: ℝⁿ → ℝ : MultivariateFunction, ℝ → ℝ : UnivariateFunction and ℝ → ℝⁿ : UnivariateVectorFunction.&lt;br /&gt;
* Added support of the method StrictLegsSequence#addAll&lt;br /&gt;
* Added systematic acceleration calculation in BSP ephemerides (previously not calculated at all) via Chebyshev polynomial expansion. No regression expected on positions and velocities.&lt;br /&gt;
* Added a class SafetyMarginDetector to detect escape limits crossings. User can choose between two methods to compute escape limit: either at the satellite position or at the orbit’s pericenter.&lt;br /&gt;
* Allows the user to configure the desired TDB time scale prior to instantiating UserIAUPole, BSPEphemerisLoader, and PosVelChebyshev objects. Dates are initialized within their respective constructors based on this TDB scale, rather than being handled in a static way.&lt;br /&gt;
* New AstronomicalNightDetector detector allowing to find for astronomical dawn and dusk events (independent of the actual spacecraft state).&lt;br /&gt;
* Improved matrix toString display: Systematic display of row x column dimensions and large/small numbers are shown in scientific notation without numerical approximation for computing formats (JAVA, OCTAVE, SCILAB and NUMPY).&lt;br /&gt;
* Added support for the Alpha-5 TLE numbering format, extending the range of supported satellite catalog numbers from [0; 99,999] to [0; 339,999].&lt;br /&gt;
* Fixed excessive memory consumption in detectors inheriting from &amp;lt;code&amp;gt;AbstractSignalPropagationDetector&amp;lt;/code&amp;gt;. This issue occurred when detecting a large number of events, particularly during long propagation analyses. Implementing date caching, fully transparent to the user, resolves this issue.&lt;br /&gt;
&lt;br /&gt;
== Bugs fixes ==&lt;br /&gt;
* In BSPEphemerisLoader, fix the TDB offset extraction by applying a “/ 1000” conversion, fix an error message that could lead to an infinite loop, update the getTDBModel() method so it can be called directly without having to call before the loadCelestialBodyEphemeris method.&lt;br /&gt;
* Fix the method FacetBodyShape#getIntersectionPoint which was using a line defined in the wrong coordinate system to compute the closest triangles.&lt;br /&gt;
* Fix for reading .bsp files when the binary file format is not declared at the correct index (more robust DafHandleManager method).&lt;br /&gt;
* Correction in the AbstractEllipsoidBodyShape#getApparentRadiusDirection method: using the observer&#039;s PVCoordinatesProvider instead of the body&#039;s (this) as the origin for the first direction vector. This incorrect behavior had an impact when the input direction depended on the observer&#039;s trajectory (for example, with a VelocityDirection linked to the observing satellite).&lt;br /&gt;
* Added a cache system to store and manage the “other dates” in AbstractSignalPropagationDetector instead of storing them indefinitely in a Map, which could cause large memory consumption during long propagations.&lt;br /&gt;
* Added validation checks during orbital parameter construction to prevent the creation of physically inconsistent ApsisOrbit, EquatorialOrbit, or KeplerianOrbit objects.&lt;br /&gt;
** KeplerianParameters / EquatorialParameters: the condition “e &amp;gt;= 0” must be satisfied&lt;br /&gt;
** ApsisAltitudeParameters / ApsisRadiusParameters: the condition “periapsis &amp;gt; 0” must be satisfied&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.18&amp;diff=4176</id>
		<title>Catégorie:Tutorials 4.18</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.18&amp;diff=4176"/>
		<updated>2026-06-10T11:02:12Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « [https://github.com/CNES/patrius-tutorials/tree/patrius-4.18 Tutorials PATRIUS 4.18]   The tutorials for PATRIUS v4.18 can now be found on the [https://github.com/CNES/patrius-tutorials/tree/patrius-4.18 CNES&amp;#039; GitHub page] »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://github.com/CNES/patrius-tutorials/tree/patrius-4.18 Tutorials PATRIUS 4.18]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The tutorials for PATRIUS v4.18 can now be found on the [https://github.com/CNES/patrius-tutorials/tree/patrius-4.18 CNES&#039; GitHub page]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.17&amp;diff=4175</id>
		<title>Catégorie:Tutorials 4.17</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.17&amp;diff=4175"/>
		<updated>2026-06-10T11:01:28Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « [https://github.com/CNES/patrius-tutorials/tree/patrius-4.17 Tutorials PATRIUS 4.17]   The tutorials for PATRIUS v4.17 can now be found on the [https://github.com/CNES/patrius-tutorials/tree/patrius-4.17 CNES&amp;#039; GitHub page] »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://github.com/CNES/patrius-tutorials/tree/patrius-4.17 Tutorials PATRIUS 4.17]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The tutorials for PATRIUS v4.17 can now be found on the [https://github.com/CNES/patrius-tutorials/tree/patrius-4.17 CNES&#039; GitHub page]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Events:_orbital&amp;diff=4174</id>
		<title>User Manual 4.18 Events: orbital</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Events:_orbital&amp;diff=4174"/>
		<updated>2026-06-10T10:59:55Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
Here are presented all the events detectors of the theme &amp;quot;orbital&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
Those event detectors are available in the packages :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detecors/package-summary.html Package fr.cnes.sirius.patrius.events.detectors]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Detectors ===&lt;br /&gt;
This section describes the meaning of the g switching function for the &amp;quot;orbital&amp;quot; event detectors, and their particularities :&lt;br /&gt;
&lt;br /&gt;
==== Alignment Detector ====&lt;br /&gt;
&lt;br /&gt;
This detector computes the difference &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; between the alignment angle &amp;lt;math&amp;gt;\beta_{threshold}&amp;lt;/math&amp;gt; and the angle between the satellite position, the central body and the second body position projection in the orbital plane.&amp;lt;br&amp;gt;&lt;br /&gt;
If &amp;lt;math&amp;gt;\theta_1 =-\pi - \theta&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\theta_2 = \pi - \theta&amp;lt;/math&amp;gt;, the g switching function will be:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\theta_1&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;\theta &amp;lt; \theta_1&amp;lt;/math&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;\theta &amp;lt; \theta_2&amp;lt;/math&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
and &amp;lt;math&amp;gt;\theta_2&amp;lt;/math&amp;gt; otherwise.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{threshold}&amp;lt;/math&amp;gt; is an oriented angle and is positive when is oriented as the orbital momentum.&lt;br /&gt;
&lt;br /&gt;
[[File:alignmentDetector.png|750x400px]]&lt;br /&gt;
&lt;br /&gt;
Axes &amp;lt;math&amp;gt;\vec a&amp;lt;/math&amp;gt; (satellite normalized position) and &amp;lt;math&amp;gt;\vec b&amp;lt;/math&amp;gt; (satellite normalized velocity) are transformed into axes &amp;lt;math&amp;gt;\vec x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec y&amp;lt;/math&amp;gt; knowing the value of &amp;lt;math&amp;gt;\beta_{threshold}&amp;lt;/math&amp;gt; angle; g is found projecting the target body position in the orbital plane and computing its &amp;lt;math&amp;gt;\vec x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec y&amp;lt;/math&amp;gt; components.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; target body projection is in the half-plane &amp;lt;math&amp;gt;y&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; target body projection is in the half-plane &amp;lt;math&amp;gt;y&amp;lt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; target body projection belongs to the straight line &amp;lt;math&amp;gt;y=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Altitude Detector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function measures the difference between the current altitude &amp;lt;math&amp;gt;h_{sat}&amp;lt;/math&amp;gt; and the threshold altitude &amp;lt;math&amp;gt;h_{thr}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g &amp;gt; 0 : h_{sat} &amp;gt; h_{thr}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 : h_{sat} &amp;lt; h_{thr}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ApsideDetector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function is the dot product of the satellite position and velocity vectors: &amp;lt;math&amp;gt;g =\vec p \cdot \vec v&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; the satellite is in the half-orbit from perigee to apogee;&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; the satellite is in the half-orbit from apogee to perigee.&lt;br /&gt;
&lt;br /&gt;
[[File:apside.png|center|539x316px]]&lt;br /&gt;
&lt;br /&gt;
==== DateDetector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function is the value of the difference between the current date and the target date. If no event dates have been added i.e. if no target dates have been initialized, &amp;lt;math&amp;gt;g=-1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== RelativeDateDetector ====&lt;br /&gt;
This detector extends of DateDetector. The g switching function is the same as the  [[#DateDetector|DateDetector]].&lt;br /&gt;
&lt;br /&gt;
==== EclipseDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector is in charge of the umbra/penumbra eclipse events detection.&amp;lt;br&amp;gt;&lt;br /&gt;
Different features are available:&lt;br /&gt;
* the occulted and occulting bodies are both spherical;&lt;br /&gt;
* the occulted body is a direction;&lt;br /&gt;
* the occulting body has an ellipsoid shape.&lt;br /&gt;
&lt;br /&gt;
In addition to that, the &amp;lt;code&amp;gt;EclipseDetector&amp;lt;/code&amp;gt; can detect eclipse events based on a threshold lighting ratio &amp;lt;math&amp;gt;\epsilon_{0}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;0&amp;lt;=\epsilon_{0}&amp;lt;=1&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
When &amp;lt;math&amp;gt;\epsilon_{0}=0&amp;lt;/math&amp;gt;, an eclipse event is triggered only if whole occulted body is hidden by the occulting body (total eclipse); when &amp;lt;math&amp;gt;\epsilon_{0}=1&amp;lt;/math&amp;gt;, an event is immediately triggered when the occulted body is partially hidden (penumbra eclipse).&amp;lt;br&amp;gt;&lt;br /&gt;
As a general rule, the lighting ratio is equal to:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\epsilon = 1-\frac{A_{occulted}}{\pi r_{occulted}^2}&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
where &amp;lt;math&amp;gt;r_{occulted}&amp;lt;/math&amp;gt; is the apparent radius of the occulted body. &amp;lt;br&amp;gt;&lt;br /&gt;
The g function is: &amp;lt;math&amp;gt;g=\epsilon_{0}-\epsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The g switching function computation needs the satellite position vector (&amp;lt;math&amp;gt;\vec P_{sat}&amp;lt;/math&amp;gt;), the occulted body (&amp;lt;math&amp;gt;\vec P_{ted}&amp;lt;/math&amp;gt;) and occulting body (&amp;lt;math&amp;gt;\vec P_{ing}&amp;lt;/math&amp;gt;) position vectors.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\vec {PS}=\vec {P_{ted}}-\vec {P_{sat}}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;sin(\widehat{rs})=\dfrac{r_{ted}}{|\vec {PS}|}&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\vec {PO}=\vec {P_{ing}}-\vec {P_{sat}}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;sin(\widehat{ro})=\dfrac{r_{ing}}{|\vec {PO}|}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; is the angle between &amp;lt;math&amp;gt;\vec {PS}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec {PO}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Distinction is made between total eclipse and partial eclipse.&amp;lt;br&amp;gt;&lt;br /&gt;
The following diagrams show the evolution of the g function value for an eclipse scenario with two spherical bodies. &lt;br /&gt;
&lt;br /&gt;
===== Total eclipse =====&lt;br /&gt;
&lt;br /&gt;
The passage to umbra is detected. The g switching function is &amp;lt;math&amp;gt;g = \alpha- \widehat{ro} + \widehat{rs}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; satellite is not in eclipse:&lt;br /&gt;
[[File:eclipse1.png|576x274px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; beginning of umbra:&lt;br /&gt;
[[File:eclipse2.png|570x161px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; umbra:&lt;br /&gt;
[[File:eclipse3.png|574x180px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; end of umbra:&lt;br /&gt;
[[File:eclipse4.png|570x182px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; satellite is not in eclipse:&lt;br /&gt;
[[File:eclipse5.png|588x264px]]&lt;br /&gt;
&lt;br /&gt;
===== Partial eclipse =====&lt;br /&gt;
&lt;br /&gt;
The passage to penumbra is detected. The g switching function is &amp;lt;math&amp;gt;g = \alpha- \widehat {ro} - \widehat {rs}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; satellite is not in eclipse:&lt;br /&gt;
[[File:eclipse6.png|566x273px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; beginning of penumbra:&lt;br /&gt;
[[File:eclipse7.png|552x198px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; penumbra:&lt;br /&gt;
[[File:eclipse8.png|581x178px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; end of penumbra:&lt;br /&gt;
[[File:eclipse9.png|578x217px]]&lt;br /&gt;
&lt;br /&gt;
Another feature of the &amp;lt;code&amp;gt;EclipseDetector&amp;lt;/code&amp;gt; is the detection of partial and total eclipse by a spheroid.&lt;br /&gt;
&lt;br /&gt;
[[File:ellipsoideclipse.png|center]]&lt;br /&gt;
&lt;br /&gt;
The point on the horizon (H) is calculated as the point of the ellipsoid that is in the same plane as A, C and S (respectively center of occulted body, center of occulting body and satellite). The distance of H to the center C of the ellipsoid is then projected onto a plane orthogonal to the Satellite / Occulting (SA) body direction, and the resulting length is considered as the radius of an &amp;quot;apparent&amp;quot; sphere representing the occulting body. The partial and total eclipse are then computed as per above.&lt;br /&gt;
&lt;br /&gt;
===== Particular case =====&lt;br /&gt;
&lt;br /&gt;
A specific case is having a spacecraft lower than the occulting body radius (i.e. spacecraft altitude &amp;lt; occulting body radius).&amp;lt;br&amp;gt;&lt;br /&gt;
Two cases are possible:&lt;br /&gt;
* The satellite is behind the occulted body (angle occulted body- occulting body - satellite &amp;gt; Pi/2): satellite is considered to be in total eclipse.&lt;br /&gt;
* The satellite is in front of the occulted body (angle occulted body- occulting body - satellite &amp;lt;= Pi/2): apparent radius of occulting body cannot be computed. Hence it is considered to be equal to Pi/2 (slight approximation since it means satellite is considered to be lying exactly on the surface of the occulting body). Then usual computation of g function applies.&lt;br /&gt;
&lt;br /&gt;
==== BodyInEclipseDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector is in charge of the umbra/penumbra eclipse events detection for a non-point target body. 3 bodies are considered to compute the BodyInEclipse events:&lt;br /&gt;
&lt;br /&gt;
*Target body: body on which the eclipse events are to be detected.&lt;br /&gt;
&lt;br /&gt;
*Occulted body: this is the body that is no longer visible from the target body due to the presence of the occulting body in the line of sight (the occulted body is generally the sun).&lt;br /&gt;
&lt;br /&gt;
*Occulting body: body that causes the eclipse.&lt;br /&gt;
[[Fichier:BodyInEclipseDetector1.png|centré|683x683px]]&lt;br /&gt;
The following assumptions are made:&lt;br /&gt;
* The three bodies are considered spherical during calculations (the apparent radius of the bodies are used).&lt;br /&gt;
* For the cases where the target body is fully in eclipse, the target body must be much smaller than the possible irregularities of the occulting body to avoid false positives. (Further explanation of this point in the edge cases section).&lt;br /&gt;
* No atmospheric effect is taken into account.&lt;br /&gt;
*The propagation delay can be activated or not.&lt;br /&gt;
&lt;br /&gt;
The core of the algorithm consists of selecting a point on the surface of the target that is representative of the surface of the target as a whole, and then calculating the illumination rate at that point. &lt;br /&gt;
&lt;br /&gt;
The calculation of g is therefore done in three steps:&lt;br /&gt;
*Selection of the reference point: This depends on the type of eclipse targeted (partial or total; whether the body is completely eclipsed or not), the chosen model (complete or simplified), and the relative position of the bodies involved.&lt;br /&gt;
* Calculation of the illumination rate at the selected target point.&lt;br /&gt;
*Comparison of the obtained illumination rate with the target illumination rate (0 if we are looking for total eclipses, 1 if we are looking for partial eclipses).&lt;br /&gt;
2 modes are available for the computation of eclipse events:&lt;br /&gt;
&lt;br /&gt;
1.   Exact model: &lt;br /&gt;
&lt;br /&gt;
In this model, the occulted body is considered as non-punctual. 4 points are of interest to detect the eclipse events: &lt;br /&gt;
*H&amp;lt;sub&amp;gt;PPU&amp;lt;/sub&amp;gt; = point of interest for entry partially in penumbra&lt;br /&gt;
*H&amp;lt;sub&amp;gt;PU&amp;lt;/sub&amp;gt; = point of interest for entry partially in umbra&lt;br /&gt;
* H&amp;lt;sub&amp;gt;TPU&amp;lt;/sub&amp;gt; = point of interest for entry totally in penumbra&lt;br /&gt;
*H&amp;lt;sub&amp;gt;TU&amp;lt;/sub&amp;gt; = point of interest for entry totally in umbra&lt;br /&gt;
[[Fichier:BodyInEclipseDetector2.png|centré|776x776px]]&lt;br /&gt;
2.   Approximative model&lt;br /&gt;
&lt;br /&gt;
In this model, the occulted body is considered as punctual. In this case, only 2 interest points exists to detect eclipse events:  &lt;br /&gt;
*H&amp;lt;sub&amp;gt;P&amp;lt;/sub&amp;gt; = point of interest for entry partially in eclipse&lt;br /&gt;
*H&amp;lt;sub&amp;gt;T&amp;lt;/sub&amp;gt; = point of interest for entry totally in eclipse&lt;br /&gt;
[[Fichier:BodyInEclipseDetector3.png|centré|771x771px]]&lt;br /&gt;
For any of the models, the lighting ratio of the corresponding interest points is computed to detect the events.&lt;br /&gt;
&lt;br /&gt;
The lighting ratio is then compared against the target lighting ratio (0 if we want to detect total eclipses and 1 for partial eclipses), and the value of the g function (switching function) is returned for a given date. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Edge Cases:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Occulting body &amp;lt;&amp;lt; Target Body:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
If the occulting body is smaller than the target body, it might happen that none of the 4 points of interest is in eclipse, however the target body is partially in eclipse as shown in the figure below:&lt;br /&gt;
[[Fichier:BodyInEclipseDetector4.png|centré|806x806px]]&lt;br /&gt;
This case is possible only if the line SA intersects the target body. In this case, none of the interest points of the exact model or of the approximative model are used to compute the lighting ratio. In this case it is the intersection point H&amp;lt;sub&amp;gt;C&amp;lt;/sub&amp;gt; that is used to compute the lighting ratio (to know if it is inside umbra or only inside penumbra).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Shape of occulting body non spherical:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In the hypotheses section it was said that the 3 bodies are considered spherical. However, it is really only the occulted and the target bodies that have to be spherical. The occulting body might have any other shape. It is during the computation that we model the occulting body as spherical by using the getApparentRadius method. &lt;br /&gt;
&lt;br /&gt;
In certain edge cases, a BodyInEclipse event might be raised by the propagator, even though this is not actually the case. This type of situation can occur when the occulting body is elongated in the direction of the plane of the eclipse. &lt;br /&gt;
[[Fichier:BodyInEclipseDetector5.png|centré]]&lt;br /&gt;
The calculation method considers a planar projection of the problem. When an object is detected as &amp;quot;completely in the shadow&amp;quot; of another, it is ensured that the furthest point of the eclipse cone in the plane containing the centers of the three objects is in eclipse. This guarantees that all points of the target object belonging to this plane are in eclipse. However, there is no guarantee for points outside of the plane. This is not an issue when the obscuring object is spherical, but it can become one when it is elongated. In the example below, the target is considered &amp;quot;entirely&amp;quot; eclipsed by the detector, even though some points are illuminated. &lt;br /&gt;
&lt;br /&gt;
This type of case is unlikely to occur in the Earth-Moon scenario, where the obscuring body is very close to a sphere, but it is not impossible in the case of asteroids, which have non-regular shapes. Other problems of this kind can arise when the body is not convex, but such cases become extremely rare.&lt;br /&gt;
&lt;br /&gt;
This is why for the cases where the target body is fully in eclipse, the target body must be much smaller than the possible irregularities of the occulting body to avoid false positives.&lt;br /&gt;
&lt;br /&gt;
==== PlaneCrossingDetector ====&lt;br /&gt;
The detector allows to detect if a spacecraft crosses a plane defined in a specific reference frame. The following entries are needed to define a &amp;lt;code&amp;gt;PlaneCrossingDetector&amp;lt;/code&amp;gt;:&lt;br /&gt;
*plane reference frame ;&lt;br /&gt;
*point which is contained in the plane ;&lt;br /&gt;
* normal vector to plane.&lt;br /&gt;
&lt;br /&gt;
The detection function &amp;lt;math&amp;gt;g()&amp;lt;/math&amp;gt; monitors the dot product between the normal vector to plane and the distance position vector of the spacecraft with respect to the origin of the point of the plan:&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt;the satellite is over the plane;&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt;the satellite is under the plane.&lt;br /&gt;
&lt;br /&gt;
==== NodeDetector ====&lt;br /&gt;
The &amp;lt;code&amp;gt;NodeDetector&amp;lt;/code&amp;gt; detects the orbital nodes; the user can choose what the detect (ascending nodes, descending nodes or both) through the &amp;lt;code&amp;gt;slopeSelection &amp;lt;/code&amp;gt; parameter. It is a particular application case of the &amp;lt;code&amp;gt;PlaneCrossingDetector&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
The g switching function returns the Z component of the satellite position in the geocentric frame:&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt;the satellite is over the equatorial plane (in its orbit from ascending node to descending node);&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt;the satellite is under the equatorial plane (in its orbit from descending node to ascending node).&lt;br /&gt;
&lt;br /&gt;
==== DistanceDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;DistanceDetector &amp;lt;/code&amp;gt; detects the time when the distance between the spacecraft and a point of space reaches a given value.&lt;br /&gt;
&lt;br /&gt;
The point of space is given as a &amp;lt;code&amp;gt;PVcoordinatesProvider&amp;lt;/code&amp;gt; : it can be either a celestial body (as a &amp;lt;code&amp;gt;CelestialBody&amp;lt;/code&amp;gt;), a point at the surface of a body (as a &amp;lt;code&amp;gt;TopocentricFrame&amp;lt;/code&amp;gt;), or any another class that implements that interface.&lt;br /&gt;
&lt;br /&gt;
Here is the example for a point on the surface of a body :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// earth shape&lt;br /&gt;
final BodyShape earth = new OneAxisEllipsoid(earthRadius, ea, ITRFFrame);&lt;br /&gt;
&lt;br /&gt;
// considered point&lt;br /&gt;
final EllipsoidPoint point = new EllipsoidPoint(ellipsoid, LLHCoordinatesSystem.ELLIPSODETIC, latitude, longitude, altitude, &amp;quot;point &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// associated topocentric frame : this object is a PVCoordinatesProvider&lt;br /&gt;
final TopocentricFrame topoFramePoint = new TopocentricFrame(point, &amp;quot;Gstation&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// detector&lt;br /&gt;
final DistanceDetector detector = new DistanceDetector(topoFramePoint, distance);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Its g switching function computes the difference between the spacecraft position and the point position (in the same frame), and then subtracts the given distance from its norm. &lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt;the distance spacecraft/point is bigger than the distance threshold value;&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt;the distance spacecraft/point is smaller than the distance threshold value;&lt;br /&gt;
&lt;br /&gt;
==== ExtremaDistanceDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaDistanceDetector&amp;lt;/code&amp;gt; detects if the spacecraft is at a local extremum for the distance relative to a point of space, defined the same way as in the previous DistanceDetector. The choice of the extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;distanceType&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the square norm of the velocity for the vector representing this distance, thus the sign change is indeed a local extremum. &lt;br /&gt;
&lt;br /&gt;
==== ExtremaLatitudeDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaLatitudeDetector&amp;lt;/code&amp;gt; detects if the spacecraft is at a local extremum for the geodetic latitude. The choice of the extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;latitudeType&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the z-component of the spacecraft velocity in the orbit definition frame.&lt;br /&gt;
&lt;br /&gt;
==== LatitudeDetector ====&lt;br /&gt;
The &amp;lt;code&amp;gt;LatitudeDetector&amp;lt;/code&amp;gt; detects the time when the spacecraft reaches a given geodetic latitude, the &amp;lt;code&amp;gt;BodyShape&amp;lt;/code&amp;gt; of the earth being known to compute it.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the difference between the current latitude and the one to detect.&lt;br /&gt;
&lt;br /&gt;
==== ExtremaLongitudeDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaLongitudeDetector&amp;lt;/code&amp;gt; detects if the spacecraft is at a local extremum for the longitude. The choice of the extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;extremumType&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
The g switching function is the dot vector of the position with the result of the cross product of the velocity relative to the body and unitary vector Z :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g =\vec P \cdot (\vec Vrel \wedge \vec Vz)&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The main part of this function is the cross product which switches when the relative velocity is colinear to Z.&lt;br /&gt;
&lt;br /&gt;
==== LongitudeDetector ====&lt;br /&gt;
The &amp;lt;code&amp;gt;LongitudeDetector&amp;lt;/code&amp;gt; detects the time when the spacecraft reaches a given longitude.&lt;br /&gt;
&lt;br /&gt;
Working with longitude always gives a problem of continuity when longitude pass from PI rad to- PI rad. The best solution find to avoid this is to save some information from the last computation of the g function. &lt;br /&gt;
&lt;br /&gt;
In this way the g function is the following difference expressed between-PI rad and PI rad : currentLongitude - longitudeToDetect&lt;br /&gt;
&lt;br /&gt;
At each g function call, this difference is saved, and each time the difference between the current difference and the last difference is greater than PI rad, it means there is a discontinuity, the g fonction is opposed. This avoids discontinuity. Then all zero are detected.&lt;br /&gt;
&lt;br /&gt;
This solution, also avoids problem about detecting a longitude at PI rad further (that we meet with a sin(a- b) g function).&lt;br /&gt;
&lt;br /&gt;
==== Safety Margin Detector ====&lt;br /&gt;
&lt;br /&gt;
This detector computes the safety margin ∆ with respect to the escape velocity. Users have the choice between two methods for the safety margin computation:&lt;br /&gt;
* INSTANTANEOUS: The safety margin is computed using the spacecraft&#039;s current velocity v and the escape velocity v_esc evaluated at the satellite&#039;s current position (v_esc=√(2μ/r)): ∆ = v/v_esc-1&lt;br /&gt;
* PERICENTRE: The safety margin is computed at the orbit&#039;s pericenter (where the satellite speed is maximum) using the orbital eccentricity e: ∆ = √((1+e)/2)-1&lt;br /&gt;
&lt;br /&gt;
Note: For circular orbits (e=0 and v=√(μ/r)), both methods are equivalent and yield ∆ = 1/√2-1.&lt;br /&gt;
&lt;br /&gt;
The g switching function is the difference between the computed safety margin ∆ and a user-defined safety margin threshold t (safetyMarginIn): g = ∆-t&lt;br /&gt;
&lt;br /&gt;
==== AOLDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;AOLDetector&amp;lt;/code&amp;gt; detects when the spacecraft reaches a predetermined argument of latitude (true, mean or eccentric supportes) with respect to a given equator ; the argument of latitude is the angle between the spacecraft position and the ascending node.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the sinus of the difference between the spacecraft current angular position &amp;lt;math&amp;gt;\beta&amp;lt;/math&amp;gt; and the threshold position value &amp;lt;math&amp;gt;\beta_{input}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g=sin(\beta- \beta_{input})&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
An AOL event is triggered only if the g-function slope is positive at its zero.&lt;br /&gt;
&lt;br /&gt;
==== AnomalyDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;AnomalyDetector&amp;lt;/code&amp;gt; detects when the spacecraft reaches a predetermined anomaly; the anomaly is the angle between the spacecraft position and the perigee.&amp;lt;br&amp;gt;&lt;br /&gt;
Three types of anomaly can be detected: true, mean and eccentric anomaly.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the sinus of the difference between the spacecraft current anomaly and the threshold anomaly value:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g=sin(\alpha- \alpha_{input})&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
(This g function is identical to the AOLDetector g function).&amp;lt;br&amp;gt;&lt;br /&gt;
Like the &amp;lt;code&amp;gt;AOLDetector&amp;lt;/code&amp;gt;, an anomaly event is triggered only if the g-function slope is positive at its zero.&lt;br /&gt;
&lt;br /&gt;
Using precaution : This detector is unusable on a circular orbit where the perigee always moves very fast and in any way.&lt;br /&gt;
&lt;br /&gt;
==== ThreeBodiesAngleDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ThreeBodiesAngleDetector&amp;lt;/code&amp;gt; detects when the angle between three bodies (they can be celestial bodies, spacecrafts, ground stations, ...) is equal to a predetermined value.&amp;lt;br&amp;gt;&lt;br /&gt;
If &amp;lt;math&amp;gt;\vec{P_{1}}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\vec{P_{2}}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec{P_{3}}&amp;lt;/math&amp;gt; are the positions of the three bodies, and &amp;lt;math&amp;gt;\vec{P_{21}}&amp;lt;/math&amp;gt; is the difference &amp;lt;math&amp;gt;\vec{P_{2}}-\vec{P_{1}}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec{P_{23}}&amp;lt;/math&amp;gt; the difference &amp;lt;math&amp;gt;\vec{P_{2}}-\vec{P_{3}}&amp;lt;/math&amp;gt;, the computed angle will be: &amp;lt;math&amp;gt;\widehat{\vec{P_{21}} \vec{P_{23}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:threeBodies.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the difference between the current angle between the three bodies and the threshold angle. The threshold angle is not oriented and its value is between 0 and PI.&lt;br /&gt;
&lt;br /&gt;
==== ExtremaThreeBodiesAngleDetector ====&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaThreeBodiesAngleDetector&amp;lt;/code&amp;gt; detects when the angle between three bodies (defined the same way as in the &amp;lt;code&amp;gt;ThreeBodiesAngleDetector&amp;lt;/code&amp;gt;) reaches its minimal or maximal value.&amp;lt;br&amp;gt;&lt;br /&gt;
The choice of the detected extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;extremumType&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the derivative of the angle value (in fact, part of the derivative : a factor with a &lt;br /&gt;
constant sign has been ignored).&amp;lt;br&amp;gt;&lt;br /&gt;
This derivative is obtained by expressing all the positions and velocities of the two extreme points (&amp;lt;math&amp;gt;P_{1}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;P_{3}&amp;lt;/math&amp;gt;) in a frame linked to the one at the angle origin (&amp;lt;math&amp;gt;P_{2}&amp;lt;/math&amp;gt;).&amp;lt;br&amp;gt;&lt;br /&gt;
If the two vectors from the new origin are &amp;lt;math&amp;gt;\vec{P_{21}}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec{P_{23}}&amp;lt;/math&amp;gt; the angle expression is : &amp;lt;math&amp;gt;\arccos(\vec{P_{21}}.\vec{P_{23}} / (|\vec{P_{21}}|.|\vec{P_{23}}|))&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Once derivated as &amp;lt;math&amp;gt;(gof)&#039; = (g&#039;of).f&#039;&amp;lt;/math&amp;gt; and the &amp;lt;math&amp;gt;arccos&amp;lt;/math&amp;gt; derivative being always negative, the switching function is minus the derivative of the inner expression &amp;lt;math&amp;gt;\vec{P_{21}}.\vec{P_{23}} / (|\vec{P_{21}}|.|\vec{P_{23}}|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== BetaAngleDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;BetaAngleDetector&amp;lt;/code&amp;gt; detects when the beta angle reaches a predetermined value; the beta angle is the angle between the orbit plane and the vector to the Sun.&lt;br /&gt;
[[File:BetaAngle.png|center]]&lt;br /&gt;
&lt;br /&gt;
The beta angle belongs to [- π/2 , π/2 ]; its sign is positive when the Sun is in the half-plane containing the spacecraft&#039;s momentum.&lt;br /&gt;
&lt;br /&gt;
==== LocalTimeAngleDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;LocalTimeAngleDetector&amp;lt;/code&amp;gt; detects when the spacecraft local time is equal to a predetermined value; the spacecraft local time is the angle between the projections of the Earth-Sun vector and the Earth-spacecraft vector in the equatorial plane plus PI. In PATRIUS, local time is expressed as an angle in the range [-PI; PI[. Local time angle is PI (or 12.00h) when the geometric angle Sun-Earth-Spacecraft is 0 and 0 (or 0.00h) when this angle is PI.&amp;lt;br&amp;gt;&lt;br /&gt;
The local time is increasing for prograde orbits and decreasing for retrograde orbits. The events are detected in both cases.&lt;br /&gt;
&lt;br /&gt;
The g function is the following difference expressed between-PI rad and PI rad : &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;currentLocalTime- localTimeToDetect&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At each g function call, this difference is saved, and each time the difference between the current difference and the last difference is greater than PI rad, it means there is a discontinuity, the g fonction is opposed. This avoids discontinuity. Then all zero are detected.&lt;br /&gt;
&lt;br /&gt;
This solution, also avoids problem about detecting a local time at PI rad further (that we meet with a sin(a- b) g function).&lt;br /&gt;
&lt;br /&gt;
==== BodyPointLocalTimeAngleDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;BodyPointLocalTimeAngleDetector&amp;lt;/code&amp;gt; follows the same logic as its parent class &amp;lt;code&amp;gt;LocalTimeAngleDetector&amp;lt;/code&amp;gt; but, instead of computing the events for a certain position of the spacecraft, the events are computed with respect to a point of the surface of the body, by using the zenithal direction (normal to the surface). &lt;br /&gt;
&lt;br /&gt;
To compute the local time of a certain point in a body, first the Frame is verified (it cannot be null). Then, the normal direction of the body point is computed. Afterwards, the sun position is obtained. The local time corresponds to the angle between the projections of the Earth-Sun and the normal direction over the equatorial plane plus PI.&lt;br /&gt;
&lt;br /&gt;
==== SolarTimeAngleDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;SolarTimeAngleDetector&amp;lt;/code&amp;gt; detects when the spacecraft solar time is equal to a predetermined value; the spacecraft solar time is the angle between the the Earth-Sun projection in the orbital plane and the Earth-spacecraft vector plus PI. In PATRIUS, solar time is expressed as an angle in the range [-PI; PI[. Solar time angle is PI (or 12.00h) when the geometric angle Sun-Earth-Spacecraft is 0 and 0 (or 0.00h) when this angle is PI. &amp;lt;br&amp;gt;&lt;br /&gt;
The solar time is always increasing with time. It is mesured around the orbit momentum.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the sinus of the difference between the spacecraft current solar time &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; and the threshold solar time value &amp;lt;math&amp;gt;\theta_{t}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g=sin(\theta- \theta_{t})&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Like the &amp;lt;code&amp;gt;AOLDetector&amp;lt;/code&amp;gt;, a solar time event is triggered only if the g-function slope is positive at its zero.&lt;br /&gt;
&lt;br /&gt;
==== NadirSolarIncidenceDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;NadirSolarIncidenceDetector&amp;lt;/code&amp;gt; detects when the solar incidence, seen from the nadir point of the spacecraft, reaches a predetermined value.&amp;lt;br&amp;gt;&lt;br /&gt;
The solar incidence is the angle between the nadir- satellite vector and the nadir - sun vector.&lt;br /&gt;
&lt;br /&gt;
[[File:nadirsolarincidence.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== BodyPointSolarIncidenceDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;BodyPointSolarIncidenceDetector&amp;lt;/code&amp;gt; detects when the solar incidence angle reaches a predetermined value. The solar incidence is the angle between the interest point-satellite vector and the interest point-sun vector. The interest point being described by a BodyPoint.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:BodyPointSolarIncidenceDetector.png|center]]&#039;&#039;&#039;AstronomicalNightDetector&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The AstronomicalNightDetector detects when the Sun&#039;s elevation reaches a predetermined threshold, specifically designed to identify astronomical dawn and dusk events.&lt;br /&gt;
&lt;br /&gt;
Astronomical night is defined as the period when the Sun is more than 18 degrees below the horizon (elevation ≤ -18°). At this stage, the sky is dark enough for all astronomical observations; no scattered sunlight illuminates the atmosphere. &lt;br /&gt;
&lt;br /&gt;
This detector is independent of the actual spacecraft state, as it evaluates the Sun&#039;s position relative to a specific TopocentricFrame (e.g., a ground station or a specific terrestrial location).&lt;br /&gt;
&lt;br /&gt;
The  switching function measures the difference between the threshold angle and the current solar elevation: &#039;&#039;g = duskAngle – elevation&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The  function is positive at night (when the Sun&#039;s elevation is lower than the ) and negative during the day or twilight.&lt;br /&gt;
[[Fichier:Twilight is the period between dawn and sunrise, and between sunset and dusk.png|alt=Twilight is the period between dawn and sunrise, and between sunset and dusk, Source: Twilight - Wikipedia|centré|sans_cadre]]&lt;br /&gt;
&#039;&#039;Twilight is the period between dawn and sunrise, and between sunset and dusk, Source: [[wikipedia:Twilight|Twilight - Wikipedia]]&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By default, the  is set to -18° by default, but this value can be customized in the constructor to detect other types of twilight (e.g., civil at -6° or nautical at -12°).&lt;br /&gt;
&lt;br /&gt;
====EarthZoneDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;EarthZoneDetector&amp;lt;/code&amp;gt; detects when the spacecraft enters and leaves an earth zone. Several separated zones can be defined for one detector instance. In that case, the EarthZoneDetector detects the entery of the satellite NADIR point in any of the zones.&lt;br /&gt;
&lt;br /&gt;
The zones can be described two ways : &lt;br /&gt;
*As an array of {latitude, longitudes} that define the geodetic points with a zero altitude on a BodyShape. With this definition, the test made will be the entering of the spacecraft&#039;s NADIR point in the zone.&lt;br /&gt;
*As an array of vectors expressed in a given frame. With this definition, the entering of the spacecraft itself in the conic field from the center of the given frame to those points will be detected. Note that the given frame must be a terrestrial frame for the detection of earth zones entering, but the use of other frames is possible (other bodies, inertial frames…).&lt;br /&gt;
&lt;br /&gt;
In both cases, the points must respect the following conditions : &lt;br /&gt;
*At least 3 points are needed to define a zone&lt;br /&gt;
*two consecutive points must not be too close (1.e-10 on the difference of thier normalized values)&lt;br /&gt;
*the arc between two consecutive points must not cross the one between two consecutive others of the same zone.&lt;br /&gt;
&lt;br /&gt;
The points must also be given in the right order : from the point i to the point i + 1, if the associated vector from the center of the earth are &amp;lt;math&amp;gt;v_{i}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;v_{i + 1}&amp;lt;/math&amp;gt;, the inside of the zone is on the left, e.g. the side of the positive cross vector &amp;lt;math&amp;gt;v_{i} . v_{i + 1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Constructors with default maxCheck and threshold values are available, but beware of their values, and use the other constructors if needed  : if the zone is complex and the MaxCheck too large, the event detection could fail, because it would not manage to converge. To compute the event with enough precision to converge, set a small enough MaxCheck. To compute an approximative event even if the zone is precise and complex, set a large enough Threshold.&lt;br /&gt;
&lt;br /&gt;
===Particular detections===&lt;br /&gt;
All those detectors can be used for the following particular cases :&lt;br /&gt;
&lt;br /&gt;
*sub-solar point reaching  : use the SolarTimeAngleDetector with a &amp;quot;12h&amp;quot; time to detect.&lt;br /&gt;
*generic masking by a spherical body : use the GenericEclipseDetector, or the ThreeBodiesAngleDetector.&lt;br /&gt;
*terminator reaching (the nadir point reaches the night / day limit) : use the NadirSolarIncidenceDetector with a zero incidence.&lt;br /&gt;
*Sun interference in ground antennas : use the ThreeBodiesAngleDetector.&lt;br /&gt;
*RF interference between the main spacecraft and another one : use the ThreeBodiesAngleDetector&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
{{specialInclusion prefix=$theme_sub section=&amp;quot;GettingStarted&amp;quot;/}}&lt;br /&gt;
&lt;br /&gt;
== Contents==&lt;br /&gt;
===Interfaces===&lt;br /&gt;
All the detectors implement the interface :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Javadoc &lt;br /&gt;
|-&lt;br /&gt;
|EventDetector&lt;br /&gt;
|This interface represents an event finder.&lt;br /&gt;
|[&amp;lt;nowiki/&amp;gt;{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/EventDetector.html EventDetector ]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Classes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|AlignmentDetector&lt;br /&gt;
|This class handles (satellite/central body/projection in the orbital plane of secondary body) alignment events.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AlignmentDetector.html AlignmentDetector]&lt;br /&gt;
|-&lt;br /&gt;
|AltitudeDetector&lt;br /&gt;
|This class handles satellite altitude crossing events.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AltitudeDetector.html AltitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ApsideDetector&lt;br /&gt;
|This class handles satellite apogee and perigee crossing events.&lt;br /&gt;
| [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ApsideDetector.html ApsideDetector]&lt;br /&gt;
|-&lt;br /&gt;
|BodyInEclipseDetector&lt;br /&gt;
|This class handles the umbra/penumbra eclipse events detection for a non-point target body&lt;br /&gt;
|[{{JavaDoc4.18}}&amp;lt;nowiki&amp;gt;/fr/cnes/sirius/patrius/events/detectors/BodyInEclipseDetector.html BodyInEclipseDetector]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|BodyPointLocalTimeAngleDetector &lt;br /&gt;
|This class handles events representing the fact that a point on the surface of a spacecraft reaches a certain local time angle&lt;br /&gt;
|[{{JavaDoc4.18}}&amp;lt;nowiki&amp;gt;/fr/cnes/sirius/patrius/events/detectors/BodyPointLocalTimeAngleDetector.html BodyPointLocalTimeAngleDetector]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|DateDetector &lt;br /&gt;
|This class handles the occurrence of predefined dates.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/DateDetector.html DateDetector]&lt;br /&gt;
|-&lt;br /&gt;
|EclipseDetector&lt;br /&gt;
|This class handles total or partial eclipse events.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/EclipseDetector.html EclipseDetector]&lt;br /&gt;
|-&lt;br /&gt;
|NodeDetector&lt;br /&gt;
|This class handles satellite equator crossing events.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/NodeDetector.html NodeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|DistanceDetector&lt;br /&gt;
|This class handles events relating to the distance between the satellite and a given body.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/DistanceDetector.html DistanceDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ExtremaDistanceDetector&lt;br /&gt;
|This class handles events representing the reaching of extrema for the distance to a given body.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ExtremaDistanceDetector.html ExtremaDistanceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| ExtremaLatitudeDetector&lt;br /&gt;
|This class handles events representing the reaching of extrema for the geodetic latitude.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ExtremaLatitudeDetector.html ExtremaLatitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ExtremaLongitudeDetector&lt;br /&gt;
|This class handles events representing the reaching of extrema for the longitude.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ExtremaLongitudeDetector.html ExtremaLongitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|LatitudeDetector&lt;br /&gt;
|This class handles events representing the reaching of a given geodetic latitude, the earth shape being known.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/LatitudeDetector.html LatitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|LongitudeDetector&lt;br /&gt;
|This class handles events representing the reaching of a given longitude&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/LongitudeDetector.html LongitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|AnomalyDetector&lt;br /&gt;
|This class handles events representing the reaching of an anomaly angle.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AnomalyDetector.html AnomalyDetector]&lt;br /&gt;
|-&lt;br /&gt;
|SafetyMarginDetector&lt;br /&gt;
| This class handles escape velocity crossing detection.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/SafetyMarginDetector.html SafetyMarginDetector]|-&lt;br /&gt;
|-&lt;br /&gt;
|AOLDetector&lt;br /&gt;
| This class handles events representing the reaching of an argument of latitude value.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AOLDetector.html AOLDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ThreeBodiesAngleDetector&lt;br /&gt;
|This class handles events representing the reaching of a predetermined angle between three bodies.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ThreeBodiesAngleDetector.html ThreeBodiesAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ExtremaThreeBodiesAngleDetector&lt;br /&gt;
|This class handles events representing the reaching of of extrema for the angle between three bodies.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ExtremaThreeBodiesAngleDetector.html ExtremaThreeBodiesAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|BetaAngleDetector&lt;br /&gt;
|This class handles the event : reaching a given beta angle value for a spacecraft.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/BetaAngleDetector.html BetaAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|LocalTimeAngleDetector&lt;br /&gt;
|This class handles events representing the reaching of a predetermined spacecraft local time angle.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/LocalTimeAngleDetector.html LocalTimeAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|AstronomicalNightDetector&lt;br /&gt;
|This class handles astronomical dawn and dusk events (independent of the actual spacecraft state).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AstronomicalNightDetector.html AstronomicalNightDetector]&lt;br /&gt;
|-&lt;br /&gt;
|SolarTimeAngleDetector&lt;br /&gt;
|This class handles events representing the reaching of a predetermined spacecraft solar time angle.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/SolarTimeAngleDetector.html SolarTimeAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|NadirSolarIncidenceDetector&lt;br /&gt;
|This class handles events representing the reaching of a predetermined spacecraft nadir point solar incidence.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/NadirSolarIncidenceDetector.html NadirSolarIncidenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
|EarthZoneDetector&lt;br /&gt;
|This class handles events representing the entering and leaving of earth zones.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/EarthZoneDetector.html EarthZoneDetector]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
[[Category:User Manual 4.18 Mission]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Fichier:Twilight_is_the_period_between_dawn_and_sunrise,_and_between_sunset_and_dusk.png&amp;diff=4173</id>
		<title>Fichier:Twilight is the period between dawn and sunrise, and between sunset and dusk.png</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Fichier:Twilight_is_the_period_between_dawn_and_sunrise,_and_between_sunset_and_dusk.png&amp;diff=4173"/>
		<updated>2026-06-10T10:53:40Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Twilight is the period between dawn and sunrise, and between sunset and dusk&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Celestial_bodies&amp;diff=4172</id>
		<title>User Manual 4.18 Celestial bodies</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Celestial_bodies&amp;diff=4172"/>
		<updated>2026-06-10T10:48:39Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The celestial bodies are described by their main features : position and geometry. The positions are ephemeris that must be loaded from models, the geometries are created as one axis ellipsoids or facet bodies.&lt;br /&gt;
The package provides a factory able to create any celestial body of the solar system.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The classes for bodies description are available in the package &amp;lt;code&amp;gt;bodies&amp;lt;/code&amp;gt; of Patrius.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Orekit&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/package-summary.html Package fr.cnes.sirius.patrius.bodies]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/package-summary.html Package fr.cnes.sirius.patrius.bodies]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
&lt;br /&gt;
Orekit bodies : [https://www.orekit.org/static/architecture/bodies.html Orekit Bodies architecture description ]&lt;br /&gt;
&lt;br /&gt;
IAU report : [https://astrogeology.usgs.gov/groups/iau-wgccre Report of the IAU Working Group on Cartographic Coordinates and Rotational Elements: 2009]&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
None.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Celestial bodies ===&lt;br /&gt;
The Moon, the Sun and planets of the solar system are all represented by the [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/CelestialBody.html CelestialBody] interface. This class associates a name (eg Sun) to :&lt;br /&gt;
* a gravitational coefficient GM &lt;br /&gt;
*a body centered ICRF frame (which can be retrieved with method &amp;lt;code&amp;gt;getICRF()&amp;lt;/code&amp;gt;).&lt;br /&gt;
*a body centered EME2000 frame (which can be retrieved with method &amp;lt;code&amp;gt;getEME2000()&amp;lt;/code&amp;gt;).&lt;br /&gt;
*a body centered inertial frame taking into account only the constant part (α, δ) of IAUPole (which can be retrieved with method &amp;lt;code&amp;gt;getInertialFrame(IAUPoleModelType.CONSTANT)&amp;lt;/code&amp;gt;).&lt;br /&gt;
*a body centered inertial frame taking into account only the constant and secular parts (α, δ) of IAUPole (which can be retrieved with method &amp;lt;code&amp;gt;getInertialFrame(IAUPoleModelType.MEAN)&amp;lt;/code&amp;gt;).&lt;br /&gt;
*a body centered inertial frame taking into account the constant secular and harmonics parts (α, δ) of IAUPole (which can be retrieved with method &amp;lt;code&amp;gt;getInertialFrame(IAUPoleModelType.TRUE)&amp;lt;/code&amp;gt;).&lt;br /&gt;
*a body centered rotating frame taking into account only the constant part w of IAUPole (which can be retrieved with method &amp;lt;code&amp;gt;getRotatingFrame(IAUPoleModelType.CONSTANT)&amp;lt;/code&amp;gt;). It&#039;s parent frame is the inertial equator frame.&lt;br /&gt;
*a body centered rotating frame taking into account only the constant and secular parts w of IAUPole (which can be retrieved with method &amp;lt;code&amp;gt;getRotatingFrame(IAUPoleModelType.MEAN)&amp;lt;/code&amp;gt;). It&#039;s parent frame is the mean equator frame.&lt;br /&gt;
*a body centered rotating frame taking into account the constant secular and harmonics parts w of IAUPole (which can be retrieved with method &amp;lt;code&amp;gt;getRotatingFrame(IAUPoleModelType.TRUE)&amp;lt;/code&amp;gt;). It&#039;s parent frame is the true equator frame.&lt;br /&gt;
&lt;br /&gt;
Inertially-oriented and body-oriented frames are defined in the following way:&lt;br /&gt;
* Body-centered inertial frame is centered on the celestial body centered and pole axis (Z axis) is shifted by right ascension α and declination δ.&lt;br /&gt;
* Body-centered rotating frame is linked to inertially-oriented frame by a rotation of angle W(t) (reference values for W(t) is provided by IAU).&lt;br /&gt;
&lt;br /&gt;
To build a celestial body, the user can:&lt;br /&gt;
* use the static methods of the &amp;lt;code&amp;gt;CelestialBodyFactory&amp;lt;/code&amp;gt; to create instances of the most common celestial bodies (Moon, Sun, Jupiter, etc.). JPL Ephemeris data are used. Warning: using the factory requires to load JPL Ephemeris data beforehand.&lt;br /&gt;
* use the simplified models (Meeus, etc.).&lt;br /&gt;
* creates its own celestial body using the class &amp;lt;code&amp;gt;UserCelestialBody&amp;lt;/code&amp;gt; as well as its own pole motion using the class &amp;lt;code&amp;gt;UserIAUPole&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For the two first case (JPL and Meeus), the pole data of the body are automatically retrieved using the IAU data through &amp;lt;code&amp;gt;IAUPoleFactory&amp;lt;/code&amp;gt; class (data is contained within PATRIUS).&lt;br /&gt;
By default, IAU pole data for planetary bodies (including Sun and moon) are available in PATRIUS through the use of the &amp;lt;code&amp;gt;IAUPoleFactory.getIAUPole()&amp;lt;/code&amp;gt;. Data come from the IAU 2009 working group Technical Note.&lt;br /&gt;
&lt;br /&gt;
These methods are detailed in the following sections.&lt;br /&gt;
&lt;br /&gt;
=== Ephemeris Loader ===&lt;br /&gt;
For any celestial body of the Solar System, the actual computation of its position and velocity relies on the JPL planetary ephemerides files. These files are binary files and loaded thanks to the JPLCelestialBodyLoader object.&lt;br /&gt;
&lt;br /&gt;
Note that celestial bodies and associated ephemeris loaders are distinct: a class loads the ephemeris returning a &amp;lt;code&amp;gt;CelestialBodyEphemeris&amp;lt;/code&amp;gt; while the other loads the whole &amp;lt;code&amp;gt;CelestialBody&amp;lt;/code&amp;gt;.&lt;br /&gt;
However, for sake of clarity, the main visible loaders are celestial body loaders.&lt;br /&gt;
&lt;br /&gt;
For the moment, this object is able to load JPL DE XXX files and IMCCE INPOP files which are the most commonly used data files (see below for an exact list of accepted files). For instance with the most common files, the JPL DE 405 covers the years 1600 to 2200 at maximum precision, the JPL DE 406 covers the years-3000 to +3000 at only slightly reduced precision. The DE 405 file is the basis for the Astronomical Almanac and leads to sufficiently accurate results and, for most purposes, even the accuracy of DE 406 is sufficient.&lt;br /&gt;
&lt;br /&gt;
==== JPLCelestialBodyLoader ====&lt;br /&gt;
&lt;br /&gt;
In order to generate the ephemerides of one celestial body of the Solar System, one has to use the JPLCelestialBodyLoader as follows :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;   &lt;br /&gt;
final JPLCelestialBodyLoader loaderEMB = new JPLCelestialBodyLoader(fileName, &lt;br /&gt;
                   EphemerisType.EARTH_MOON);&lt;br /&gt;
final JPLCelestialBodyLoader loaderSSB = new JPLCelestialBodyLoader(fileName, &lt;br /&gt;
                   EphemerisType.SOLAR_SYSTEM_BARYCENTER);&lt;br /&gt;
CelestialBodyFactory.addCelestialBodyLoader(CelestialBodyFactory.EARTH_MOON, loaderEMB);&lt;br /&gt;
CelestialBodyFactory.addCelestialBodyLoader(CelestialBodyFactory.SOLAR_SYSTEM_BARYCENTER, loaderSSB);&lt;br /&gt;
&lt;br /&gt;
// Reference frame&lt;br /&gt;
Frame icrf = FramesFactory.getICRF();&lt;br /&gt;
&lt;br /&gt;
// Ephemeris of the Sun&lt;br /&gt;
JPLCelestialBodyLoaderloader = new JPLCelestialBodyLoader(&amp;quot;unxp2000.405&amp;quot;, &lt;br /&gt;
                EphemerisType.SUN);&lt;br /&gt;
&lt;br /&gt;
// Creation of the Sun&lt;br /&gt;
CelestialBody sun = loader.loadCelestialBody(CelestialBodyFactory.SUN);&lt;br /&gt;
&lt;br /&gt;
// Coordinates of the Sun given a date and a reference frame&lt;br /&gt;
PVCoordinates pvSun = sun.getPVCoordinates(date, icrf);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the user wants to create a JPLCelestialBodyLoader, first of all, he must supply the folder where the DE XXX files are stored. Then he has to give the name of the file which contains the data (DE XXX), the type of celestial body and a date (desired central date) as entries of the JPLCelestialBodyLoader.&lt;br /&gt;
&lt;br /&gt;
The first argument (name of the data file) may be &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;. In this case, Patrius takes the first compatible file found. If one wants only files from the DE 405 ephemerides, for instance, he has to give the String &amp;lt;code&amp;gt; &amp;quot;^unx[mp](\\d\\d\\d\\d)\\.(?:405)$&amp;quot;&amp;lt;/code&amp;gt;. The last argument can also be &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;. If the central date is not mentionned an arbitrary 100 days range will be loaded whereas if it is mentionned all data within a +/-50 days range around this date will be loaded.&lt;br /&gt;
&lt;br /&gt;
Once the data is loaded, thanks to the JPLCelestialBodyLoader, the user can create the celestial body with the method loadCelestialBody() of the JPLCelestialBodyLoaderclass. To do so, the user has to be sure that all required data is loaded. Indeed, apart from the Moon, the Earth and the Earth-Moon barycenter, the creation of a celestial body requires some data on the Earth Moon barycenter and the Solar System barycenter in order to instanciate the frame in which the ephemerides of the celestial body will be defined. Therefore, the user has to create a JPLCelestialBodyLoaderfor the Earth-Moon barycenter and the Solar System barycenter prior to creating the celestial body, otherwise Patrius will arbitrarily load a DE file to generate the corresponding ephemerides that are used afterwards for the generation of the frame. Then the user has to complete the list of the loaders of the CelestialBodyFactory with these two loaders before calling the method loadCelestialBody().&lt;br /&gt;
&lt;br /&gt;
A static method &amp;lt;code&amp;gt;hasNoLoader()&amp;lt;/code&amp;gt; in the class &amp;lt;code&amp;gt;CelestialBodyFactory&amp;lt;/code&amp;gt; allows for a given celestial body to verify if a default loader exists. The user can verify if a specific loader exists for the body before using the default one this way.&lt;br /&gt;
&lt;br /&gt;
NB : The user has to clean the CelestialBodyFactory memory if he does not want to work with the previously defined celestial bodies.&lt;br /&gt;
&lt;br /&gt;
==== JPL ephemerides ====&lt;br /&gt;
&lt;br /&gt;
The JPL ephemerides data is available on the [ftp://ssd.jpl.nasa.gov/pub/eph/planets/ JPL FTP server] [R3].&lt;br /&gt;
&lt;br /&gt;
Available ephemerides :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Development Ephemerides&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Created in...&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
|DE200&lt;br /&gt;
|September 1981&lt;br /&gt;
|includes nutations but not librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the dynamical equator and equinox of 2000.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2305424.13 (1599 DEC 09)  to  JED 2513360.5 (2169 MAR 31).&lt;br /&gt;
&lt;br /&gt;
This ephemeris was used for  the Astronomical Almanac from 1984 to 2003. (See Standish, 1982 and Standish, 1990).&lt;br /&gt;
|-&lt;br /&gt;
|DE202&lt;br /&gt;
|October 1987&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the dynamical equator and equinox of 2000.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2414992.5 (1899 DEC 04) to  JED 2469808.5 (2050 JAN 02).&lt;br /&gt;
|-&lt;br /&gt;
|DE403&lt;br /&gt;
|May 1993&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2305200.5 (1599 APR 29) to  JED 2524400.5 (2199 JUN 22).&lt;br /&gt;
&lt;br /&gt;
Fit to planetary and lunar laser ranging data.(See Folkner et al. 1994).&lt;br /&gt;
|-&lt;br /&gt;
|DE405, DE406&lt;br /&gt;
|May 1997&lt;br /&gt;
|For the DE405:&lt;br /&gt;
&lt;br /&gt;
includes both nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2305424.130  (1599 DEC 09)  to  JED 2525008.50  (2201 FEB 20)&lt;br /&gt;
&lt;br /&gt;
For the DE406 :&lt;br /&gt;
&lt;br /&gt;
the same as the DE405 except the time span : Spans JED 0624976.50 (-3001 FEB 04) to 2816912.50 (+3000 MAY 06)&lt;br /&gt;
&lt;br /&gt;
This is the same integration as DE405, with the accuracy of the interpolating polynomials has been lessened to reduce file size for the longer time span covered by the file.&lt;br /&gt;
|-&lt;br /&gt;
|DE410&lt;br /&gt;
|April 2003&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2415056.5 (1900 FEB 06) to JED 2458832.5 (2019 DEC 15).&lt;br /&gt;
&lt;br /&gt;
Ephemeris used for Mars Exploration Rover navigation.&lt;br /&gt;
|-&lt;br /&gt;
|DE413&lt;br /&gt;
|November 2004&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2414992.5, (1899 DEC 04) to JED 2469872.5 (2050 MAR 07).&lt;br /&gt;
&lt;br /&gt;
Created to update the orbit of Pluto to aid in planning for an occultation of a relatively bright star by Charon on 11 July 2005.&lt;br /&gt;
|-&lt;br /&gt;
|DE414&lt;br /&gt;
|May 2005&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2414992.5, (1899 DEC 04) to JED 2469872.5 (2050 MAR 07).&lt;br /&gt;
&lt;br /&gt;
Fit to ranging data from MGS and Odyssey through 2003. (See Konopliv et al., 2006.)&lt;br /&gt;
|-&lt;br /&gt;
|DE418&lt;br /&gt;
|August 2007&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2414864.13 (1899 JUL 29) to JED 2470192.5 (2051 JAN 21)&lt;br /&gt;
|-&lt;br /&gt;
|DE421&lt;br /&gt;
|February 2008&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2414864.13 (1899 JUL 29) to JED 2471184.13 (2053 OCT 09)&lt;br /&gt;
&lt;br /&gt;
Fit to planetary and lunar laser ranging data. (See Folkner et al., 2009)&lt;br /&gt;
|-&lt;br /&gt;
|DE422&lt;br /&gt;
|September 2009&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 625648.5, (-3000 DEC 07) to JED 2816816.5, (3000 JAN 30).&lt;br /&gt;
&lt;br /&gt;
Intended for the MESSENGER mission to Mercury.&amp;lt;br&amp;gt;&lt;br /&gt;
Extended integration time to serve as successor to DE406.&amp;lt;br&amp;gt;&lt;br /&gt;
Fit to ranging data from MGS and Odyssey through 2003. (See Konopliv et al., 2010.)&lt;br /&gt;
|-&lt;br /&gt;
|DE423&lt;br /&gt;
|February 2010&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame  version 2.0.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2378480.5, (1799 DEC 16) to JED  2524624.13, (2200 FEB 02).&lt;br /&gt;
&lt;br /&gt;
Intended for the MESSENGER mission to Mercury.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== IMCCE INPOP ephemerides ====&lt;br /&gt;
&lt;br /&gt;
The IMCCE INPOP ephemeris is available on IMCCE website.&lt;br /&gt;
&lt;br /&gt;
Available INPOP ephemerides :&lt;br /&gt;
* 06b&lt;br /&gt;
* 06c&lt;br /&gt;
* 08a&lt;br /&gt;
* 10a&lt;br /&gt;
* 10b&lt;br /&gt;
* 10e&lt;br /&gt;
* 13c&lt;br /&gt;
* 17a&lt;br /&gt;
* 19a&lt;br /&gt;
&lt;br /&gt;
=== Simplified analytical models ===&lt;br /&gt;
==== Meeus Model ====&lt;br /&gt;
&lt;br /&gt;
The Meeus Model is a simplified model which gives the position of the Sun and the Moon with respect to the time T expressed in centuries (TT time scale). This model is an analytical model less precise than the DE ephemerides given by JPL. It is adapted for onboard applications.&lt;br /&gt;
The class implementing the Meeus Model allows three different models computing the position of the Sun with appropriate equations : the standard model (provided by Jean Meeus), the Stela model and an onboard model. The main differences between these model is the computation of the obliquity of the ecliptic : indeed, its value is fixed to 0 for the standard model, given by an expression involving &amp;lt;math&amp;gt;T, T^{2}&amp;lt;/math&amp;gt;for Stela model and &amp;lt;math&amp;gt;T, T^{2}, T^{3}&amp;lt;/math&amp;gt; for the onboard model.&lt;br /&gt;
Moreover, the onboard model computed the position in J2000 frame, whereas standard and Stela models use respectively EOD and MOD frame.&lt;br /&gt;
&lt;br /&gt;
Regarding the precision, one has to expect a maximum difference of 25593km in position for the Sun and a maximum angular difference of 34.13&#039;&#039; (wrt DE405 ephemerides). For the Moon, one has to expect a maximum difference of 26 km in position and a maximum angular difference of 15.2&#039;&#039; (wrt DE405 ephemerides). As for the performances (in terms of execution time), the Meeus model for the Sun is faster than the DE405 ephemerides. However, we did not come to the same conclusion for the Moon even by decreasing the degree of precision (number of terms taken into account to compute the latitude, longitude and distance which are needed to compute in fine the position of the Moon).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Deviation in position wrt DE423&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Angular deviation wrt DE423&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sun&#039;&#039;&#039;&lt;br /&gt;
|12000 km&lt;br /&gt;
|34.13&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 62x66x46&#039;&#039;&#039;&lt;br /&gt;
|12.4 km&lt;br /&gt;
|15.2&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 26x13x13&#039;&#039;&#039;&lt;br /&gt;
|225 km&lt;br /&gt;
|122&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 9x4x3&#039;&#039;&#039;&lt;br /&gt;
|1591 km&lt;br /&gt;
|889&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Deviation in position wrt DE405&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Angular deviation wrt DE405&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sun&#039;&#039;&#039;&lt;br /&gt;
|25593km&lt;br /&gt;
|34.13&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 62x66x46&#039;&#039;&#039;&lt;br /&gt;
|26 km&lt;br /&gt;
|15.2&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Number of elementary operations&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Number of trigonometric operations&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sun&#039;&#039;&#039;&lt;br /&gt;
|89&lt;br /&gt;
|10&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 62x66x46&#039;&#039;&#039;&lt;br /&gt;
|2671&lt;br /&gt;
|182&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 26x13x13&#039;&#039;&#039;&lt;br /&gt;
|917&lt;br /&gt;
|60&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 9x4x3&#039;&#039;&#039;&lt;br /&gt;
|401&lt;br /&gt;
|24&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
References for the tables : &lt;br /&gt;
* &amp;quot;Modèles d&#039;éphémérides luni-solaires&amp;quot;, CNES DCT/SB/MS, 03/14/2011&lt;br /&gt;
* &amp;quot;Modèle MEEUS pour éphémérides Lune-Soleil : Compléments sur le nombre d&#039;opérations&amp;quot;, CNES DCT/SB/MS&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| execution time - DE405&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| execution time- MEEUS&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sun&#039;&#039;&#039;&lt;br /&gt;
|59 s 548 ms&lt;br /&gt;
|19 s 938 ms&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 62x66x46&#039;&#039;&#039;&lt;br /&gt;
|11 s 625 ms&lt;br /&gt;
|3 mn 22 s 323 ms&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 26x13x13&#039;&#039;&#039;&lt;br /&gt;
|11 s 625 ms&lt;br /&gt;
|1 mn 17 s 74 ms&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 9x4x3&#039;&#039;&#039;&lt;br /&gt;
|11 s 625 ms&lt;br /&gt;
|40 s 326 ms&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In order to build such a Sun or Moon, one has to use the object MeeusSun or MeeusMoon which both extend AbstractCelestialBody. Note that it is not possible to build those celestial bodies from the CelestialBodyFactory, for the moment.&lt;br /&gt;
&lt;br /&gt;
==== Basic board Sun model ====&lt;br /&gt;
The basic board Sun  model is a simplified analytical model which gives the direction of the Sun (the normalized position) with respect to time. &lt;br /&gt;
This model is similar to the Meeus model (the constants of the model are different) and is adapted for onboard applications. &lt;br /&gt;
The reference inertial frame is the CIRF.&lt;br /&gt;
&lt;br /&gt;
=== User-defined celestial bodies ===&lt;br /&gt;
User can defined its own celestial body by using &amp;lt;code&amp;gt;UserCelestialBody&amp;lt;/code&amp;gt;.&lt;br /&gt;
This class requires to provide:&lt;br /&gt;
* Its name.&lt;br /&gt;
* Its position-velocity through time using a &amp;lt;code&amp;gt;PVCoordinateProvider&amp;lt;/code&amp;gt; implementation.&lt;br /&gt;
* Its gravitational constant.&lt;br /&gt;
* Its pole motion using &amp;lt;code&amp;gt;IAUPole&amp;lt;/code&amp;gt; implementation or directly the &amp;lt;code&amp;gt;UserIAUPole&amp;lt;/code&amp;gt; implementation.&lt;br /&gt;
The &amp;lt;code&amp;gt;UserIAUPole&amp;lt;/code&amp;gt; is a simple way to build standard pole motion from IAU note. It requires to provide for each component (α, δ and W) a list of functions of duration in days and duration in centuries (from a reference epoch) as defined in IAU note. This functions are &amp;lt;code&amp;gt;UnivariateDifferentiableFunction&amp;lt;/code&amp;gt;.&lt;br /&gt;
Available functions in PATRIUS include:&lt;br /&gt;
* &amp;lt;code&amp;gt;PolynomialFunction&amp;lt;/code&amp;gt;: polynomial function&lt;br /&gt;
* &amp;lt;code&amp;gt;SineFunction&amp;lt;/code&amp;gt;: function of the form k.sin(f) with f an &amp;lt;code&amp;gt;UnivariateDifferentiableFunction&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CosineFunction&amp;lt;/code&amp;gt;: function of the form k.cos(f) with f an &amp;lt;code&amp;gt;UnivariateDifferentiableFunction&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example: building Ceres&#039;&#039;&#039;.&lt;br /&gt;
According to the IAU report, Ceres has the following parameters:&lt;br /&gt;
* α = 291◦ ± 5◦&lt;br /&gt;
* δ = 59◦ ± 5◦&lt;br /&gt;
* W = 170.90◦ + 952.1532◦d&lt;br /&gt;
With &#039;&#039;d&#039;&#039; being the interval in days from the standard epoch (the standard epoch is JD 2451545.0, i.e. 2000 January 1 12 hours TDB)&lt;br /&gt;
&lt;br /&gt;
Ceres gravitational constant is 6.263E10 m^^3^^kg^^-1^^s^^-2^^.&lt;br /&gt;
&lt;br /&gt;
If one knows Ceres motion given for instance by a &amp;lt;code&amp;gt;PVCoordinatePropagator&amp;lt;/code&amp;gt; &#039;&#039;pv&#039;&#039;, then one can build Ceres with the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Gravitational parameter&lt;br /&gt;
final double gm = 6.263E10;&lt;br /&gt;
&lt;br /&gt;
// Pole motion - Method 1 - Implementation if IAUPole interface&lt;br /&gt;
final IAUPole pole = new IAUPole() {&lt;br /&gt;
    @Override&lt;br /&gt;
    public double getPrimeMeridianAngle(final AbsoluteDate date) {&lt;br /&gt;
        // W&lt;br /&gt;
        final double d = date.durationFrom(AbsoluteDate.J2000_EPOCH) / Constants.JULIAN_DAY;&lt;br /&gt;
        return FastMath.toRadians(170.90) + FastMath.toRadians(952.1532)* d;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    @Override&lt;br /&gt;
    public Vector3D getPole(final AbsoluteDate date) {&lt;br /&gt;
        // Pole bias: alpha and delta&lt;br /&gt;
        return new Vector3D(FastMath.toRadians(291), FastMath.toRadians(59));&lt;br /&gt;
    }&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Pole motion - Method 2 - Use of UserIAUPole class&lt;br /&gt;
// Alpha 0 coefficients&lt;br /&gt;
final List&amp;lt;IAUPoleFunction&amp;gt; alpha0List = new ArrayList&amp;lt;IAUPoleFunction&amp;gt;();&lt;br /&gt;
alpha0List.add(new IAUPoleFunction(IAUPoleType.CONSTANT, new PolynomialFunction(new double[] { 291 }), IAUTimeDependency.DAYS);&lt;br /&gt;
final IAUPoleCoefficients1D alpha0Coeffs = new IAUPoleCoefficients1D(alpha0List);&lt;br /&gt;
// Delta 0 coefficients&lt;br /&gt;
final List&amp;lt;IAUPoleFunction&amp;gt; delta0List = new ArrayList&amp;lt;IAUPoleFunction&amp;gt;();&lt;br /&gt;
delta0List.add(new IAUPoleFunction(IAUPoleType.CONSTANT, new PolynomialFunction(new double[] { 59 }), IAUTimeDependency.DAYS);&lt;br /&gt;
final IAUPoleCoefficients1D delta0Coeffs = new IAUPoleCoefficients1D(delta0List );&lt;br /&gt;
// W coefficients&lt;br /&gt;
final List&amp;lt;IAUPoleFunction&amp;gt; w0List = new ArrayList&amp;lt;IAUPoleFunction&amp;gt;();&lt;br /&gt;
w0List.add(new IAUPoleFunction(IAUPoleType.CONSTANT, new PolynomialFunction(new double[] { 170.9 }), IAUTimeDependency.DAYS);&lt;br /&gt;
w0List.add(new IAUPoleFunction(IAUPoleType.SECULAR, new PolynomialFunction(new double[] { 0, 952.1532 }), IAUTimeDependency.DAYS);&lt;br /&gt;
final IAUPoleCoefficients1D wCoeffs = new IAUPoleCoefficients1D(w0List);&lt;br /&gt;
// Build pole&lt;br /&gt;
final IAUPole pole = new UserIAUPole(new IAUPoleCoefficients(alpha0Coeffs, delta0Coeffs, wCoeffs));&lt;br /&gt;
&lt;br /&gt;
// Build Ceres body&lt;br /&gt;
final CelestialBody ceres = new UserCelestialBody(&amp;quot;Ceres&amp;quot;, pv, gm, pole, FramesFactory.getICRF(), null);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then &amp;lt;code&amp;gt;ceres&amp;lt;/code&amp;gt; object possesses all features of:&lt;br /&gt;
* A &amp;lt;code&amp;gt;CelestialBody&amp;lt;/code&amp;gt;: retrieve body-centered inertial frames or body-centered rotating frames&lt;br /&gt;
* A &amp;lt;code&amp;gt;PVCoordinateProvider&amp;lt;/code&amp;gt;: retrieve position and velocity at any time&lt;br /&gt;
&lt;br /&gt;
==== BodyShape====&lt;br /&gt;
&lt;br /&gt;
The BodyShape interface carries servals features common to body shapes such as its name, frame, intersection point computation, distance to a line, closest point computation, body point transformation. &lt;br /&gt;
A couple of getter/setter allows to configure the LLHCoordinatesSystem associated to the shape, which can be ELLIPSODETIC, BODYCENTRIC_RADIAL or BODYCENTRIC_NORMAL. This coordinates system is used for instance by closest point computation or body point transformation. &lt;br /&gt;
The interface extends the PVCoordinatesProvider and ApparentRadiusProvider interfaces. The first carry the service to determine the PVCoordinates of the body at any date and the second describes two related features:&lt;br /&gt;
* Compute the apparent radius of the occulting body from the spacecraft (observer) position. Given a plane containing the spacecraft position, the center of the occulting body (the body shape) and the center of the occulted body, and given a line contained within this plane, passing by the spacecraft position and tangent to the mesh of the occulting body, the apparent radius corresponds to the length of the line starting from the center of the occulting body, perpendicular to the first given line and ending at the intersection of the two lines.&lt;br /&gt;
* Compute the apparent radius in a plane containing the spacecraft position, the center of the occulting body and a specified direction instead of the occulted body position. The rest of the behavior stays identical.&lt;br /&gt;
* Compute the maximum apparent radius of the body as seen by the spacecraft position. This radius, expressed in meters, corresponds to the maximum distance from the body&#039;s center to any point on its surface belonging to the limb ellipse (contour ellipse) viewed by the spacecraft.&lt;br /&gt;
Note: The apparent radius is computed in one direction from the frame origin of the body to the perpendicular tangent line. In case of dissymmetric shape, this definition it might introduce some limitations as the radius computed in the other direction would be different.&lt;br /&gt;
&lt;br /&gt;
==== OneAxisEllipsoid ====&lt;br /&gt;
&lt;br /&gt;
This type is used to represent the shape of a planet. One very useful implementation represents an ellipsoid (OneAxisEllipsoid). It is constructed from an equatorial radius, a flattening coefficient, and a reference frame that will be used to localize Geodetic points on the shape.&lt;br /&gt;
&lt;br /&gt;
The one-axis ellipsoid is a good approximate model for most planet-size and larger natural bodies. It is the equilibrium shape reached by a fluid body under its own gravity field when it rotates. The symmetry axis is the rotation or polar axis.&lt;br /&gt;
&lt;br /&gt;
It could be interesting to obtain the intersection point of a line from the satellite to the surface of the body for a given altitude. To that purpose, one can use the method getIntersectionPoint(Line, Vector3D, Frame, AbsoluteDate, double) of the interface BodyShape.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
AbsoluteDate date = new AbsoluteDate(new DateComponents(2008, 03, 21),&lt;br /&gt;
                                             TimeComponents.H12,&lt;br /&gt;
                                             TimeScalesFactory.getUTC());       &lt;br /&gt;
CelestialBodyFrame frame = FramesFactory.getITRF();&lt;br /&gt;
// Body shape model&lt;br /&gt;
OneAxisEllipsoid earth = new OneAxisEllipsoid(6378136.460, 1 / 298.257222101, frame);&lt;br /&gt;
&lt;br /&gt;
// Satellite on any position&lt;br /&gt;
&lt;br /&gt;
circ = new CircularOrbit(7178000.0, 0.5e-4, 0., FastMath.toRadians(50.), FastMath.toRadians(0.),&lt;br /&gt;
                                   FastMath.toRadians(90.), PositionAngle.MEAN, &lt;br /&gt;
                                   FramesFactory.getEME2000(), date, mu);&lt;br /&gt;
        &lt;br /&gt;
// Transform satellite position to position/velocity parameters in EME2000 and ITRF200B&lt;br /&gt;
PVCoordinates pvSatEME2000 = circ.getPVCoordinates();&lt;br /&gt;
PVCoordinates pvSatItrf  = frame.getTransformTo(FramesFactory.getEME2000(), date).transformPVCoordinates(pvSatEME2000);&lt;br /&gt;
Vector3D pSatItrf  = pvSatItrf.getPosition();&lt;br /&gt;
        &lt;br /&gt;
// Nadir point of the satellite&lt;br /&gt;
Vector3D pointItrf     = new Vector3D.ZERO;&lt;br /&gt;
Vector3D direction = Vector3D(1., pSatItrf,-1., pointItrf);&lt;br /&gt;
Line line = new Line(pSatItrf, direction);&lt;br /&gt;
// intersection point between the ellipsoid and the line that joins the satellite and the center of the body&lt;br /&gt;
double altitude  = 0;&lt;br /&gt;
EllipsoidPoint nadir = earth.getIntersectionPoint(line, pSatItrf, frame, date, altitude);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The ThreeAxisEllipsoid class shares many features with the OneAxisEllipsoid and allows to define an ellipsoid fully defined by its three axis radius (along the directions (0, 0, 1) ; (0, 1, 0) ; (0, 0, 1)).&lt;br /&gt;
&lt;br /&gt;
OneAxisEllipsoid extends the AbstractEllipsoidBodyShape class (also extended by ThreeAxisEllipsoid) and AbstractEllipsoidBodyShape implements the EllipsoidBodyShape interface, which extends the StarConvexBodyShape interface, which, at its turn, extends the BodyShape interface (already introduced).&lt;br /&gt;
&lt;br /&gt;
==== Facet celestial body ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FacetBodyShape&amp;lt;/code&amp;gt; is a class used to define a celestial body as a mesh. This is particularly useful for small irregular bodies such as asteroids.&lt;br /&gt;
For example, Phobos contains here 100 000 vertices and 200 000 facets:&lt;br /&gt;
[[File:Phobos.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
This class:&lt;br /&gt;
* Inherits the &amp;lt;code&amp;gt;BodyShape&amp;lt;/code&amp;gt; interface and hence can be used together with &amp;lt;code&amp;gt;EclipseDetector&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;SensorModel&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Provides some useful and optimised methods for small body handling. Facets are connected to each other allowing some methods to be writen in a recursive or iterative way and hence being very fast. If &amp;lt;i&amp;gt;n&amp;lt;/i&amp;gt; is the number of vertices of the body, fast recursive or iterative methods are in O(log(n)).&lt;br /&gt;
&lt;br /&gt;
For use as a &amp;lt;code&amp;gt;CelestialBody&amp;lt;/code&amp;gt;, this class must be linked to a &amp;lt;code&amp;gt;UserCelestialBody&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===== Mesh provider =====&lt;br /&gt;
&lt;br /&gt;
A mesh is described by a list of facets &amp;lt;code&amp;gt;Triangle&amp;lt;/code&amp;gt; and or vertices &amp;lt;code&amp;gt;Vertex&amp;lt;/code&amp;gt;. A &amp;lt;code&amp;gt;Triangle&amp;lt;/code&amp;gt; contains three vertices.&lt;br /&gt;
Mesh is provided by the generic interface &amp;lt;code&amp;gt;MeshProvider&amp;lt;/code&amp;gt;. This interface currently possesses two implementation:&lt;br /&gt;
* &amp;lt;code&amp;gt;ObjMeshLoader&amp;lt;/code&amp;gt;: in this case, the mesh is provided under official .obj file format. See [https://en.wikipedia.org/wiki/Wavefront_.obj_file This page] for more information on the format.&lt;br /&gt;
* &amp;lt;code&amp;gt;GeodeticMeshLoader&amp;lt;/code&amp;gt;: in this case, the mesh is provided in an ASCII column file listing each vertex in the format [Latitude Longitude Altitude].&lt;br /&gt;
&lt;br /&gt;
===== Available methods =====&lt;br /&gt;
&lt;br /&gt;
Note that most methods return &amp;lt;b&amp;gt;exact&amp;lt;/b&amp;gt; results. For example, &amp;lt;code&amp;gt;distanceTo&amp;lt;/code&amp;gt; methods returns exact distance to mesh body. Only &amp;lt;code&amp;gt;getEllipsoid(EllipsoidType)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;getApparentRadius&amp;lt;/code&amp;gt; methods return a simplified result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FacetBodyShape&amp;lt;/code&amp;gt; provides the following methods:&lt;br /&gt;
* &amp;lt;code&amp;gt;getIntersection(Line, Vector3D, Frame, AbsoluteDate)&amp;lt;/code&amp;gt; and similar which return an &amp;lt;code&amp;gt;Intersection&amp;lt;/code&amp;gt; object.This object contains the intersection point as well as the &amp;lt;code&amp;gt;Triangle&amp;lt;/code&amp;gt; containing the intersection point. This method is recursive and is in O(log(n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;buildPoint(LLHCoordinatesSystem, double, double, double, String)&amp;lt;/code&amp;gt; and similar which return the facet point associated to the specified corrinates in the given LLH coordinates system.&lt;br /&gt;
* &amp;lt;code&amp;gt;getApparentRadius&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;getApparentRadiusDirection&amp;lt;/code&amp;gt; methods which provides the local radius of the body shape seen by an observer in the direction of an occulted body or a specified direction using an approximate iterative algorithm. This method is used by EclipseDetector for instance.&lt;br /&gt;
* &amp;lt;code&amp;gt;getMaximumApparentRadius&amp;lt;/code&amp;gt; method is not supported by this class (throw an UnsupportedOperationException) as the determination of a contour ellipse won&#039;t be possible on this body shape that can define any shape.&lt;br /&gt;
* &amp;lt;code&amp;gt;resize(MarginType, double)&amp;lt;/code&amp;gt; method which returns a resized body shape.&lt;br /&gt;
* &amp;lt;code&amp;gt;closestPointTo&amp;lt;/code&amp;gt; methods which return the two closest points between the line given in input and the current facet body shape. One of the two points belongs to the line, the other to the facet body shape.&lt;br /&gt;
* &amp;lt;code&amp;gt;distanceTo()&amp;lt;/code&amp;gt; method which returns the distance to the body. This method is recursive and is hence in O(log(n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;getNeighbors()&amp;lt;/code&amp;gt; methods which returns the neighbors triangles to:&lt;br /&gt;
** A point or a triangle given a &amp;quot;neighborhood distance&amp;quot;&lt;br /&gt;
** A triangle given a &amp;quot;neighborhood order&amp;quot;. In this case, order 1 returns the immediate neighbors of the triangles, order 2 returns also the neighbors&#039; neighbors and so on.&lt;br /&gt;
This method is recursive and is hence in O(log(n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;getFieldData()&amp;lt;/code&amp;gt; which returns a container &amp;lt;code&amp;gt;FieldData&amp;lt;/code&amp;gt; containing data related to the field of view:&lt;br /&gt;
** Visible triangles from the satellite field of view &amp;lt;code&amp;gt;IFieldOfView&amp;lt;/code&amp;gt;. A visible triangle must be entirely in the field of view and not masked by any other triangle.&lt;br /&gt;
** Contour of the seen triangles. Contour is strictly contained in the field of view&lt;br /&gt;
If main direction of the field of view is provided, this method is recursive and is in O(log(n)). Otherwise, it is in O(n) and is much slower.&lt;br /&gt;
* &amp;lt;code&amp;gt;isInEclipse()&amp;lt;/code&amp;gt; method which returns true if the satellite is currently in eclipse, false otherwise. Penumbra is not taken into account. This method is in O(log(n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;getNeverVisibleTriangles()&amp;lt;/code&amp;gt; which returns a list of facets which are never visible from the provided ephemeris. Visibility criteria is the same as for &amp;lt;code&amp;gt;getFieldData()&amp;lt;/code&amp;gt; method. This method is in O((n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;getNeverEnlightenedTriangles()&amp;lt;/code&amp;gt; which returns a list of facets which are never enlightened by the Sun. Visibility criteria is the same as for &amp;lt;code&amp;gt;getFieldData()&amp;lt;/code&amp;gt; method. This method is in O((n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;getVisibleAndEnlightenedTriangles()&amp;lt;/code&amp;gt; which returns a list of facets which are visible and enlightened at the same time, at least once on the provided ephemeris. Visibility criteria is the same as for &amp;lt;code&amp;gt;getFieldData()&amp;lt;/code&amp;gt; method. This method is in O((n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;getEllipsoidType()&amp;lt;/code&amp;gt; which returns the type of the ellipsoid.&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;code&amp;gt;BodyShapeFitter&amp;lt;/code&amp;gt; allows to build shapes fitted on the main Shape provided as input. Different criteria are available and the type of ellipsoid returned can be obtained by calling the method &amp;lt;code&amp;gt;getEllipsoid(EllipsoidType)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== EllipsoidPoint====&lt;br /&gt;
&lt;br /&gt;
The ellipsoid point is defined by a latitude, a longitude and an altitude in the frame associated to the ellipsoid (EllipsoidBodyShape). It could be interesting to know the position of a satellite in terms of geodetic coordinates rather than Cartesian ones and vice versa (the corresponding methods in OneAxisEllipsoid).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// equatorial radius of the celestial body&lt;br /&gt;
double ae = 6378137.0;&lt;br /&gt;
// flatness of the celestial body&lt;br /&gt;
double f = 1.0 / 298.257222101;&lt;br /&gt;
// date        &lt;br /&gt;
AbsoluteDate date = AbsoluteDate.J2000_EPOCH;&lt;br /&gt;
// reference frame attached to the body        &lt;br /&gt;
CelestialBodyFrame frame = FramesFactory.getITRF();&lt;br /&gt;
// body shape model (ellipsoid)     &lt;br /&gt;
OneAxisEllipsoid model = new OneAxisEllipsoid(ae, f, frame);&lt;br /&gt;
&lt;br /&gt;
// transformation with jacobian matrix : cartesian to geodetic&lt;br /&gt;
&lt;br /&gt;
// initial cartesian point that will be transformed&lt;br /&gt;
Vector3D cp = new Vector3D(4637885.347, 121344.1308, 4362452.869);&lt;br /&gt;
// coresponding ellipsoid point        &lt;br /&gt;
EllipsoidPoint point = model.buildPoint(cp, frame, date, &amp;quot;point&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// transformation with jacobian matrix : geodetic to cartesian&lt;br /&gt;
&lt;br /&gt;
// coresponding Cartesian point        &lt;br /&gt;
Vector3D cp2 = model.computePositionFromEllipsodeticCoordinates(0.852479154923577, 0.0423149994747243, 111.6);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be also interesting to obtain the jacobian matrix of the transformation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// transformation : cartesian to geodetic&lt;br /&gt;
&lt;br /&gt;
final double[][] computedJacobian = LLHCoordinatesSystem.ELLIPSODETIC.jacobianFromCartesian(point);&lt;br /&gt;
&lt;br /&gt;
// transformation : geodetic to cartesian&lt;br /&gt;
&lt;br /&gt;
final double[][] computedJacobian2 = LLHCoordinatesSystem.ELLIPSODETIC.jacobianToCartesian(point);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The enumeration LLHCoordinatesSystem.ELLIPSODETIC allows the computation of the time derivatives of the LLH coordinates of a point. There are two algorithms implemented: &lt;br /&gt;
* Analytical calculation for OneAxisEllipsoid &lt;br /&gt;
* Finite-difference numerical calculation for all other types of ellipsoid, such as ThreeAxisEllipsoid&lt;br /&gt;
&lt;br /&gt;
The selection between the analytical and numerical method is automatic and the only function to call is the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double[] LLHCoordinatesSystem.ELLIPSODETIC.computeLLHRates(final BodyShape bodyShape, final PVCoordinates pv, final Frame frame, &lt;br /&gt;
final AbsoluteDate date) &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The longitude, latitude, and height rates are returned and expressed in rad/s, rad/s, et m/s respectively.&lt;br /&gt;
&lt;br /&gt;
Here is a full example of how to use this functionality:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Create Earth OneAxisEllipsoid&lt;br /&gt;
final double ae = 6378137.0;// GRS80 constant&lt;br /&gt;
final double flattening = 1.0 / 298.257222101;// GRS80 constant&lt;br /&gt;
final CelestialBodyFrame itrf = FramesFactory.getITRF();&lt;br /&gt;
final CelestialBodyFrame gcrf = FramesFactory.getGCRF();&lt;br /&gt;
final OneAxisEllipsoid earth = new OneAxisEllipsoid(ae, flattening, itrf);&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2010, 7, 9, 20, 30, 0);&lt;br /&gt;
&lt;br /&gt;
// Create orbit around the Earth in GCRF&lt;br /&gt;
final double mu = 3.986005e14;// GRS80 constant&lt;br /&gt;
final KeplerianOrbit orbit = KeplerianOrbit(ae + 700e3, 0.0, 0.5, 1.2, 1.1, 2.3, PositionAngle.TRUE, gcrf, date, mu);&lt;br /&gt;
&lt;br /&gt;
// Compute the rates using the analytical implementation&lt;br /&gt;
final double[] rates = LLHCoordinatesSystem.ELLIPSODETIC&lt;br /&gt;
                .computeLLHRates(earth, orbit.getPVCoordinates(), gcrf, date);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ApparentRadiusProvider&#039;&#039;&#039;&lt;br /&gt;
|Interface representing apparent radius providers.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/ApparentRadiusProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BodyShape&#039;&#039;&#039;&lt;br /&gt;
|Interface representing the rigid surface shape of a natural body.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/BodyShape.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBody&#039;&#039;&#039;&lt;br /&gt;
|Interface for celestial bodies like Sun, Moon or solar system planets.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/CelestialBody.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBodyEphemeris&#039;&#039;&#039;&lt;br /&gt;
|Interface for celestial body ephemeris like Sun, Moon or solar system planets.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/CelestialBodyEphemeris.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBodyLoader&#039;&#039;&#039;&lt;br /&gt;
|Interface for celestial body loaders.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/CelestialBodyLoader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBodyEphemerisLoader&#039;&#039;&#039;&lt;br /&gt;
|Interface for celestial body ephemeris loaders.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/CelestialBodyEphemerisLoader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MeshLoader&#039;&#039;&#039;&lt;br /&gt;
|Interface for FacetCelestialBody mesh provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/mesh/MeshProvider.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBodyFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory class for bodies of the solar system.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/CelestialBodyFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BodyPoint&#039;&#039;&#039;&lt;br /&gt;
|Point location relative to a 2D body surface.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/GeodeticPoint.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;JPLCelestialBodyLoader&#039;&#039;&#039;&lt;br /&gt;
|Loader for JPL ephemerides binary files (DE 405, DE 406, ...).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/JPLCelestialBodyLoader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OneAxisEllipsoid&#039;&#039;&#039;&lt;br /&gt;
|Modeling of a one-axis ellipsoid.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/OneAxisEllipsoid.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ThreeAxisEllipsoid&#039;&#039;&#039;&lt;br /&gt;
|Modeling of a tri-axis ellipsoid.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/ThreeAxisEllipsoid.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MeeusSun&#039;&#039;&#039;&lt;br /&gt;
|Position of the Sun according to Meeus model. Three models with there appropriate equations are avaible : the standard model (former MeeusSun), Stela model (former MeeuSunStela) and an on-board model&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/MeeusSun.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MeeusMoon&#039;&#039;&#039;&lt;br /&gt;
|Position of the Moon according to Meeus model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/MeeusMoon.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BasicBoardSun&#039;&#039;&#039;&lt;br /&gt;
|Direction of the Sun according to a basic board Sun model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/BasicBoardSun.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UserCelestialBody&#039;&#039;&#039;&lt;br /&gt;
|User-defined celestial body&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/UserCelestialBody.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UserIAUPole&#039;&#039;&#039;&lt;br /&gt;
|User-defined IAU pole motion&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/UserIAUPole.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IAUPoleFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory for retrieval of solar system bodies IAU pole data&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/IAUPoleFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IAUPoleFunction&#039;&#039;&#039;&lt;br /&gt;
|Atomic IAU pole function. IAU pole data is the sum of atomic IAUPoleFunction.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/IAUPoleFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FacetBodyShape&#039;&#039;&#039;&lt;br /&gt;
|Celestial body defined by a mesh.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/mesh/FacetBodyShape.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BodyShapeFitter&#039;&#039;&#039;&lt;br /&gt;
|Fitter for a given body shape provided as input.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/mesh/BodyShapeFitter.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Triangle&#039;&#039;&#039;&lt;br /&gt;
|Unitary facet (triangle) for a FacetCelestialBody.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/mesh/Triangle.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ObjMeshLoader&#039;&#039;&#039;&lt;br /&gt;
|.obj 3D file mesh loader.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/mesh/ObjMeshLoader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeodeticMeshLoader&#039;&#039;&#039;&lt;br /&gt;
|Mesh loader for ASCII files describing the body with latitude/longitude/altitude components (1 per line).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/mesh/GeodeticMeshLoader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Environment_Models&amp;diff=4171</id>
		<title>User Manual 4.18 Environment Models</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Environment_Models&amp;diff=4171"/>
		<updated>2026-06-10T10:43:59Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The scope of this section is to present the physical models available through the Patrius library.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
All the classes related to physical models are in the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.parameter&amp;lt;/code&amp;gt;packages. The classes related to reading potential files are in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.potential&amp;lt;/code&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/package-summary.html Package fr.cnes.sirius.patrius.forces.atmospheres]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/package-summary.html Package fr.cnes.sirius.patrius.forces.atmospheres.solarActivity]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/package-summary.html Package fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.specialized]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/package-summary.html Package fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.specialized]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/package-summary.html Package fr.cnes.sirius.patrius.forces.gravity.potential]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/variations/package-summary.html Package fr.cnes.sirius.patrius.forces.gravity.variations]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/package-summary.html Package fr.cnes.sirius.patrius.forces.gravity.tides.coefficients]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/package-summary.html Package fr.cnes.sirius.patrius.math.parameter]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/ReferencePointsDisplacement.html Class fr.cnes.sirius.patrius.utils.ReferencePointsDisplacement]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
Some useful links are given hereunder.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IERS Page&#039;&#039;&#039;&lt;br /&gt;
[http://www.iers.org/IERS/EN/Publications/TechnicalNotes/tn36.html IERS Conventions (2010), Technical Note No.36]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Project Pages&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://cddis.nasa.gov/ NASA - Crustal Dynamics Data Information System (CDDIS)]&lt;br /&gt;
* [http://op.gfz-potsdam.de/grace/ GFZ - Grace (Gravity Recovery and Climate Experiment) Mission Homepage]&lt;br /&gt;
* [http://icgem.gfz-potsdam.de/ICGEM/ GFZ - International Centre for Global Earth Models]&lt;br /&gt;
* [http://grgs.obs-mip.fr Groupe de Recherche de Géodésie Spatiale]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results Pages&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;EGM96: The NASA GSFC and NIMA Joint Geopotential Model&#039;&#039;, Lemoine; F. G., Kenyon; S. C., Factor; J. K., Trimmer; R.G., Pavlis; N. K., Chinn; D. S., Cox; C. M., Klosko; S. M., Luthcke; S. B., Torrence; M. H., Wang; Y. M., Williamson; R. G., Pavlis; E. C., Rapp; R. H., Olson; T. R., NASA Goddard Space Flight Center, Greenbelt, Maryland, 20771 USA, July 1998, Available [http://cddis.nasa.gov/926/egm96/egm96.html here].&lt;br /&gt;
* &#039;&#039;GFZ : Global Gravity Field Models&#039;&#039;, Available [http://icgem.gfz-potsdam.de/ICGEM/modelstab.html here].&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Earth Potential Models ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.potential&amp;lt;/code&amp;gt; package provides tools allowing the user to read external gravity potential data files. The following file formats are supported :&lt;br /&gt;
&lt;br /&gt;
* EGM96 ASCII format data&lt;br /&gt;
* EIGEN-GRACE format&lt;br /&gt;
* ICGEM format&lt;br /&gt;
* GRGS format&lt;br /&gt;
&lt;br /&gt;
Below is a diagram showing the architecture of the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.potential&amp;lt;/code&amp;gt; package.&lt;br /&gt;
&lt;br /&gt;
[[File:physicalModels.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
For a detailed explanation of the Data Management System, please refer to the [SUP_DMS_Home Data Management System section] of the Support User Manual.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.variations&amp;lt;/code&amp;gt; package provides tools allowing the user to read external variable gravity potential data files. The corresponding ForceModel is also included in the package. The following file formats are supported :&lt;br /&gt;
&lt;br /&gt;
* GRGS RL02&lt;br /&gt;
&lt;br /&gt;
Below is a diagram showing the architecture of the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.variations&amp;lt;/code&amp;gt; package.&lt;br /&gt;
&lt;br /&gt;
[[File:varPOT.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;VariableGravityFieldFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;GRGSRL02FormatReader&amp;lt;/code&amp;gt;: GRGSR L02 file format&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for variable gravity field computation.&lt;br /&gt;
&lt;br /&gt;
=== Atmosphere models and solar activity model ===&lt;br /&gt;
==== Generalities about Solar Activity and Atmospheres ====&lt;br /&gt;
&lt;br /&gt;
The atmospheres make use of solar activity in order to compute the density at the given user location excepted US76 model that is only based on altitude parameters. The PATRIUS architecture of atmospheres and solar activity is divided into three layers :&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Atmospheres use solar data in specific ways&#039;&#039;&#039;&lt;br /&gt;
Each atmosphere model uses the solar data in a specific way (more simply, US76 doesn&#039;t use solar data). These representations are enclosed in the atmosphere model specific interfaces, such as [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/DTMInputParameters.html DTMInputParamters]. Atmosphere models available include US76 (for low altitudes in range 0 to 1000km), DTM2000, DTM2012 and MSISE2000.&lt;br /&gt;
*&#039;&#039;&#039;Reading and storing solar data&#039;&#039;&#039;&lt;br /&gt;
The way to store the solar data is enclosed in the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataProvider.html SolarActivityDataProvider interface]. It defines the basic coefficients (Ap, Kp and F10.7 cm) that any solar activity data provider class should be able to return, in order to be compatible with the atmosphere specific implementations (see next point). The [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/package-summary.html solarActivity package] contains classes that can read different file formats and can return the solar activity data. So far, one class for each of the ACSOL and NOAA formats has been implemented. Additionally, one class representing constant solar activity (that requires no external file) has been implemented.&lt;br /&gt;
*&#039;&#039;&#039;Using the solar data in an adequate fashion&#039;&#039;&#039;&lt;br /&gt;
Making effective use of the solar data for specific atmospheres requires an object that provides solar data (implementing the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataProvider.html SolarActivityDataProvider]) and answers to the interfaces that define the ways in which the atmosphere models use this data (e.g. implementing  [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/DTM2000InputParameters.html DTMInputParameters]). These classes are contained in the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/package-summary.html fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.specialized package]). So far, one class for each of the DTM2000/DTM2012 and MSISE2000 models have been implemented.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.atmospheres.solarActivity&amp;lt;/code&amp;gt; package follows the same architecture as the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.potential&amp;lt;/code&amp;gt; package. The user must use the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataFactory.html SolarActivityDataFactory class].&lt;br /&gt;
&lt;br /&gt;
For a detailed explanation of the Data Management System, please refer to the [SUP_DMS_Home Data Management System section] of the Support User Manual.&lt;br /&gt;
&lt;br /&gt;
For performances reasons, numerical propagator checks availability of solar activity data at start of propagation and not at every solar activity data call. If required solar activity or geomagnetic activity does not cover the required range by the atmospheric model, an exception is returned.&lt;br /&gt;
&lt;br /&gt;
==== Atmospheric models ====&lt;br /&gt;
&lt;br /&gt;
Various models are available in PATRIUS: DTM-2000, DTM-2012, MSIS-00, US76, etc. all models inherit the &amp;lt;code&amp;gt;Atmosphere&amp;lt;/code&amp;gt; interface providing total density information.&amp;lt;br&amp;gt;&lt;br /&gt;
DTM and MSIS models also implement the &amp;lt;code&amp;gt;ExtendedAtmosphere&amp;lt;/code&amp;gt; interface which provides more detailed data such as temperature and partial densities of atmosphere constituents.&amp;lt;br&amp;gt;&lt;br /&gt;
Some models require solar and geomagnetic information (see below for how to provide solar and geomagnetic data).&lt;br /&gt;
&lt;br /&gt;
===== MSIS2000 Atmosphere model =====&lt;br /&gt;
&lt;br /&gt;
The NRLMSIS series represents the gold standard for empirical neutral atmosphere models, used to predict temperature, density, and composition from the ground to the exosphere. The transition from NRLMSISE-00 (released in 2013) to NRLMSIS 2.0 (released in 2020) marks a significant leap in modeling accuracy and architectural design. PATRIUS implements both models.&lt;br /&gt;
&lt;br /&gt;
Key Differences&lt;br /&gt;
&lt;br /&gt;
* NRLMSISE00 (or NRLMSIS 1.0):&lt;br /&gt;
** Relies on older mass spectrometer and incoherent scatter radar data. While robust, it often overestimates densities during extreme solar minimums and struggles with the precise &amp;quot;satellite drag&amp;quot; modeling required for modern space situational awareness.&lt;br /&gt;
** Models the primary species (He, O, N2, O, Ar, H, N) and includes an &amp;quot;anomalous oxygen&amp;quot; component to account for satellite drag discrepancies.&lt;br /&gt;
&lt;br /&gt;
* NRLMSISE20 (or NRLMSIS 2.0):&lt;br /&gt;
** Incorporates decades of new data, including extensive satellite accelerometer measurements and improved occultation data. It is significantly more accurate in the thermosphere and exosphere, particularly during low solar activity.&lt;br /&gt;
** Introduces a more rigorous treatment of atomic species. Notably, it includes Atomic Nitrogen (N) and Nitric Oxide (NO) as intrinsic parts of the model (though, as you noted in your previous translation, some implementations may still exclude NO depending on the reference version used). It also ensures better mass-density consistency.&lt;br /&gt;
** Version 2.0 enforces stricter physical constraints between temperature and density profiles, ensuring that the transition between the lower atmosphere and the thermosphere is physically smoother.&lt;br /&gt;
&lt;br /&gt;
Note that a new model NRLMSIS 2.1 has been presented in 2025. This model is not implemented yet in PATRIUS.&lt;br /&gt;
&lt;br /&gt;
More information can be found at the [http://www.nrl.navy.mil/research/nrl-review/2003/atmospheric-science/picone/ Naval Research Laboratory website] and [https://map.nrl.navy.mil/map/pub/nrl/NRLMSIS/ Geospace Science &amp;amp; Technology Branch]. Note that several adaptations have been made to optimize the JAVA model compare to these FORTRAN models.&lt;br /&gt;
&lt;br /&gt;
In order to use this atmosphere model, the user must proceed by giving the following arguments as inputs to the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/MSISE2000.html MSISE2000] class :&lt;br /&gt;
&lt;br /&gt;
* The empirical atmosphere model it self (NRLMSISE00 or NRLMSISE20)&lt;br /&gt;
* Solar activity data (as a [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/MSISE2000InputParameters.html MSISE2000InputParameters])&lt;br /&gt;
* the Earth model (as a [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/bodies/BodyShape.html BodyShape])&lt;br /&gt;
* the Sun model (as a [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/bodies/CelestialBody.html CelestialBody])&lt;br /&gt;
&lt;br /&gt;
The following code snippet creates an instance of MSISE2000 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
 // Create an instance of the BodyShape &amp;quot;EARTH&amp;quot;, with user chosen&lt;br /&gt;
 // equatorial radius, flattening and body frame&lt;br /&gt;
 Frame frame = FramesFactory.getITRF();&lt;br /&gt;
 double f = 0.29825765000000E+03;&lt;br /&gt;
 double ae = 6378136.46;&lt;br /&gt;
 BodyShape earth = new OneAxisEllipsoid(ae, 1 / f, frame);&lt;br /&gt;
&lt;br /&gt;
 // Get the instance of the CelestialBody &amp;quot;SUN&amp;quot;&lt;br /&gt;
 CelestialBody sun = CelestialBodyFactory.getSun();&lt;br /&gt;
&lt;br /&gt;
 // Create the solar activity data to be used&lt;br /&gt;
 SolarActivityDataProvider solarActivity = SolarActivityDataFactory.getSolarActivityDataProvider();&lt;br /&gt;
 final MSISE2000InputParameters msiseData = new ClassicalMSISE2000SolarData(solarActivity);&lt;br /&gt;
&lt;br /&gt;
 // Create an instance of the atmosphere model&lt;br /&gt;
 Atmosphere atmosModel = new MSISE2000(new NRLMSISE00(), msiseData , earth, sun);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: the NRLMSISE-00 model is not continuous. There is a discontinuity every day (at 0h in UTC time scale). Discontinuities are however very small (1E-3 on a relative scale).&lt;br /&gt;
&lt;br /&gt;
The main difference in usage between the models NRLMSISE-00 and NRLMSIS 2.0 is that :&lt;br /&gt;
&lt;br /&gt;
* NRLMSISE-00 uses a “Flags” container to define the model’s specific settings every time we call the gtd7d(Input, Flags) method&lt;br /&gt;
* NRLMSIS 2.0 doesn’t use the “Flags” container when calling the gtd7d(Input, Flags). Instead, the model is configured once in its constructor by providing a specific MSISInit instance.&lt;br /&gt;
&lt;br /&gt;
==== Solar and geomagnetic activity ====&lt;br /&gt;
&lt;br /&gt;
Solar and geomagnetic activity can be provided in various ways:&lt;br /&gt;
* Constant solar activity using:&amp;lt;br&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final SolarActivityDataProvider constantSolarActivity = new ConstantSolarActivity(140, 15);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Variable solar activity using (for instance):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final SolarActivityDataProvider variableSolarActivity = new NOAAFormatReader(...);&lt;br /&gt;
final SolarActivityDataProvider otherVariableSolarActivity = new ACSOLFormatReader(...);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solar and geomagnetic activity data often having a limited timespan, the class &amp;lt;code&amp;gt;ExtendedSolarActivityWrapper&amp;lt;/code&amp;gt; allows data extension with constant values. Solar and geomagnetic data returned before timespan are equals to an average of first available data (the average duration being user-chosen). Solar and geomagnetic data returned after timespan are equals to an average of last available data (the average duration being user-chosen). Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final SolarActivityDataProvider innerProvider = new NOAAFormatReader() // Variable solar activity over a given timespan&lt;br /&gt;
final double duration = 86400; // Duration on which average solar activity will be computed if date out of innerProvider timespan&lt;br /&gt;
final ExtendedSolarActivityWrapper solarActivity = new ExtendedSolarActivityWrapper(innerProvider, duration)// Extended solar activity&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will create an solar activity whose value will be:&lt;br /&gt;
* Value of innerProvider if date is within innerProvider timespan&lt;br /&gt;
* Average value on [lower boundary, lower boundary + duration] if date is before innerProvider lower boundary&lt;br /&gt;
* Average value on [upper boundary- duration, upper boundary] if date is after innerProvider upperboundary&lt;br /&gt;
&lt;br /&gt;
These providers are used as inputs of atmospheric models.&lt;br /&gt;
&lt;br /&gt;
===== Reading Solar Activity Data files =====&lt;br /&gt;
&lt;br /&gt;
The data is read through the &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt; infrastructure; it provides several ways to load solar activity data. Please see the [SUP_DMS_Home Data Management System section] for more information.&lt;br /&gt;
&lt;br /&gt;
The following file formats are supported by PATRIUS:&lt;br /&gt;
* ACSOL format&lt;br /&gt;
* NOAA format&lt;br /&gt;
&lt;br /&gt;
The user access point is the &amp;lt;code&amp;gt;SolarActivityDataFactory&amp;lt;/code&amp;gt; which automatically detects available files and uses the adequate solar file reader. If no file is specified by the user, this factory uses the first available file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
//Directory containing the file ACSOL.act&lt;br /&gt;
final File potdir = new File(&amp;quot;/my/data/solar&amp;quot;);&lt;br /&gt;
//The directory is given to the data loader&lt;br /&gt;
DataProvidersManager.getInstance().addProvider(new DirectoryCrawler(potdir));&lt;br /&gt;
//The ACSOL file is registered in the SolarActivityDataFactory&lt;br /&gt;
//If it is the only solar activity file of the directory, this step is not necessary&lt;br /&gt;
SolarActivityDataFactory.addSolarActivityDataReader(new ACSOLFormatReader(&amp;quot;ACSOL.act&amp;quot;));&lt;br /&gt;
//A provider for the data is created&lt;br /&gt;
final SolarActivityDataProvider provider = SolarActivityDataFactory.getSolarActivityDataProvider();&lt;br /&gt;
//Get the ap, kp and instant flux at date&lt;br /&gt;
final AbsoluteDate userDate = new AbsoluteDate();&lt;br /&gt;
final double ap = provider.getAp( userDate );&lt;br /&gt;
final double kp = provider.getKp( userDate );&lt;br /&gt;
final double f = provider.getInstantFluxValue( userDate );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;SolarActivityDataFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;ACSOLFormatReader&amp;lt;/code&amp;gt;: ACSOL file format&lt;br /&gt;
*&amp;lt;code&amp;gt;NOAAFormatReader&amp;lt;/code&amp;gt;: NOAA file format&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for solar activity retrieval.&lt;br /&gt;
&lt;br /&gt;
=== Tides models ===&lt;br /&gt;
==== Tides model for force computation ====&lt;br /&gt;
&lt;br /&gt;
The PATRIUS &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.tides&amp;lt;/code&amp;gt; package provides tools allowing the user to use Terestrial and Ocean tides. The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.tides.coefficients&amp;lt;/code&amp;gt; package also allows reading external ocean tides coefficients data files. The following file formats are supported by PATRIUS:&lt;br /&gt;
* FES2004 format&lt;br /&gt;
&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;OceanTidesCoefficientFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;FES2004FormatReader&amp;lt;/code&amp;gt;: FES 2004 file format&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for ocean tides computation.&lt;br /&gt;
&lt;br /&gt;
==== Reference point displacement ====&lt;br /&gt;
&lt;br /&gt;
The PATRIUS &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.utils.ReferencePointsDisplacement&amp;lt;/code&amp;gt; class provides a model describing the displacement of reference points due to the effect of the solid Earth tides. The computation is performed by the static method &#039;&#039;&#039;solidEarthTidesCorrections(AbsoluteDate, Vector3D, Vector3D, Vector3D)&#039;&#039;&#039;. The implemented model has been validated by comparison with tests available in the IERS website. The example below shows the user how to compute displacements of reference points:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Test from source ftp://tai.bipm.org/iers/convupdt/chapter7/dehanttideinel/DEHANTTIDEINEL.F&lt;br /&gt;
&lt;br /&gt;
// date : 13/04/2009&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2009, 4, 13, 0, 0, 0., TimeScalesFactory.getUTC());&lt;br /&gt;
&lt;br /&gt;
// entries : moon position, sun position, station location&lt;br /&gt;
final Vector3D moon = new Vector3D(-179996231.920342,-312468450.131567, -169288918.592160);&lt;br /&gt;
final Vector3D sun = new Vector3D(137859926952.015, 54228127881.4350, 23509422341.6960);&lt;br /&gt;
final Vector3D point = new Vector3D(4075578.385, 931852.890, 4801570.154);&lt;br /&gt;
&lt;br /&gt;
// compute the displacement&lt;br /&gt;
final Vector3D disp = ReferencePointsDisplacement.solidEarthTidesCorrections(date, point, sun, moon);&lt;br /&gt;
&lt;br /&gt;
// comparison with reference results (IERS)&lt;br /&gt;
Assert.assertEquals(0.07700420357108125891, disp.getX(), Precision.EPSILON);&lt;br /&gt;
Assert.assertEquals(0.06304056321824967613, disp.getY(), Precision.EPSILON);&lt;br /&gt;
Assert.assertEquals(0.05516568152597246810, disp.getZ(), Precision.EPSILON);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geomagnetic models ===&lt;br /&gt;
==== Design ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.models.earth&amp;lt;/code&amp;gt; package provides tools allowing the user to use different geomagnetic models. For the moment, there are only the two following models available :&lt;br /&gt;
* IGRF 11  : International Geomagnetic Reference Field eleventh generation&lt;br /&gt;
* WMM 2010 : World Magnetic Model published in december 2009&lt;br /&gt;
&lt;br /&gt;
A class diagram is given hereunder to show how geomagnetic is read and used in the library :&lt;br /&gt;
&lt;br /&gt;
[[File:geomaguml.png]]&lt;br /&gt;
&lt;br /&gt;
The user can create its own [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticModelReader.html GeoMagneticModelReader] in order to provide [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticField.html GeoMagneticField] from any file format.&lt;br /&gt;
&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;GeoMagneticFieldFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;COFFileFormatReader&amp;lt;/code&amp;gt;: COF file format&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for geomagnetic field computation (IGRF and WMM).&lt;br /&gt;
&lt;br /&gt;
==== IGRF 11 geomagnetic model ====&lt;br /&gt;
&lt;br /&gt;
The International Geomagnetic Reference Field (IGRF) was introduced by the International Association of Geomagnetism and Aeronomy (IAGA) in 1968 in response to the demand for a standard spherical harmonic representation of the Earth&#039;s main field. The model is updated at 5-yearly intervals, the latest being the 11th generation, produced and released by IAGA Working Group V-MOD (formerly V-8) December 2009. &lt;br /&gt;
&lt;br /&gt;
More information can be found at the [http://www.ngdc.noaa.gov/IAGA/vmod/index.html IAGA Division V-Mod].&lt;br /&gt;
&lt;br /&gt;
==== WMM 2010 geomagnetic model ====&lt;br /&gt;
&lt;br /&gt;
The World Magnetic Model is a joint product of the United States’ National Geospatial-Intelligence Agency (NGA) and the United Kingdom’s Defence Geographic Centre (DGC). The WMM was developed jointly by the National Geophysical Data Center (NGDC, Boulder CO, USA) and the British Geological Survey (BGS, Edinburgh, Scotland). &lt;br /&gt;
&lt;br /&gt;
The World Magnetic Model is the standard model used by the U.S. Department of Defense, the U.K. Ministry of Defence, the North Atlantic Treaty Organization (NATO) and the International Hydrographic Organization (IHO), for navigation, attitude and heading referencing systems using the geomagnetic field. It is also used widely in civilian navigation and heading systems. The model, associated software, and documentation are distributed by NGDC on behalf of NGA. The model is produced at 5-year intervals, with the current model expiring on December 31, 2014.&lt;br /&gt;
&lt;br /&gt;
The current model, WMM2010 (published 12/2009)&lt;br /&gt;
&lt;br /&gt;
More information can be found at the [http://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml National Oceanic and Atmospheric Administration].&lt;br /&gt;
&lt;br /&gt;
==== Details, limitation and precautions ====&lt;br /&gt;
&lt;br /&gt;
In the geomagnetic field&#039;s computation from the different models, to convert geodetic coordinates (defined by the WGS-84 reference ellipsoid) to Earth Centered spherical coordinates, the following constants are used :&lt;br /&gt;
&lt;br /&gt;
* Semi major-axis of WGS-84 ellipsoid : 6378.137 km&lt;br /&gt;
* The first eccentricity squared : 0.0066943799901413169961&lt;br /&gt;
&lt;br /&gt;
and to compute the spherical harmonic variables for a given spherical coordinate uses the mean radius of IAU-66 ellipsoid 6371.2 km is used.&lt;br /&gt;
&lt;br /&gt;
The different models are used to compute gemoagnetic field near earth surface. In the model file, the given altitude range of validity is-1 to 600 km even if we can compute field outside of this range.&lt;br /&gt;
&lt;br /&gt;
The method GeoMagneticField.calculateField(final Vector3D point,final Frame frame, final AbsoluteDate date) has been added to Patrius and allows to compute the field from a position vector in a specific frame and at a specific date. This method is based on tranformModel method which recomputes the field at a date. This method doesn&#039;t work if the model doesn&#039;t support time transform. In this way, this method added to Patrius throws a Patrius exception about model not supporting time transform.&lt;br /&gt;
&lt;br /&gt;
Here is the list of all possible actual models and the time transform support (please note that only dates prior to 2010 won&#039;t support time transformation) :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Model and associated data file&lt;br /&gt;
| Model Name&lt;br /&gt;
| Validity Period&lt;br /&gt;
| Time transform support&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;23&amp;quot;|IGRF (&#039;&#039;GeoMagneticFieldFactory.getIGRF(..)&#039;&#039; uses IGRF.COF)&lt;br /&gt;
| IGRF00&lt;br /&gt;
| 1900.0 - 1905.0&lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
| IGRF05&lt;br /&gt;
| 1905.0 - 1910.0&lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
| IGRF10 &lt;br /&gt;
| 1910.0 - 1915.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF15 &lt;br /&gt;
| 1915.0 - 1920.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF20 &lt;br /&gt;
| 1920.0 - 1925.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF25 &lt;br /&gt;
| 1925.0 - 1930.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF30 &lt;br /&gt;
| 1930.0 - 1935.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF35 &lt;br /&gt;
| 1935.0 - 1940.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF40 &lt;br /&gt;
| 1940.0 - 1945.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF45 &lt;br /&gt;
| 1945.0 - 1950.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF50 &lt;br /&gt;
| 1950.0 - 1955.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF55 &lt;br /&gt;
| 1955.0 - 1960.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF60 &lt;br /&gt;
| 1960.0 - 1965.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF65 &lt;br /&gt;
| 1965.0 - 1970.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF70 &lt;br /&gt;
| 1970.0 - 1975.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF75 &lt;br /&gt;
| 1975.0 - 1980.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF80 &lt;br /&gt;
| 1980.0 - 1985.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF85 &lt;br /&gt;
| 1985.0 - 1990.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF90 &lt;br /&gt;
| 1990.0 - 1995.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF95 &lt;br /&gt;
| 1995.0 - 2000.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF2000 &lt;br /&gt;
| 2000.0 - 2005.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF2005 &lt;br /&gt;
| 2005.0 - 2010.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF2010 &lt;br /&gt;
| 2010.0 - 2015.0 &lt;br /&gt;
| true&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;|WMM (&#039;&#039;GeoMagneticFieldFactory.getWMM(..)&#039;&#039; uses WMM.COF)&lt;br /&gt;
| WMM2010 &lt;br /&gt;
| 2010.0 - 2015.0&lt;br /&gt;
| true&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Precautions :&lt;br /&gt;
The method GeoMagneticField.calculateField (final double latitude, final double longitude, final double height) doesn&#039;t use SI units. Latitude and longitude are given in degrees, and height is given in kilometers.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
==== Code Example ====&lt;br /&gt;
&lt;br /&gt;
The following code sample computes geomagnetic field elements for four (date, position) of a fake trajectory :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
    public void codeExemple() throws PatriusException {&lt;br /&gt;
&lt;br /&gt;
        Utils.setDataRoot(&amp;quot;earth&amp;quot;);&lt;br /&gt;
        FramesFactory.setConfiguration(Utils.getIERS2003ConfigurationWOEOP(true));&lt;br /&gt;
&lt;br /&gt;
        //Fake trajectory : list of date and list of position&lt;br /&gt;
        List&amp;lt;AbsoluteDate&amp;gt; dateList = new ArrayList&amp;lt;AbsoluteDate&amp;gt;();&lt;br /&gt;
        AbsoluteDate initDate = new AbsoluteDate(2010, 1, 1, 12, 0, 0.0, TimeScalesFactory.getTT());&lt;br /&gt;
        &lt;br /&gt;
        dateList.add(initDate);&lt;br /&gt;
        dateList.add(new AbsoluteDate(initDate, 600));&lt;br /&gt;
        dateList.add(new AbsoluteDate(initDate, 1200));&lt;br /&gt;
        dateList.add(new AbsoluteDate(initDate, 1800));&lt;br /&gt;
        &lt;br /&gt;
        List&amp;lt;Vector3D&amp;gt; positionList = new ArrayList&amp;lt;Vector3D&amp;gt;();&lt;br /&gt;
        positionList.add(new Vector3D(6.46885878304673824e+06,-1.88050918456274318e+06, -1.32931592294715829e+04));&lt;br /&gt;
        positionList.add(new Vector3D(6.58239141552595049e+06,-1.43349476017528563e+06, -1.39460373997706010e+04));&lt;br /&gt;
        positionList.add(new Vector3D(6.66499609614125639e+06,-9.79745192516532145e+05, -1.45334684008149434e+04));&lt;br /&gt;
        positionList.add(new Vector3D(6.71628402448997274e+06,-5.21392324304617418e+05, -1.50526405214286660e+04));&lt;br /&gt;
        &lt;br /&gt;
        // Get the model to the initial date&lt;br /&gt;
        final GeoMagneticField model = GeoMagneticFieldFactory.getIGRF(dateList.get(0));&lt;br /&gt;
        &lt;br /&gt;
        // For each date and position, compute the GeoMagneticElement and add it to a list&lt;br /&gt;
        List&amp;lt;GeoMagneticElements&amp;gt; geoMagList = new ArrayList&amp;lt;GeoMagneticElements&amp;gt;();&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        for (AbsoluteDate date : dateList){&lt;br /&gt;
            geoMagList.add(model.calculateField(positionList.get(i), FramesFactory.getEME2000(), date));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Print each field vector B &lt;br /&gt;
        for (GeoMagneticElements geoMagElement : geoMagList){&lt;br /&gt;
            System.out.println(geoMagElement.toString());&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code produces the following standard output :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;MagneticField[B={29817,109;-2303,065; -9138,097},H=29905,92,F=31270,895,I=-16,991,D=-4,417]&lt;br /&gt;
MagneticField[B={29442,018;-2166,283; -8949,299},H=29521,606,F=30848,261,I=-16,864,D=-4,208]&lt;br /&gt;
MagneticField[B={29067,408;-1996,393; -8794,324},H=29135,885,F=30434,19,I=-16,796,D=-3,929]&lt;br /&gt;
MagneticField[B={28695,713;-1796,821; -8680,411},H=28751,913,F=30033,681,I=-16,799,D=-3,583]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Atmosphere&#039;&#039;&#039;&lt;br /&gt;
|Interface for atmospheric models.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/Atmosphere.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ExtendedAtmosphere&#039;&#039;&#039;&lt;br /&gt;
|Interface for atmospheric models with detailed data.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/ExtendedAtmosphere.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SolarActivityDataProvider&#039;&#039;&#039;&lt;br /&gt;
|Interface for solar activity data providers, to be used for atmosphere models&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DTM2000InputParameters&#039;&#039;&#039;&lt;br /&gt;
|Container for solar activity data, compatible with DTM Atmosphere models.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/DTMInputParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MSISE2000InputParameters&#039;&#039;&#039;&lt;br /&gt;
|Container for solar activity data, compatible with MSISE2000 Atmosphere model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/MSISE2000InputParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTidesCoefficientsProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide ocean tides coefficients.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PotentialCoefficientsProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide gravity field coefficients.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/PotentialCoefficientsProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VariablePotentialCoefficientsProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide variable gravity field coefficients.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/variations/coefficients/VariablePotentialCoefficientsProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RadiationSensitive&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide an direct solar radiative pressure model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/radiation/RadiationSensitive.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RediffusedRadiationSensitive&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide an rediffused radiative pressure model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/radiation/RediffusedRadiationSensitive.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticDataProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is a generic geomagnetic data provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticDataProvider.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&#039;&#039;&#039;Earth potential&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EGMFormatReader&#039;&#039;&#039;&lt;br /&gt;
|This reader is adapted to the EGM Format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/EGMFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GravityFieldFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory used to read gravity field files in several supported formats. &#039;&#039;&#039;Main user access point&#039;&#039;&#039; : the simple way of reading a potential file is by using this factory.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/GravityFieldFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VariableGravityFieldFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory used to read variable gravity field files in several supported formats. &#039;&#039;&#039;Main user access point&#039;&#039;&#039; : the simple way of reading a variable potential file is by using this factory.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/variations/coefficients/VariableGravityFieldFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GRGSFormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for the GRGS gravity field format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/GRGSFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GRGSRL02FormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for the GRGS RL02 variable gravity field format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/variations/coefficients/GRGSRL02FormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ICGEMFormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for the ICGEM gravity field format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/ICGEMFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PotentialCoefficientsReader&#039;&#039;&#039;&lt;br /&gt;
|This abstract class represents a Gravitational Potential Coefficients file reader.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/PotentialCoefficientsReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SHMFormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for the SHM gravity field format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/SHMFormatReader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Atmosphere Models&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DTM2000&#039;&#039;&#039;&lt;br /&gt;
|This class implements the DTM2000 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/DTM2000.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DTM2012&#039;&#039;&#039;&lt;br /&gt;
|This class implements the DTM2012 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/DTM2012.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;JB2006&#039;&#039;&#039;&lt;br /&gt;
|This class implements the JB2006 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/JB2006.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MSISE2000&#039;&#039;&#039;&lt;br /&gt;
|This class implements the MSIS atmospheric model (from a NRLMSIS sub-model).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/MSISE2000.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NRLMSISE00&#039;&#039;&#039;&lt;br /&gt;
|This class implements the NRLMSIS 1.0 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/MSIS/NRLMSISE00.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NRLMSISE20&#039;&#039;&#039;&lt;br /&gt;
|This class implements the NRLMSIS 2.0 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/MSIS/NRLMSISE20.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;US76&#039;&#039;&#039;&lt;br /&gt;
|This class implements the US76 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/US76.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solar Activity&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DTMSolarData&#039;&#039;&#039;&lt;br /&gt;
|This class represents a solar data container adapted for the DTM atmosphere models.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/DTMSolarData.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ClassicalMSISE2000SolarData&#039;&#039;&#039;&lt;br /&gt;
|This class represents a solar data container adapted for the MSISE2000 atmosphere model. The average ap values are computed arithmetically.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/ClassicalMSISE2000SolarData.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ContinuousMSISE2000SolarData&#039;&#039;&#039;&lt;br /&gt;
|This class represents a solar data container adapted for the MSISE2000 atmosphere model. The mean ap values are computed by trapezoidal integration.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/ContinuousMSISE2000SolarData.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ACSOLFormatReader&#039;&#039;&#039;&lt;br /&gt;
|This class reads ACSOL format solar activity data&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/ACSOLFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ConstantSolarActivity&#039;&#039;&#039;&lt;br /&gt;
|This class represents constant solar activity&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/ConstantSolarActivity.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NOAAFormatReader&#039;&#039;&#039;&lt;br /&gt;
|This class reads NOAA format solar activity data&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/NOAAFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SolarActivityDataFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory used to read solar activity files and return SolarActivityDataProvider&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SolarActivityToolbox&#039;&#039;&#039;&lt;br /&gt;
|Solar activity toolbox. Has methods to compute mean flux values, to convert from ap to kp.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityToolbox.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MarshallSolarActivityFutureEstimation&#039;&#039;&#039;&lt;br /&gt;
|This class reads and provides solar activity data needed by atmospheric models: F107 solar flux and Kp indexes.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/MarshallSolarActivityFutureEstimation.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ExtendedSolarActivityWrapper&#039;&#039;&#039;&lt;br /&gt;
|This class extends a solar activity provider out of its timespan with constant values.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/ExtendedSolarActivityWrapper.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ocean Tides Coefficients&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FES2004FormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for FES2004 format coefficients files.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/FES2004FormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTidesCoefficientsFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory used to read ocean tides coefficients files in different formats and return an OceanTidesCoefficientsProvider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTidesCoefficientsReader&#039;&#039;&#039;&lt;br /&gt;
|This abstract class represents a Ocean Tides Coefficients file reader.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTidesCoefficientsSet&#039;&#039;&#039;&lt;br /&gt;
|Represents a line from the ocean tides data file.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsSet.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Geomagnetic Field&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticElements&#039;&#039;&#039;&lt;br /&gt;
|This class contains all the elements about a magnetic field : the magnetic field vector and associated caracteristics Inclination, Declination, Total Intensity, Horizontal Intensity.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticElements.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticField&#039;&#039;&#039;&lt;br /&gt;
|These objects are produced by the factory and are based on a model for a decimal year date and allows to compute GeomagneticElements &lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticField.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticFieldFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory to produce GeoMagneticField.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticFieldFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticModelReader&#039;&#039;&#039;&lt;br /&gt;
|To load the model from an input file&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticModelReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;COFFileFormatReader&#039;&#039;&#039;&lt;br /&gt;
|Class loading the geomagnetic data from COF files.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/COFFileFormatReader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Orbit_Propagation]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Environment_Models&amp;diff=4170</id>
		<title>User Manual 4.18 Environment Models</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Environment_Models&amp;diff=4170"/>
		<updated>2026-06-10T10:42:25Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The scope of this section is to present the physical models available through the Patrius library.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
All the classes related to physical models are in the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.parameter&amp;lt;/code&amp;gt;packages. The classes related to reading potential files are in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.potential&amp;lt;/code&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/package-summary.html Package fr.cnes.sirius.patrius.forces.atmospheres]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/package-summary.html Package fr.cnes.sirius.patrius.forces.atmospheres.solarActivity]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/package-summary.html Package fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.specialized]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/package-summary.html Package fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.specialized]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/package-summary.html Package fr.cnes.sirius.patrius.forces.gravity.potential]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/variations/package-summary.html Package fr.cnes.sirius.patrius.forces.gravity.variations]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/package-summary.html Package fr.cnes.sirius.patrius.forces.gravity.tides.coefficients]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/package-summary.html Package fr.cnes.sirius.patrius.math.parameter]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/ReferencePointsDisplacement.html Class fr.cnes.sirius.patrius.utils.ReferencePointsDisplacement]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
Some useful links are given hereunder.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IERS Page&#039;&#039;&#039;&lt;br /&gt;
[http://www.iers.org/IERS/EN/Publications/TechnicalNotes/tn36.html IERS Conventions (2010), Technical Note No.36]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Project Pages&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://cddis.nasa.gov/ NASA - Crustal Dynamics Data Information System (CDDIS)]&lt;br /&gt;
* [http://op.gfz-potsdam.de/grace/ GFZ - Grace (Gravity Recovery and Climate Experiment) Mission Homepage]&lt;br /&gt;
* [http://icgem.gfz-potsdam.de/ICGEM/ GFZ - International Centre for Global Earth Models]&lt;br /&gt;
* [http://grgs.obs-mip.fr Groupe de Recherche de Géodésie Spatiale]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results Pages&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;EGM96: The NASA GSFC and NIMA Joint Geopotential Model&#039;&#039;, Lemoine; F. G., Kenyon; S. C., Factor; J. K., Trimmer; R.G., Pavlis; N. K., Chinn; D. S., Cox; C. M., Klosko; S. M., Luthcke; S. B., Torrence; M. H., Wang; Y. M., Williamson; R. G., Pavlis; E. C., Rapp; R. H., Olson; T. R., NASA Goddard Space Flight Center, Greenbelt, Maryland, 20771 USA, July 1998, Available [http://cddis.nasa.gov/926/egm96/egm96.html here].&lt;br /&gt;
* &#039;&#039;GFZ : Global Gravity Field Models&#039;&#039;, Available [http://icgem.gfz-potsdam.de/ICGEM/modelstab.html here].&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Earth Potential Models ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.potential&amp;lt;/code&amp;gt; package provides tools allowing the user to read external gravity potential data files. The following file formats are supported :&lt;br /&gt;
&lt;br /&gt;
* EGM96 ASCII format data&lt;br /&gt;
* EIGEN-GRACE format&lt;br /&gt;
* ICGEM format&lt;br /&gt;
* GRGS format&lt;br /&gt;
&lt;br /&gt;
Below is a diagram showing the architecture of the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.potential&amp;lt;/code&amp;gt; package.&lt;br /&gt;
&lt;br /&gt;
[[File:physicalModels.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
For a detailed explanation of the Data Management System, please refer to the [SUP_DMS_Home Data Management System section] of the Support User Manual.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.variations&amp;lt;/code&amp;gt; package provides tools allowing the user to read external variable gravity potential data files. The corresponding ForceModel is also included in the package. The following file formats are supported :&lt;br /&gt;
&lt;br /&gt;
* GRGS RL02&lt;br /&gt;
&lt;br /&gt;
Below is a diagram showing the architecture of the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.variations&amp;lt;/code&amp;gt; package.&lt;br /&gt;
&lt;br /&gt;
[[File:varPOT.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;VariableGravityFieldFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;GRGSRL02FormatReader&amp;lt;/code&amp;gt;: GRGSR L02 file format&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for variable gravity field computation.&lt;br /&gt;
&lt;br /&gt;
=== Atmosphere models and solar activity model ===&lt;br /&gt;
==== Generalities about Solar Activity and Atmospheres ====&lt;br /&gt;
&lt;br /&gt;
The atmospheres make use of solar activity in order to compute the density at the given user location excepted US76 model that is only based on altitude parameters. The PATRIUS architecture of atmospheres and solar activity is divided into three layers :&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Atmospheres use solar data in specific ways&#039;&#039;&#039;&lt;br /&gt;
Each atmosphere model uses the solar data in a specific way (more simply, US76 doesn&#039;t use solar data). These representations are enclosed in the atmosphere model specific interfaces, such as [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/DTMInputParameters.html DTMInputParamters]. Atmosphere models available include US76 (for low altitudes in range 0 to 1000km), DTM2000, DTM2012 and MSISE2000.&lt;br /&gt;
*&#039;&#039;&#039;Reading and storing solar data&#039;&#039;&#039;&lt;br /&gt;
The way to store the solar data is enclosed in the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataProvider.html SolarActivityDataProvider interface]. It defines the basic coefficients (Ap, Kp and F10.7 cm) that any solar activity data provider class should be able to return, in order to be compatible with the atmosphere specific implementations (see next point). The [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/package-summary.html solarActivity package] contains classes that can read different file formats and can return the solar activity data. So far, one class for each of the ACSOL and NOAA formats has been implemented. Additionally, one class representing constant solar activity (that requires no external file) has been implemented.&lt;br /&gt;
*&#039;&#039;&#039;Using the solar data in an adequate fashion&#039;&#039;&#039;&lt;br /&gt;
Making effective use of the solar data for specific atmospheres requires an object that provides solar data (implementing the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataProvider.html SolarActivityDataProvider]) and answers to the interfaces that define the ways in which the atmosphere models use this data (e.g. implementing  [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/DTM2000InputParameters.html DTMInputParameters]). These classes are contained in the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/package-summary.html fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.specialized package]). So far, one class for each of the DTM2000/DTM2012 and MSISE2000 models have been implemented.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.atmospheres.solarActivity&amp;lt;/code&amp;gt; package follows the same architecture as the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.potential&amp;lt;/code&amp;gt; package. The user must use the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataFactory.html SolarActivityDataFactory class].&lt;br /&gt;
&lt;br /&gt;
For a detailed explanation of the Data Management System, please refer to the [SUP_DMS_Home Data Management System section] of the Support User Manual.&lt;br /&gt;
&lt;br /&gt;
For performances reasons, numerical propagator checks availability of solar activity data at start of propagation and not at every solar activity data call. If required solar activity or geomagnetic activity does not cover the required range by the atmospheric model, an exception is returned.&lt;br /&gt;
&lt;br /&gt;
==== Atmospheric models ====&lt;br /&gt;
&lt;br /&gt;
Various models are available in PATRIUS: DTM-2000, DTM-2012, MSIS-00, US76, etc. all models inherit the &amp;lt;code&amp;gt;Atmosphere&amp;lt;/code&amp;gt; interface providing total density information.&amp;lt;br&amp;gt;&lt;br /&gt;
DTM and MSIS models also implement the &amp;lt;code&amp;gt;ExtendedAtmosphere&amp;lt;/code&amp;gt; interface which provides more detailed data such as temperature and partial densities of atmosphere constituents.&amp;lt;br&amp;gt;&lt;br /&gt;
Some models require solar and geomagnetic information (see below for how to provide solar and geomagnetic data).&lt;br /&gt;
&lt;br /&gt;
===== MSIS2000 Atmosphere model =====&lt;br /&gt;
&lt;br /&gt;
The NRLMSIS series represents the gold standard for empirical neutral atmosphere models, used to predict temperature, density, and composition from the ground to the exosphere. The transition from NRLMSISE-00 (released in 2013) to NRLMSIS 2.0 (released in 2020) marks a significant leap in modeling accuracy and architectural design. PATRIUS implements both models.&lt;br /&gt;
&lt;br /&gt;
Key Differences&lt;br /&gt;
&lt;br /&gt;
* NRLMSISE00 (or NRLMSIS 1.0):&lt;br /&gt;
** Relies on older mass spectrometer and incoherent scatter radar data. While robust, it often overestimates densities during extreme solar minimums and struggles with the precise &amp;quot;satellite drag&amp;quot; modeling required for modern space situational awareness.&lt;br /&gt;
** Models the primary species (He, O, N2, O, Ar, H, N) and includes an &amp;quot;anomalous oxygen&amp;quot; component to account for satellite drag discrepancies.&lt;br /&gt;
&lt;br /&gt;
* NRLMSISE20 (or NRLMSIS 2.0):&lt;br /&gt;
** Incorporates decades of new data, including extensive satellite accelerometer measurements and improved occultation data. It is significantly more accurate in the thermosphere and exosphere, particularly during low solar activity.&lt;br /&gt;
** Introduces a more rigorous treatment of atomic species. Notably, it includes Atomic Nitrogen (N) and Nitric Oxide (NO) as intrinsic parts of the model (though, as you noted in your previous translation, some implementations may still exclude NO depending on the reference version used). It also ensures better mass-density consistency.&lt;br /&gt;
** Version 2.0 enforces stricter physical constraints between temperature and density profiles, ensuring that the transition between the lower atmosphere and the thermosphere is physically smoother.&lt;br /&gt;
&lt;br /&gt;
Note that a new model NRLMSIS 2.1 has been presented in 2025. This model is not implemented yet in PATRIUS.&lt;br /&gt;
&lt;br /&gt;
More information can be found at the [http://www.nrl.navy.mil/research/nrl-review/2003/atmospheric-science/picone/ Naval Research Laboratory website] and [https://map.nrl.navy.mil/map/pub/nrl/NRLMSIS/ Geospace Science &amp;amp; Technology Branch]. Note that several adaptations have been made to optimize the JAVA model compare to these FORTRAN models.&lt;br /&gt;
&lt;br /&gt;
In order to use this atmosphere model, the user must proceed by giving the following arguments as inputs to the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/MSISE2000.html MSISE2000] class :&lt;br /&gt;
&lt;br /&gt;
* The empirical atmosphere model it self (NRLMSISE00 or NRLMSISE20)&lt;br /&gt;
* Solar activity data (as a [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/MSISE2000InputParameters.html MSISE2000InputParameters])&lt;br /&gt;
* the Earth model (as a [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/bodies/BodyShape.html BodyShape])&lt;br /&gt;
* the Sun model (as a [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/bodies/CelestialBody.html CelestialBody])&lt;br /&gt;
&lt;br /&gt;
The following code snippet creates an instance of MSISE2000 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
 // Create an instance of the BodyShape &amp;quot;EARTH&amp;quot;, with user chosen&lt;br /&gt;
 // equatorial radius, flattening and body frame&lt;br /&gt;
 Frame frame = FramesFactory.getITRF();&lt;br /&gt;
 double f = 0.29825765000000E+03;&lt;br /&gt;
 double ae = 6378136.46;&lt;br /&gt;
 BodyShape earth = new OneAxisEllipsoid(ae, 1 / f, frame);&lt;br /&gt;
&lt;br /&gt;
 // Get the instance of the CelestialBody &amp;quot;SUN&amp;quot;&lt;br /&gt;
 CelestialBody sun = CelestialBodyFactory.getSun();&lt;br /&gt;
&lt;br /&gt;
 // Create the solar activity data to be used&lt;br /&gt;
 SolarActivityDataProvider solarActivity = SolarActivityDataFactory.getSolarActivityDataProvider();&lt;br /&gt;
 final MSISE2000InputParameters msiseData = new ClassicalMSISE2000SolarData(solarActivity);&lt;br /&gt;
&lt;br /&gt;
 // Create an instance of the atmosphere model&lt;br /&gt;
 Atmosphere atmosModel = new MSISE2000(new NRLMSISE00(), msiseData , earth, sun);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: the NRLMSISE-00 model is not continuous. There is a discontinuity every day (at 0h in UTC time scale). Discontinuities are however very small (1E-3 on a relative scale).&lt;br /&gt;
&lt;br /&gt;
The main difference in usage between the models NRLMSISE-00 and NRLMSIS 2.0 is that :&lt;br /&gt;
&lt;br /&gt;
* NRLMSISE-00 uses a “Flags” container to define the model’s specific settings every time we call the gtd7d(Input, Flags) method&lt;br /&gt;
* NRLMSIS 2.0 doesn’t use the “Flags” container when calling the gtd7d(Input, Flags). Instead, the model is configured once in its constructor by providing a specific MSISInit instance.&lt;br /&gt;
&lt;br /&gt;
==== Solar and geomagnetic activity ====&lt;br /&gt;
&lt;br /&gt;
Solar and geomagnetic activity can be provided in various ways:&lt;br /&gt;
* Constant solar activity using:&amp;lt;br&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final SolarActivityDataProvider constantSolarActivity = new ConstantSolarActivity(140, 15);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Variable solar activity using (for instance):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final SolarActivityDataProvider variableSolarActivity = new NOAAFormatReader(...);&lt;br /&gt;
final SolarActivityDataProvider otherVariableSolarActivity = new ACSOLFormatReader(...);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solar and geomagnetic activity data often having a limited timespan, the class &amp;lt;code&amp;gt;ExtendedSolarActivityWrapper&amp;lt;/code&amp;gt; allows data extension with constant values. Solar and geomagnetic data returned before timespan are equals to an average of first available data (the average duration being user-chosen). Solar and geomagnetic data returned after timespan are equals to an average of last available data (the average duration being user-chosen). Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final SolarActivityDataProvider innerProvider = new NOAAFormatReader() // Variable solar activity over a given timespan&lt;br /&gt;
final double duration = 86400; // Duration on which average solar activity will be computed if date out of innerProvider timespan&lt;br /&gt;
final ExtendedSolarActivityWrapper solarActivity = new ExtendedSolarActivityWrapper(innerProvider, duration)// Extended solar activity&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will create an solar activity whose value will be:&lt;br /&gt;
* Value of innerProvider if date is within innerProvider timespan&lt;br /&gt;
* Average value on [lower boundary, lower boundary + duration] if date is before innerProvider lower boundary&lt;br /&gt;
* Average value on [upper boundary- duration, upper boundary] if date is after innerProvider upperboundary&lt;br /&gt;
&lt;br /&gt;
These providers are used as inputs of atmospheric models.&lt;br /&gt;
&lt;br /&gt;
===== Reading Solar Activity Data files =====&lt;br /&gt;
&lt;br /&gt;
The data is read through the &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt; infrastructure; it provides several ways to load solar activity data. Please see the [SUP_DMS_Home Data Management System section] for more information.&lt;br /&gt;
&lt;br /&gt;
The following file formats are supported by PATRIUS:&lt;br /&gt;
* ACSOL format&lt;br /&gt;
* NOAA format&lt;br /&gt;
&lt;br /&gt;
The user access point is the &amp;lt;code&amp;gt;SolarActivityDataFactory&amp;lt;/code&amp;gt; which automatically detects available files and uses the adequate solar file reader. If no file is specified by the user, this factory uses the first available file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
//Directory containing the file ACSOL.act&lt;br /&gt;
final File potdir = new File(&amp;quot;/my/data/solar&amp;quot;);&lt;br /&gt;
//The directory is given to the data loader&lt;br /&gt;
DataProvidersManager.getInstance().addProvider(new DirectoryCrawler(potdir));&lt;br /&gt;
//The ACSOL file is registered in the SolarActivityDataFactory&lt;br /&gt;
//If it is the only solar activity file of the directory, this step is not necessary&lt;br /&gt;
SolarActivityDataFactory.addSolarActivityDataReader(new ACSOLFormatReader(&amp;quot;ACSOL.act&amp;quot;));&lt;br /&gt;
//A provider for the data is created&lt;br /&gt;
final SolarActivityDataProvider provider = SolarActivityDataFactory.getSolarActivityDataProvider();&lt;br /&gt;
//Get the ap, kp and instant flux at date&lt;br /&gt;
final AbsoluteDate userDate = new AbsoluteDate();&lt;br /&gt;
final double ap = provider.getAp( userDate );&lt;br /&gt;
final double kp = provider.getKp( userDate );&lt;br /&gt;
final double f = provider.getInstantFluxValue( userDate );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;SolarActivityDataFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;ACSOLFormatReader&amp;lt;/code&amp;gt;: ACSOL file format&lt;br /&gt;
*&amp;lt;code&amp;gt;NOAAFormatReader&amp;lt;/code&amp;gt;: NOAA file format&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for solar activity retrieval.&lt;br /&gt;
&lt;br /&gt;
=== Tides models ===&lt;br /&gt;
==== Tides model for force computation ====&lt;br /&gt;
&lt;br /&gt;
The PATRIUS &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.tides&amp;lt;/code&amp;gt; package provides tools allowing the user to use Terestrial and Ocean tides. The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.tides.coefficients&amp;lt;/code&amp;gt; package also allows reading external ocean tides coefficients data files. The following file formats are supported by PATRIUS:&lt;br /&gt;
* FES2004 format&lt;br /&gt;
&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;OceanTidesCoefficientFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;FES2004FormatReader&amp;lt;/code&amp;gt;: FES 2004 file format&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for ocean tides computation.&lt;br /&gt;
&lt;br /&gt;
==== Reference point displacement ====&lt;br /&gt;
&lt;br /&gt;
The PATRIUS &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.utils.ReferencePointsDisplacement&amp;lt;/code&amp;gt; class provides a model describing the displacement of reference points due to the effect of the solid Earth tides. The computation is performed by the static method &#039;&#039;&#039;solidEarthTidesCorrections(AbsoluteDate, Vector3D, Vector3D, Vector3D)&#039;&#039;&#039;. The implemented model has been validated by comparison with tests available in the IERS website. The example below shows the user how to compute displacements of reference points:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Test from source ftp://tai.bipm.org/iers/convupdt/chapter7/dehanttideinel/DEHANTTIDEINEL.F&lt;br /&gt;
&lt;br /&gt;
// date : 13/04/2009&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2009, 4, 13, 0, 0, 0., TimeScalesFactory.getUTC());&lt;br /&gt;
&lt;br /&gt;
// entries : moon position, sun position, station location&lt;br /&gt;
final Vector3D moon = new Vector3D(-179996231.920342,-312468450.131567, -169288918.592160);&lt;br /&gt;
final Vector3D sun = new Vector3D(137859926952.015, 54228127881.4350, 23509422341.6960);&lt;br /&gt;
final Vector3D point = new Vector3D(4075578.385, 931852.890, 4801570.154);&lt;br /&gt;
&lt;br /&gt;
// compute the displacement&lt;br /&gt;
final Vector3D disp = ReferencePointsDisplacement.solidEarthTidesCorrections(date, point, sun, moon);&lt;br /&gt;
&lt;br /&gt;
// comparison with reference results (IERS)&lt;br /&gt;
Assert.assertEquals(0.07700420357108125891, disp.getX(), Precision.EPSILON);&lt;br /&gt;
Assert.assertEquals(0.06304056321824967613, disp.getY(), Precision.EPSILON);&lt;br /&gt;
Assert.assertEquals(0.05516568152597246810, disp.getZ(), Precision.EPSILON);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geomagnetic models ===&lt;br /&gt;
==== Design ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.models.earth&amp;lt;/code&amp;gt; package provides tools allowing the user to use different geomagnetic models. For the moment, there are only the two following models available :&lt;br /&gt;
* IGRF 11  : International Geomagnetic Reference Field eleventh generation&lt;br /&gt;
* WMM 2010 : World Magnetic Model published in december 2009&lt;br /&gt;
&lt;br /&gt;
A class diagram is given hereunder to show how geomagnetic is read and used in the library :&lt;br /&gt;
&lt;br /&gt;
[[File:geomaguml.png]]&lt;br /&gt;
&lt;br /&gt;
The user can create its own [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticModelReader.html GeoMagneticModelReader] in order to provide [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticField.html GeoMagneticField] from any file format.&lt;br /&gt;
&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;GeoMagneticFieldFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;COFFileFormatReader&amp;lt;/code&amp;gt;: COF file format&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for geomagnetic field computation (IGRF and WMM).&lt;br /&gt;
&lt;br /&gt;
==== IGRF 11 geomagnetic model ====&lt;br /&gt;
&lt;br /&gt;
The International Geomagnetic Reference Field (IGRF) was introduced by the International Association of Geomagnetism and Aeronomy (IAGA) in 1968 in response to the demand for a standard spherical harmonic representation of the Earth&#039;s main field. The model is updated at 5-yearly intervals, the latest being the 11th generation, produced and released by IAGA Working Group V-MOD (formerly V-8) December 2009. &lt;br /&gt;
&lt;br /&gt;
More information can be found at the [http://www.ngdc.noaa.gov/IAGA/vmod/index.html IAGA Division V-Mod].&lt;br /&gt;
&lt;br /&gt;
==== WMM 2010 geomagnetic model ====&lt;br /&gt;
&lt;br /&gt;
The World Magnetic Model is a joint product of the United States’ National Geospatial-Intelligence Agency (NGA) and the United Kingdom’s Defence Geographic Centre (DGC). The WMM was developed jointly by the National Geophysical Data Center (NGDC, Boulder CO, USA) and the British Geological Survey (BGS, Edinburgh, Scotland). &lt;br /&gt;
&lt;br /&gt;
The World Magnetic Model is the standard model used by the U.S. Department of Defense, the U.K. Ministry of Defence, the North Atlantic Treaty Organization (NATO) and the International Hydrographic Organization (IHO), for navigation, attitude and heading referencing systems using the geomagnetic field. It is also used widely in civilian navigation and heading systems. The model, associated software, and documentation are distributed by NGDC on behalf of NGA. The model is produced at 5-year intervals, with the current model expiring on December 31, 2014.&lt;br /&gt;
&lt;br /&gt;
The current model, WMM2010 (published 12/2009)&lt;br /&gt;
&lt;br /&gt;
More information can be found at the [http://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml National Oceanic and Atmospheric Administration].&lt;br /&gt;
&lt;br /&gt;
==== Details, limitation and precautions ====&lt;br /&gt;
&lt;br /&gt;
In the geomagnetic field&#039;s computation from the different models, to convert geodetic coordinates (defined by the WGS-84 reference ellipsoid) to Earth Centered spherical coordinates, the following constants are used :&lt;br /&gt;
&lt;br /&gt;
* Semi major-axis of WGS-84 ellipsoid : 6378.137 km&lt;br /&gt;
* The first eccentricity squared : 0.0066943799901413169961&lt;br /&gt;
&lt;br /&gt;
and to compute the spherical harmonic variables for a given spherical coordinate uses the mean radius of IAU-66 ellipsoid 6371.2 km is used.&lt;br /&gt;
&lt;br /&gt;
The different models are used to compute gemoagnetic field near earth surface. In the model file, the given altitude range of validity is-1 to 600 km even if we can compute field outside of this range.&lt;br /&gt;
&lt;br /&gt;
The method GeoMagneticField.calculateField(final Vector3D point,final Frame frame, final AbsoluteDate date) has been added to Patrius and allows to compute the field from a position vector in a specific frame and at a specific date. This method is based on tranformModel method which recomputes the field at a date. This method doesn&#039;t work if the model doesn&#039;t support time transform. In this way, this method added to Patrius throws a Patrius exception about model not supporting time transform.&lt;br /&gt;
&lt;br /&gt;
Here is the list of all possible actual models and the time transform support (please note that only dates prior to 2010 won&#039;t support time transformation) :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Model and associated data file&lt;br /&gt;
| Model Name&lt;br /&gt;
| Validity Period&lt;br /&gt;
| Time transform support&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;23&amp;quot;|IGRF (&#039;&#039;GeoMagneticFieldFactory.getIGRF(..)&#039;&#039; uses IGRF.COF)&lt;br /&gt;
| IGRF00&lt;br /&gt;
| 1900.0 - 1905.0&lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
| IGRF05&lt;br /&gt;
| 1905.0 - 1910.0&lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
| IGRF10 &lt;br /&gt;
| 1910.0 - 1915.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF15 &lt;br /&gt;
| 1915.0 - 1920.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF20 &lt;br /&gt;
| 1920.0 - 1925.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF25 &lt;br /&gt;
| 1925.0 - 1930.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF30 &lt;br /&gt;
| 1930.0 - 1935.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF35 &lt;br /&gt;
| 1935.0 - 1940.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF40 &lt;br /&gt;
| 1940.0 - 1945.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF45 &lt;br /&gt;
| 1945.0 - 1950.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF50 &lt;br /&gt;
| 1950.0 - 1955.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF55 &lt;br /&gt;
| 1955.0 - 1960.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF60 &lt;br /&gt;
| 1960.0 - 1965.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF65 &lt;br /&gt;
| 1965.0 - 1970.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF70 &lt;br /&gt;
| 1970.0 - 1975.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF75 &lt;br /&gt;
| 1975.0 - 1980.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF80 &lt;br /&gt;
| 1980.0 - 1985.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF85 &lt;br /&gt;
| 1985.0 - 1990.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF90 &lt;br /&gt;
| 1990.0 - 1995.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF95 &lt;br /&gt;
| 1995.0 - 2000.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF2000 &lt;br /&gt;
| 2000.0 - 2005.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF2005 &lt;br /&gt;
| 2005.0 - 2010.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF2010 &lt;br /&gt;
| 2010.0 - 2015.0 &lt;br /&gt;
| true&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;|WMM (&#039;&#039;GeoMagneticFieldFactory.getWMM(..)&#039;&#039; uses WMM.COF)&lt;br /&gt;
| WMM2010 &lt;br /&gt;
| 2010.0 - 2015.0&lt;br /&gt;
| true&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Precautions :&lt;br /&gt;
The method GeoMagneticField.calculateField (final double latitude, final double longitude, final double height) doesn&#039;t use SI units. Latitude and longitude are given in degrees, and height is given in kilometers.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
==== Code Example ====&lt;br /&gt;
&lt;br /&gt;
The following code sample computes geomagnetic field elements for four (date, position) of a fake trajectory :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
    public void codeExemple() throws PatriusException {&lt;br /&gt;
&lt;br /&gt;
        Utils.setDataRoot(&amp;quot;earth&amp;quot;);&lt;br /&gt;
        FramesFactory.setConfiguration(Utils.getIERS2003ConfigurationWOEOP(true));&lt;br /&gt;
&lt;br /&gt;
        //Fake trajectory : list of date and list of position&lt;br /&gt;
        List&amp;lt;AbsoluteDate&amp;gt; dateList = new ArrayList&amp;lt;AbsoluteDate&amp;gt;();&lt;br /&gt;
        AbsoluteDate initDate = new AbsoluteDate(2010, 1, 1, 12, 0, 0.0, TimeScalesFactory.getTT());&lt;br /&gt;
        &lt;br /&gt;
        dateList.add(initDate);&lt;br /&gt;
        dateList.add(new AbsoluteDate(initDate, 600));&lt;br /&gt;
        dateList.add(new AbsoluteDate(initDate, 1200));&lt;br /&gt;
        dateList.add(new AbsoluteDate(initDate, 1800));&lt;br /&gt;
        &lt;br /&gt;
        List&amp;lt;Vector3D&amp;gt; positionList = new ArrayList&amp;lt;Vector3D&amp;gt;();&lt;br /&gt;
        positionList.add(new Vector3D(6.46885878304673824e+06,-1.88050918456274318e+06, -1.32931592294715829e+04));&lt;br /&gt;
        positionList.add(new Vector3D(6.58239141552595049e+06,-1.43349476017528563e+06, -1.39460373997706010e+04));&lt;br /&gt;
        positionList.add(new Vector3D(6.66499609614125639e+06,-9.79745192516532145e+05, -1.45334684008149434e+04));&lt;br /&gt;
        positionList.add(new Vector3D(6.71628402448997274e+06,-5.21392324304617418e+05, -1.50526405214286660e+04));&lt;br /&gt;
        &lt;br /&gt;
        // Get the model to the initial date&lt;br /&gt;
        final GeoMagneticField model = GeoMagneticFieldFactory.getIGRF(dateList.get(0));&lt;br /&gt;
        &lt;br /&gt;
        // For each date and position, compute the GeoMagneticElement and add it to a list&lt;br /&gt;
        List&amp;lt;GeoMagneticElements&amp;gt; geoMagList = new ArrayList&amp;lt;GeoMagneticElements&amp;gt;();&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        for (AbsoluteDate date : dateList){&lt;br /&gt;
            geoMagList.add(model.calculateField(positionList.get(i), FramesFactory.getEME2000(), date));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Print each field vector B &lt;br /&gt;
        for (GeoMagneticElements geoMagElement : geoMagList){&lt;br /&gt;
            System.out.println(geoMagElement.toString());&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code produces the following standard output :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;MagneticField[B={29817,109;-2303,065; -9138,097},H=29905,92,F=31270,895,I=-16,991,D=-4,417]&lt;br /&gt;
MagneticField[B={29442,018;-2166,283; -8949,299},H=29521,606,F=30848,261,I=-16,864,D=-4,208]&lt;br /&gt;
MagneticField[B={29067,408;-1996,393; -8794,324},H=29135,885,F=30434,19,I=-16,796,D=-3,929]&lt;br /&gt;
MagneticField[B={28695,713;-1796,821; -8680,411},H=28751,913,F=30033,681,I=-16,799,D=-3,583]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Atmosphere&#039;&#039;&#039;&lt;br /&gt;
|Interface for atmospheric models.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/Atmosphere.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ExtendedAtmosphere&#039;&#039;&#039;&lt;br /&gt;
|Interface for atmospheric models with detailed data.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/ExtendedAtmosphere.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SolarActivityDataProvider&#039;&#039;&#039;&lt;br /&gt;
|Interface for solar activity data providers, to be used for atmosphere models&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DTM2000InputParameters&#039;&#039;&#039;&lt;br /&gt;
|Container for solar activity data, compatible with DTM Atmosphere models.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/DTMInputParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MSISE2000InputParameters&#039;&#039;&#039;&lt;br /&gt;
|Container for solar activity data, compatible with MSISE2000 Atmosphere model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/MSISE2000InputParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTidesCoefficientsProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide ocean tides coefficients.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PotentialCoefficientsProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide gravity field coefficients.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/PotentialCoefficientsProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VariablePotentialCoefficientsProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide variable gravity field coefficients.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/variations/coefficients/VariablePotentialCoefficientsProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RadiationSensitive&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide an direct solar radiative pressure model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/radiation/RadiationSensitive.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RediffusedRadiationSensitive&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide an rediffused radiative pressure model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/radiation/RediffusedRadiationSensitive.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticDataProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is a generic geomagnetic data provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticDataProvider.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&#039;&#039;&#039;Earth potential&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EGMFormatReader&#039;&#039;&#039;&lt;br /&gt;
|This reader is adapted to the EGM Format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/EGMFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GravityFieldFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory used to read gravity field files in several supported formats. &#039;&#039;&#039;Main user access point&#039;&#039;&#039; : the simple way of reading a potential file is by using this factory.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/GravityFieldFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VariableGravityFieldFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory used to read variable gravity field files in several supported formats. &#039;&#039;&#039;Main user access point&#039;&#039;&#039; : the simple way of reading a variable potential file is by using this factory.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/variations/coefficients/VariableGravityFieldFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GRGSFormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for the GRGS gravity field format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/GRGSFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GRGSRL02FormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for the GRGS RL02 variable gravity field format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/variations/coefficients/GRGSRL02FormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ICGEMFormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for the ICGEM gravity field format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/ICGEMFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PotentialCoefficientsReader&#039;&#039;&#039;&lt;br /&gt;
|This abstract class represents a Gravitational Potential Coefficients file reader.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/PotentialCoefficientsReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SHMFormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for the SHM gravity field format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/SHMFormatReader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Atmosphere Models&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DTM2000&#039;&#039;&#039;&lt;br /&gt;
|This class implements the DTM2000 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/DTM2000.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DTM2012&#039;&#039;&#039;&lt;br /&gt;
|This class implements the DTM2012 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/DTM2012.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;JB2006&#039;&#039;&#039;&lt;br /&gt;
|This class implements the JB2006 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/JB2006.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MSISE2000&#039;&#039;&#039;&lt;br /&gt;
|This class implements the MSIS00 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/MSISE2000.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NRLMSISE00&#039;&#039;&#039;&lt;br /&gt;
|This class implements the NRLMSISE 1.0 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/MSIS/NRLMSISE00.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NRLMSISE20&#039;&#039;&#039;&lt;br /&gt;
|This class implements the NRLMSISE 2.0 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/MSIS/NRLMSISE20.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;US76&#039;&#039;&#039;&lt;br /&gt;
|This class implements the US76 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/US76.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solar Activity&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DTMSolarData&#039;&#039;&#039;&lt;br /&gt;
|This class represents a solar data container adapted for the DTM atmosphere models.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/DTMSolarData.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ClassicalMSISE2000SolarData&#039;&#039;&#039;&lt;br /&gt;
|This class represents a solar data container adapted for the MSISE2000 atmosphere model. The average ap values are computed arithmetically.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/ClassicalMSISE2000SolarData.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ContinuousMSISE2000SolarData&#039;&#039;&#039;&lt;br /&gt;
|This class represents a solar data container adapted for the MSISE2000 atmosphere model. The mean ap values are computed by trapezoidal integration.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/ContinuousMSISE2000SolarData.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ACSOLFormatReader&#039;&#039;&#039;&lt;br /&gt;
|This class reads ACSOL format solar activity data&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/ACSOLFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ConstantSolarActivity&#039;&#039;&#039;&lt;br /&gt;
|This class represents constant solar activity&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/ConstantSolarActivity.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NOAAFormatReader&#039;&#039;&#039;&lt;br /&gt;
|This class reads NOAA format solar activity data&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/NOAAFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SolarActivityDataFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory used to read solar activity files and return SolarActivityDataProvider&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SolarActivityToolbox&#039;&#039;&#039;&lt;br /&gt;
|Solar activity toolbox. Has methods to compute mean flux values, to convert from ap to kp.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityToolbox.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MarshallSolarActivityFutureEstimation&#039;&#039;&#039;&lt;br /&gt;
|This class reads and provides solar activity data needed by atmospheric models: F107 solar flux and Kp indexes.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/MarshallSolarActivityFutureEstimation.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ExtendedSolarActivityWrapper&#039;&#039;&#039;&lt;br /&gt;
|This class extends a solar activity provider out of its timespan with constant values.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/ExtendedSolarActivityWrapper.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ocean Tides Coefficients&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FES2004FormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for FES2004 format coefficients files.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/FES2004FormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTidesCoefficientsFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory used to read ocean tides coefficients files in different formats and return an OceanTidesCoefficientsProvider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTidesCoefficientsReader&#039;&#039;&#039;&lt;br /&gt;
|This abstract class represents a Ocean Tides Coefficients file reader.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTidesCoefficientsSet&#039;&#039;&#039;&lt;br /&gt;
|Represents a line from the ocean tides data file.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsSet.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Geomagnetic Field&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticElements&#039;&#039;&#039;&lt;br /&gt;
|This class contains all the elements about a magnetic field : the magnetic field vector and associated caracteristics Inclination, Declination, Total Intensity, Horizontal Intensity.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticElements.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticField&#039;&#039;&#039;&lt;br /&gt;
|These objects are produced by the factory and are based on a model for a decimal year date and allows to compute GeomagneticElements &lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticField.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticFieldFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory to produce GeoMagneticField.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticFieldFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticModelReader&#039;&#039;&#039;&lt;br /&gt;
|To load the model from an input file&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticModelReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;COFFileFormatReader&#039;&#039;&#039;&lt;br /&gt;
|Class loading the geomagnetic data from COF files.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/COFFileFormatReader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Orbit_Propagation]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Environment_Models&amp;diff=4169</id>
		<title>User Manual 4.18 Environment Models</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Environment_Models&amp;diff=4169"/>
		<updated>2026-06-10T10:39:25Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The scope of this section is to present the physical models available through the Patrius library.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
All the classes related to physical models are in the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.parameter&amp;lt;/code&amp;gt;packages. The classes related to reading potential files are in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.potential&amp;lt;/code&amp;gt;.  &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/package-summary.html Package fr.cnes.sirius.patrius.forces.atmospheres]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/package-summary.html Package fr.cnes.sirius.patrius.forces.atmospheres.solarActivity]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/package-summary.html Package fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.specialized]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/package-summary.html Package fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.specialized]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/package-summary.html Package fr.cnes.sirius.patrius.forces.gravity.potential]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/variations/package-summary.html Package fr.cnes.sirius.patrius.forces.gravity.variations]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/package-summary.html Package fr.cnes.sirius.patrius.forces.gravity.tides.coefficients]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/package-summary.html Package fr.cnes.sirius.patrius.math.parameter]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/ReferencePointsDisplacement.html Class fr.cnes.sirius.patrius.utils.ReferencePointsDisplacement]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
Some useful links are given hereunder.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IERS Page&#039;&#039;&#039;&lt;br /&gt;
[http://www.iers.org/IERS/EN/Publications/TechnicalNotes/tn36.html IERS Conventions (2010), Technical Note No.36]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Project Pages&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://cddis.nasa.gov/ NASA - Crustal Dynamics Data Information System (CDDIS)]&lt;br /&gt;
* [http://op.gfz-potsdam.de/grace/ GFZ - Grace (Gravity Recovery and Climate Experiment) Mission Homepage]&lt;br /&gt;
* [http://icgem.gfz-potsdam.de/ICGEM/ GFZ - International Centre for Global Earth Models]&lt;br /&gt;
* [http://grgs.obs-mip.fr Groupe de Recherche de Géodésie Spatiale]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Results Pages&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;EGM96: The NASA GSFC and NIMA Joint Geopotential Model&#039;&#039;, Lemoine; F. G., Kenyon; S. C., Factor; J. K., Trimmer; R.G., Pavlis; N. K., Chinn; D. S., Cox; C. M., Klosko; S. M., Luthcke; S. B., Torrence; M. H., Wang; Y. M., Williamson; R. G., Pavlis; E. C., Rapp; R. H., Olson; T. R., NASA Goddard Space Flight Center, Greenbelt, Maryland, 20771 USA, July 1998, Available [http://cddis.nasa.gov/926/egm96/egm96.html here].&lt;br /&gt;
* &#039;&#039;GFZ : Global Gravity Field Models&#039;&#039;, Available [http://icgem.gfz-potsdam.de/ICGEM/modelstab.html here].&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Earth Potential Models ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.potential&amp;lt;/code&amp;gt; package provides tools allowing the user to read external gravity potential data files. The following file formats are supported :&lt;br /&gt;
&lt;br /&gt;
* EGM96 ASCII format data&lt;br /&gt;
* EIGEN-GRACE format&lt;br /&gt;
* ICGEM format&lt;br /&gt;
* GRGS format&lt;br /&gt;
&lt;br /&gt;
Below is a diagram showing the architecture of the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.potential&amp;lt;/code&amp;gt; package.&lt;br /&gt;
&lt;br /&gt;
[[File:physicalModels.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
For a detailed explanation of the Data Management System, please refer to the [SUP_DMS_Home Data Management System section] of the Support User Manual.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.variations&amp;lt;/code&amp;gt; package provides tools allowing the user to read external variable gravity potential data files. The corresponding ForceModel is also included in the package. The following file formats are supported :&lt;br /&gt;
&lt;br /&gt;
* GRGS RL02&lt;br /&gt;
&lt;br /&gt;
Below is a diagram showing the architecture of the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.variations&amp;lt;/code&amp;gt; package.&lt;br /&gt;
&lt;br /&gt;
[[File:varPOT.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;VariableGravityFieldFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;GRGSRL02FormatReader&amp;lt;/code&amp;gt;: GRGSR L02 file format&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for variable gravity field computation.&lt;br /&gt;
&lt;br /&gt;
=== Atmosphere models and solar activity model ===&lt;br /&gt;
==== Generalities about Solar Activity and Atmospheres ====&lt;br /&gt;
&lt;br /&gt;
The atmospheres make use of solar activity in order to compute the density at the given user location excepted US76 model that is only based on altitude parameters. The PATRIUS architecture of atmospheres and solar activity is divided into three layers :&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Atmospheres use solar data in specific ways&#039;&#039;&#039;&lt;br /&gt;
Each atmosphere model uses the solar data in a specific way (more simply, US76 doesn&#039;t use solar data). These representations are enclosed in the atmosphere model specific interfaces, such as [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/DTMInputParameters.html DTMInputParamters]. Atmosphere models available include US76 (for low altitudes in range 0 to 1000km), DTM2000, DTM2012 and MSISE2000.&lt;br /&gt;
*&#039;&#039;&#039;Reading and storing solar data&#039;&#039;&#039;&lt;br /&gt;
The way to store the solar data is enclosed in the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataProvider.html SolarActivityDataProvider interface]. It defines the basic coefficients (Ap, Kp and F10.7 cm) that any solar activity data provider class should be able to return, in order to be compatible with the atmosphere specific implementations (see next point). The [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/package-summary.html solarActivity package] contains classes that can read different file formats and can return the solar activity data. So far, one class for each of the ACSOL and NOAA formats has been implemented. Additionally, one class representing constant solar activity (that requires no external file) has been implemented.&lt;br /&gt;
*&#039;&#039;&#039;Using the solar data in an adequate fashion&#039;&#039;&#039;&lt;br /&gt;
Making effective use of the solar data for specific atmospheres requires an object that provides solar data (implementing the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataProvider.html SolarActivityDataProvider]) and answers to the interfaces that define the ways in which the atmosphere models use this data (e.g. implementing  [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/DTM2000InputParameters.html DTMInputParameters]). These classes are contained in the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/package-summary.html fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.specialized package]). So far, one class for each of the DTM2000/DTM2012 and MSISE2000 models have been implemented.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.atmospheres.solarActivity&amp;lt;/code&amp;gt; package follows the same architecture as the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.potential&amp;lt;/code&amp;gt; package. The user must use the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataFactory.html SolarActivityDataFactory class].&lt;br /&gt;
&lt;br /&gt;
For a detailed explanation of the Data Management System, please refer to the [SUP_DMS_Home Data Management System section] of the Support User Manual.&lt;br /&gt;
&lt;br /&gt;
For performances reasons, numerical propagator checks availability of solar activity data at start of propagation and not at every solar activity data call. If required solar activity or geomagnetic activity does not cover the required range by the atmospheric model, an exception is returned.&lt;br /&gt;
&lt;br /&gt;
==== Atmospheric models ====&lt;br /&gt;
&lt;br /&gt;
Various models are available in PATRIUS: DTM-2000, DTM-2012, MSIS-00, US76, etc. all models inherit the &amp;lt;code&amp;gt;Atmosphere&amp;lt;/code&amp;gt; interface providing total density information.&amp;lt;br&amp;gt;&lt;br /&gt;
DTM and MSIS models also implement the &amp;lt;code&amp;gt;ExtendedAtmosphere&amp;lt;/code&amp;gt; interface which provides more detailed data such as temperature and partial densities of atmosphere constituents.&amp;lt;br&amp;gt;&lt;br /&gt;
Some models require solar and geomagnetic information (see below for how to provide solar and geomagnetic data).&lt;br /&gt;
&lt;br /&gt;
===== MSIS2000 Atmosphere model =====&lt;br /&gt;
&lt;br /&gt;
The NRLMSIS series represents the gold standard for empirical neutral atmosphere models, used to predict temperature, density, and composition from the ground to the exosphere. The transition from NRLMSISE-00 (released in 2013) to NRLMSIS 2.0 (released in 2020) marks a significant leap in modeling accuracy and architectural design. PATRIUS implements both models.&lt;br /&gt;
&lt;br /&gt;
Key Differences&lt;br /&gt;
&lt;br /&gt;
* NRLMSISE-00:&lt;br /&gt;
** Relies on older mass spectrometer and incoherent scatter radar data. While robust, it often overestimates densities during extreme solar minimums and struggles with the precise &amp;quot;satellite drag&amp;quot; modeling required for modern space situational awareness.&lt;br /&gt;
** Models the primary species (He, O, N2, O, Ar, H, N) and includes an &amp;quot;anomalous oxygen&amp;quot; component to account for satellite drag discrepancies.&lt;br /&gt;
&lt;br /&gt;
* NRLMSIS 2.0:&lt;br /&gt;
** Incorporates decades of new data, including extensive satellite accelerometer measurements and improved occultation data. It is significantly more accurate in the thermosphere and exosphere, particularly during low solar activity.&lt;br /&gt;
** Introduces a more rigorous treatment of atomic species. Notably, it includes Atomic Nitrogen (N) and Nitric Oxide (NO) as intrinsic parts of the model (though, as you noted in your previous translation, some implementations may still exclude NO depending on the reference version used). It also ensures better mass-density consistency.&lt;br /&gt;
** Version 2.0 enforces stricter physical constraints between temperature and density profiles, ensuring that the transition between the lower atmosphere and the thermosphere is physically smoother.&lt;br /&gt;
&lt;br /&gt;
Note that a new model NRLMSIS 2.1 has been presented in 2025. This model is not implemented yet in PATRIUS.&lt;br /&gt;
&lt;br /&gt;
More information can be found at the [http://www.nrl.navy.mil/research/nrl-review/2003/atmospheric-science/picone/ Naval Research Laboratory website] and [https://map.nrl.navy.mil/map/pub/nrl/NRLMSIS/ Geospace Science &amp;amp; Technology Branch]. Note that several adaptations have been made to optimize the JAVA model compare to these FORTRAN models.&lt;br /&gt;
&lt;br /&gt;
In order to use this atmosphere model, the user must proceed by giving the following arguments as inputs to the [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/MSISE2000.html MSISE2000] class :&lt;br /&gt;
&lt;br /&gt;
* The empirical atmosphere model it self (NRLMSISE00 or NRLMSISE20)&lt;br /&gt;
* Solar activity data (as a [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/forces/atmospheres/MSISE2000InputParameters.html MSISE2000InputParameters])&lt;br /&gt;
* the Earth model (as a [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/bodies/BodyShape.html BodyShape])&lt;br /&gt;
* the Sun model (as a [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/bodies/CelestialBody.html CelestialBody])&lt;br /&gt;
&lt;br /&gt;
The following code snippet creates an instance of MSISE2000 :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
 // Create an instance of the BodyShape &amp;quot;EARTH&amp;quot;, with user chosen&lt;br /&gt;
 // equatorial radius, flattening and body frame&lt;br /&gt;
 Frame frame = FramesFactory.getITRF();&lt;br /&gt;
 double f = 0.29825765000000E+03;&lt;br /&gt;
 double ae = 6378136.46;&lt;br /&gt;
 BodyShape earth = new OneAxisEllipsoid(ae, 1 / f, frame);&lt;br /&gt;
&lt;br /&gt;
 // Get the instance of the CelestialBody &amp;quot;SUN&amp;quot;&lt;br /&gt;
 CelestialBody sun = CelestialBodyFactory.getSun();&lt;br /&gt;
&lt;br /&gt;
 // Create the solar activity data to be used&lt;br /&gt;
 SolarActivityDataProvider solarActivity = SolarActivityDataFactory.getSolarActivityDataProvider();&lt;br /&gt;
 final MSISE2000InputParameters msiseData = new ClassicalMSISE2000SolarData(solarActivity);&lt;br /&gt;
&lt;br /&gt;
 // Create an instance of the atmosphere model&lt;br /&gt;
 Atmosphere atmosModel = new MSISE2000(new NRLMSISE00(), msiseData , earth, sun);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Warning: the NRLMSISE-00model is not continuous. There is a discontinuity every day (at 0h in UTC time scale). Discontinuities are however very small (1E-3 on a relative scale).&lt;br /&gt;
&lt;br /&gt;
The main difference in usage between the models NRLMSISE-00 and NRLMSIS 2.0 is that :&lt;br /&gt;
&lt;br /&gt;
* NRLMSISE-00 uses a “Flags” container to define the model’s specific settings every time we call the gtd7d(Input, Flags) method&lt;br /&gt;
* NRLMSIS 2.0 doesn’t use the “Flags” container when calling the gtd7d(Input, Flags). Instead, the model is configured once in its constructor by providing a specific MSISInit instance.&lt;br /&gt;
&lt;br /&gt;
==== Solar and geomagnetic activity ====&lt;br /&gt;
&lt;br /&gt;
Solar and geomagnetic activity can be provided in various ways:&lt;br /&gt;
* Constant solar activity using:&amp;lt;br&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final SolarActivityDataProvider constantSolarActivity = new ConstantSolarActivity(140, 15);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Variable solar activity using (for instance):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final SolarActivityDataProvider variableSolarActivity = new NOAAFormatReader(...);&lt;br /&gt;
final SolarActivityDataProvider otherVariableSolarActivity = new ACSOLFormatReader(...);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solar and geomagnetic activity data often having a limited timespan, the class &amp;lt;code&amp;gt;ExtendedSolarActivityWrapper&amp;lt;/code&amp;gt; allows data extension with constant values. Solar and geomagnetic data returned before timespan are equals to an average of first available data (the average duration being user-chosen). Solar and geomagnetic data returned after timespan are equals to an average of last available data (the average duration being user-chosen). Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final SolarActivityDataProvider innerProvider = new NOAAFormatReader() // Variable solar activity over a given timespan&lt;br /&gt;
final double duration = 86400; // Duration on which average solar activity will be computed if date out of innerProvider timespan&lt;br /&gt;
final ExtendedSolarActivityWrapper solarActivity = new ExtendedSolarActivityWrapper(innerProvider, duration)// Extended solar activity&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The above code will create an solar activity whose value will be:&lt;br /&gt;
* Value of innerProvider if date is within innerProvider timespan&lt;br /&gt;
* Average value on [lower boundary, lower boundary + duration] if date is before innerProvider lower boundary&lt;br /&gt;
* Average value on [upper boundary- duration, upper boundary] if date is after innerProvider upperboundary&lt;br /&gt;
&lt;br /&gt;
These providers are used as inputs of atmospheric models.&lt;br /&gt;
&lt;br /&gt;
===== Reading Solar Activity Data files =====&lt;br /&gt;
&lt;br /&gt;
The data is read through the &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt; infrastructure; it provides several ways to load solar activity data. Please see the [SUP_DMS_Home Data Management System section] for more information.&lt;br /&gt;
&lt;br /&gt;
The following file formats are supported by PATRIUS:&lt;br /&gt;
* ACSOL format&lt;br /&gt;
* NOAA format&lt;br /&gt;
&lt;br /&gt;
The user access point is the &amp;lt;code&amp;gt;SolarActivityDataFactory&amp;lt;/code&amp;gt; which automatically detects available files and uses the adequate solar file reader. If no file is specified by the user, this factory uses the first available file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
//Directory containing the file ACSOL.act&lt;br /&gt;
final File potdir = new File(&amp;quot;/my/data/solar&amp;quot;);&lt;br /&gt;
//The directory is given to the data loader&lt;br /&gt;
DataProvidersManager.getInstance().addProvider(new DirectoryCrawler(potdir));&lt;br /&gt;
//The ACSOL file is registered in the SolarActivityDataFactory&lt;br /&gt;
//If it is the only solar activity file of the directory, this step is not necessary&lt;br /&gt;
SolarActivityDataFactory.addSolarActivityDataReader(new ACSOLFormatReader(&amp;quot;ACSOL.act&amp;quot;));&lt;br /&gt;
//A provider for the data is created&lt;br /&gt;
final SolarActivityDataProvider provider = SolarActivityDataFactory.getSolarActivityDataProvider();&lt;br /&gt;
//Get the ap, kp and instant flux at date&lt;br /&gt;
final AbsoluteDate userDate = new AbsoluteDate();&lt;br /&gt;
final double ap = provider.getAp( userDate );&lt;br /&gt;
final double kp = provider.getKp( userDate );&lt;br /&gt;
final double f = provider.getInstantFluxValue( userDate );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;SolarActivityDataFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;ACSOLFormatReader&amp;lt;/code&amp;gt;: ACSOL file format&lt;br /&gt;
*&amp;lt;code&amp;gt;NOAAFormatReader&amp;lt;/code&amp;gt;: NOAA file format&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for solar activity retrieval.&lt;br /&gt;
&lt;br /&gt;
=== Tides models ===&lt;br /&gt;
==== Tides model for force computation ====&lt;br /&gt;
&lt;br /&gt;
The PATRIUS &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.tides&amp;lt;/code&amp;gt; package provides tools allowing the user to use Terestrial and Ocean tides. The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.tides.coefficients&amp;lt;/code&amp;gt; package also allows reading external ocean tides coefficients data files. The following file formats are supported by PATRIUS:&lt;br /&gt;
* FES2004 format&lt;br /&gt;
&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;OceanTidesCoefficientFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;FES2004FormatReader&amp;lt;/code&amp;gt;: FES 2004 file format&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for ocean tides computation.&lt;br /&gt;
&lt;br /&gt;
==== Reference point displacement ====&lt;br /&gt;
&lt;br /&gt;
The PATRIUS &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.utils.ReferencePointsDisplacement&amp;lt;/code&amp;gt; class provides a model describing the displacement of reference points due to the effect of the solid Earth tides. The computation is performed by the static method &#039;&#039;&#039;solidEarthTidesCorrections(AbsoluteDate, Vector3D, Vector3D, Vector3D)&#039;&#039;&#039;. The implemented model has been validated by comparison with tests available in the IERS website. The example below shows the user how to compute displacements of reference points:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Test from source ftp://tai.bipm.org/iers/convupdt/chapter7/dehanttideinel/DEHANTTIDEINEL.F&lt;br /&gt;
&lt;br /&gt;
// date : 13/04/2009&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2009, 4, 13, 0, 0, 0., TimeScalesFactory.getUTC());&lt;br /&gt;
&lt;br /&gt;
// entries : moon position, sun position, station location&lt;br /&gt;
final Vector3D moon = new Vector3D(-179996231.920342,-312468450.131567, -169288918.592160);&lt;br /&gt;
final Vector3D sun = new Vector3D(137859926952.015, 54228127881.4350, 23509422341.6960);&lt;br /&gt;
final Vector3D point = new Vector3D(4075578.385, 931852.890, 4801570.154);&lt;br /&gt;
&lt;br /&gt;
// compute the displacement&lt;br /&gt;
final Vector3D disp = ReferencePointsDisplacement.solidEarthTidesCorrections(date, point, sun, moon);&lt;br /&gt;
&lt;br /&gt;
// comparison with reference results (IERS)&lt;br /&gt;
Assert.assertEquals(0.07700420357108125891, disp.getX(), Precision.EPSILON);&lt;br /&gt;
Assert.assertEquals(0.06304056321824967613, disp.getY(), Precision.EPSILON);&lt;br /&gt;
Assert.assertEquals(0.05516568152597246810, disp.getZ(), Precision.EPSILON);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Geomagnetic models ===&lt;br /&gt;
==== Design ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.models.earth&amp;lt;/code&amp;gt; package provides tools allowing the user to use different geomagnetic models. For the moment, there are only the two following models available :&lt;br /&gt;
* IGRF 11  : International Geomagnetic Reference Field eleventh generation&lt;br /&gt;
* WMM 2010 : World Magnetic Model published in december 2009&lt;br /&gt;
&lt;br /&gt;
A class diagram is given hereunder to show how geomagnetic is read and used in the library :&lt;br /&gt;
&lt;br /&gt;
[[File:geomaguml.png]]&lt;br /&gt;
&lt;br /&gt;
The user can create its own [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticModelReader.html GeoMagneticModelReader] in order to provide [{{PathCurrentJavaDoc}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticField.html GeoMagneticField] from any file format.&lt;br /&gt;
&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;GeoMagneticFieldFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;COFFileFormatReader&amp;lt;/code&amp;gt;: COF file format&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for geomagnetic field computation (IGRF and WMM).&lt;br /&gt;
&lt;br /&gt;
==== IGRF 11 geomagnetic model ====&lt;br /&gt;
&lt;br /&gt;
The International Geomagnetic Reference Field (IGRF) was introduced by the International Association of Geomagnetism and Aeronomy (IAGA) in 1968 in response to the demand for a standard spherical harmonic representation of the Earth&#039;s main field. The model is updated at 5-yearly intervals, the latest being the 11th generation, produced and released by IAGA Working Group V-MOD (formerly V-8) December 2009. &lt;br /&gt;
&lt;br /&gt;
More information can be found at the [http://www.ngdc.noaa.gov/IAGA/vmod/index.html IAGA Division V-Mod].&lt;br /&gt;
&lt;br /&gt;
==== WMM 2010 geomagnetic model ====&lt;br /&gt;
&lt;br /&gt;
The World Magnetic Model is a joint product of the United States’ National Geospatial-Intelligence Agency (NGA) and the United Kingdom’s Defence Geographic Centre (DGC). The WMM was developed jointly by the National Geophysical Data Center (NGDC, Boulder CO, USA) and the British Geological Survey (BGS, Edinburgh, Scotland). &lt;br /&gt;
&lt;br /&gt;
The World Magnetic Model is the standard model used by the U.S. Department of Defense, the U.K. Ministry of Defence, the North Atlantic Treaty Organization (NATO) and the International Hydrographic Organization (IHO), for navigation, attitude and heading referencing systems using the geomagnetic field. It is also used widely in civilian navigation and heading systems. The model, associated software, and documentation are distributed by NGDC on behalf of NGA. The model is produced at 5-year intervals, with the current model expiring on December 31, 2014.&lt;br /&gt;
&lt;br /&gt;
The current model, WMM2010 (published 12/2009)&lt;br /&gt;
&lt;br /&gt;
More information can be found at the [http://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml National Oceanic and Atmospheric Administration].&lt;br /&gt;
&lt;br /&gt;
==== Details, limitation and precautions ====&lt;br /&gt;
&lt;br /&gt;
In the geomagnetic field&#039;s computation from the different models, to convert geodetic coordinates (defined by the WGS-84 reference ellipsoid) to Earth Centered spherical coordinates, the following constants are used :&lt;br /&gt;
&lt;br /&gt;
* Semi major-axis of WGS-84 ellipsoid : 6378.137 km&lt;br /&gt;
* The first eccentricity squared : 0.0066943799901413169961&lt;br /&gt;
&lt;br /&gt;
and to compute the spherical harmonic variables for a given spherical coordinate uses the mean radius of IAU-66 ellipsoid 6371.2 km is used.&lt;br /&gt;
&lt;br /&gt;
The different models are used to compute gemoagnetic field near earth surface. In the model file, the given altitude range of validity is-1 to 600 km even if we can compute field outside of this range.&lt;br /&gt;
&lt;br /&gt;
The method GeoMagneticField.calculateField(final Vector3D point,final Frame frame, final AbsoluteDate date) has been added to Patrius and allows to compute the field from a position vector in a specific frame and at a specific date. This method is based on tranformModel method which recomputes the field at a date. This method doesn&#039;t work if the model doesn&#039;t support time transform. In this way, this method added to Patrius throws a Patrius exception about model not supporting time transform.&lt;br /&gt;
&lt;br /&gt;
Here is the list of all possible actual models and the time transform support (please note that only dates prior to 2010 won&#039;t support time transformation) :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Model and associated data file&lt;br /&gt;
| Model Name&lt;br /&gt;
| Validity Period&lt;br /&gt;
| Time transform support&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;23&amp;quot;|IGRF (&#039;&#039;GeoMagneticFieldFactory.getIGRF(..)&#039;&#039; uses IGRF.COF)&lt;br /&gt;
| IGRF00&lt;br /&gt;
| 1900.0 - 1905.0&lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
| IGRF05&lt;br /&gt;
| 1905.0 - 1910.0&lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
| IGRF10 &lt;br /&gt;
| 1910.0 - 1915.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF15 &lt;br /&gt;
| 1915.0 - 1920.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF20 &lt;br /&gt;
| 1920.0 - 1925.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF25 &lt;br /&gt;
| 1925.0 - 1930.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF30 &lt;br /&gt;
| 1930.0 - 1935.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF35 &lt;br /&gt;
| 1935.0 - 1940.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF40 &lt;br /&gt;
| 1940.0 - 1945.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF45 &lt;br /&gt;
| 1945.0 - 1950.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF50 &lt;br /&gt;
| 1950.0 - 1955.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF55 &lt;br /&gt;
| 1955.0 - 1960.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF60 &lt;br /&gt;
| 1960.0 - 1965.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF65 &lt;br /&gt;
| 1965.0 - 1970.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF70 &lt;br /&gt;
| 1970.0 - 1975.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF75 &lt;br /&gt;
| 1975.0 - 1980.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF80 &lt;br /&gt;
| 1980.0 - 1985.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF85 &lt;br /&gt;
| 1985.0 - 1990.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF90 &lt;br /&gt;
| 1990.0 - 1995.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF95 &lt;br /&gt;
| 1995.0 - 2000.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF2000 &lt;br /&gt;
| 2000.0 - 2005.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|DGRF2005 &lt;br /&gt;
| 2005.0 - 2010.0 &lt;br /&gt;
| false&lt;br /&gt;
|-&lt;br /&gt;
|IGRF2010 &lt;br /&gt;
| 2010.0 - 2015.0 &lt;br /&gt;
| true&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;1&amp;quot;|WMM (&#039;&#039;GeoMagneticFieldFactory.getWMM(..)&#039;&#039; uses WMM.COF)&lt;br /&gt;
| WMM2010 &lt;br /&gt;
| 2010.0 - 2015.0&lt;br /&gt;
| true&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Precautions :&lt;br /&gt;
The method GeoMagneticField.calculateField (final double latitude, final double longitude, final double height) doesn&#039;t use SI units. Latitude and longitude are given in degrees, and height is given in kilometers.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
==== Code Example ====&lt;br /&gt;
&lt;br /&gt;
The following code sample computes geomagnetic field elements for four (date, position) of a fake trajectory :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
    public void codeExemple() throws PatriusException {&lt;br /&gt;
&lt;br /&gt;
        Utils.setDataRoot(&amp;quot;earth&amp;quot;);&lt;br /&gt;
        FramesFactory.setConfiguration(Utils.getIERS2003ConfigurationWOEOP(true));&lt;br /&gt;
&lt;br /&gt;
        //Fake trajectory : list of date and list of position&lt;br /&gt;
        List&amp;lt;AbsoluteDate&amp;gt; dateList = new ArrayList&amp;lt;AbsoluteDate&amp;gt;();&lt;br /&gt;
        AbsoluteDate initDate = new AbsoluteDate(2010, 1, 1, 12, 0, 0.0, TimeScalesFactory.getTT());&lt;br /&gt;
        &lt;br /&gt;
        dateList.add(initDate);&lt;br /&gt;
        dateList.add(new AbsoluteDate(initDate, 600));&lt;br /&gt;
        dateList.add(new AbsoluteDate(initDate, 1200));&lt;br /&gt;
        dateList.add(new AbsoluteDate(initDate, 1800));&lt;br /&gt;
        &lt;br /&gt;
        List&amp;lt;Vector3D&amp;gt; positionList = new ArrayList&amp;lt;Vector3D&amp;gt;();&lt;br /&gt;
        positionList.add(new Vector3D(6.46885878304673824e+06,-1.88050918456274318e+06, -1.32931592294715829e+04));&lt;br /&gt;
        positionList.add(new Vector3D(6.58239141552595049e+06,-1.43349476017528563e+06, -1.39460373997706010e+04));&lt;br /&gt;
        positionList.add(new Vector3D(6.66499609614125639e+06,-9.79745192516532145e+05, -1.45334684008149434e+04));&lt;br /&gt;
        positionList.add(new Vector3D(6.71628402448997274e+06,-5.21392324304617418e+05, -1.50526405214286660e+04));&lt;br /&gt;
        &lt;br /&gt;
        // Get the model to the initial date&lt;br /&gt;
        final GeoMagneticField model = GeoMagneticFieldFactory.getIGRF(dateList.get(0));&lt;br /&gt;
        &lt;br /&gt;
        // For each date and position, compute the GeoMagneticElement and add it to a list&lt;br /&gt;
        List&amp;lt;GeoMagneticElements&amp;gt; geoMagList = new ArrayList&amp;lt;GeoMagneticElements&amp;gt;();&lt;br /&gt;
        int i = 0;&lt;br /&gt;
        for (AbsoluteDate date : dateList){&lt;br /&gt;
            geoMagList.add(model.calculateField(positionList.get(i), FramesFactory.getEME2000(), date));&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Print each field vector B &lt;br /&gt;
        for (GeoMagneticElements geoMagElement : geoMagList){&lt;br /&gt;
            System.out.println(geoMagElement.toString());&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code produces the following standard output :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;MagneticField[B={29817,109;-2303,065; -9138,097},H=29905,92,F=31270,895,I=-16,991,D=-4,417]&lt;br /&gt;
MagneticField[B={29442,018;-2166,283; -8949,299},H=29521,606,F=30848,261,I=-16,864,D=-4,208]&lt;br /&gt;
MagneticField[B={29067,408;-1996,393; -8794,324},H=29135,885,F=30434,19,I=-16,796,D=-3,929]&lt;br /&gt;
MagneticField[B={28695,713;-1796,821; -8680,411},H=28751,913,F=30033,681,I=-16,799,D=-3,583]&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Atmosphere&#039;&#039;&#039;&lt;br /&gt;
|Interface for atmospheric models.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/Atmosphere.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ExtendedAtmosphere&#039;&#039;&#039;&lt;br /&gt;
|Interface for atmospheric models with detailed data.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/ExtendedAtmosphere.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SolarActivityDataProvider&#039;&#039;&#039;&lt;br /&gt;
|Interface for solar activity data providers, to be used for atmosphere models&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DTM2000InputParameters&#039;&#039;&#039;&lt;br /&gt;
|Container for solar activity data, compatible with DTM Atmosphere models.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/DTMInputParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MSISE2000InputParameters&#039;&#039;&#039;&lt;br /&gt;
|Container for solar activity data, compatible with MSISE2000 Atmosphere model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/MSISE2000InputParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTidesCoefficientsProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide ocean tides coefficients.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PotentialCoefficientsProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide gravity field coefficients.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/PotentialCoefficientsProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VariablePotentialCoefficientsProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide variable gravity field coefficients.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/variations/coefficients/VariablePotentialCoefficientsProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RadiationSensitive&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide an direct solar radiative pressure model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/radiation/RadiationSensitive.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RediffusedRadiationSensitive&#039;&#039;&#039;&lt;br /&gt;
|This interface is used to provide an rediffused radiative pressure model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/radiation/RediffusedRadiationSensitive.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticDataProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is a generic geomagnetic data provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticDataProvider.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&#039;&#039;&#039;Earth potential&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EGMFormatReader&#039;&#039;&#039;&lt;br /&gt;
|This reader is adapted to the EGM Format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/EGMFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GravityFieldFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory used to read gravity field files in several supported formats. &#039;&#039;&#039;Main user access point&#039;&#039;&#039; : the simple way of reading a potential file is by using this factory.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/GravityFieldFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VariableGravityFieldFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory used to read variable gravity field files in several supported formats. &#039;&#039;&#039;Main user access point&#039;&#039;&#039; : the simple way of reading a variable potential file is by using this factory.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/variations/coefficients/VariableGravityFieldFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GRGSFormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for the GRGS gravity field format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/GRGSFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GRGSRL02FormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for the GRGS RL02 variable gravity field format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/variations/coefficients/GRGSRL02FormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ICGEMFormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for the ICGEM gravity field format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/ICGEMFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PotentialCoefficientsReader&#039;&#039;&#039;&lt;br /&gt;
|This abstract class represents a Gravitational Potential Coefficients file reader.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/PotentialCoefficientsReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SHMFormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for the SHM gravity field format.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/potential/SHMFormatReader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Atmosphere Models&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DTM2000&#039;&#039;&#039;&lt;br /&gt;
|This class implements the DTM2000 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/DTM2000.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DTM2012&#039;&#039;&#039;&lt;br /&gt;
|This class implements the DTM2012 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/DTM2012.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;JB2006&#039;&#039;&#039;&lt;br /&gt;
|This class implements the JB2006 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/JB2006.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MSISE2000&#039;&#039;&#039;&lt;br /&gt;
|This class implements the MSIS00 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/MSISE2000.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|NRLMSISE00&lt;br /&gt;
|This class implements the NRLMSISE 1.0 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/MSIS/NRLMSISE00.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|NRLMSISE20&lt;br /&gt;
|This class implements the NRLMSISE 2.0 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/MSIS/NRLMSISE20.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;US76&#039;&#039;&#039;&lt;br /&gt;
|This class implements the US76 atmospheric model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/US76.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Solar Activity&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DTMSolarData&#039;&#039;&#039;&lt;br /&gt;
|This class represents a solar data container adapted for the DTM atmosphere models.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/DTMSolarData.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ClassicalMSISE2000SolarData&#039;&#039;&#039;&lt;br /&gt;
|This class represents a solar data container adapted for the MSISE2000 atmosphere model. The average ap values are computed arithmetically.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/ClassicalMSISE2000SolarData.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ContinuousMSISE2000SolarData&#039;&#039;&#039;&lt;br /&gt;
|This class represents a solar data container adapted for the MSISE2000 atmosphere model. The mean ap values are computed by trapezoidal integration.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/ContinuousMSISE2000SolarData.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ACSOLFormatReader&#039;&#039;&#039;&lt;br /&gt;
|This class reads ACSOL format solar activity data&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/ACSOLFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ConstantSolarActivity&#039;&#039;&#039;&lt;br /&gt;
|This class represents constant solar activity&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/ConstantSolarActivity.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NOAAFormatReader&#039;&#039;&#039;&lt;br /&gt;
|This class reads NOAA format solar activity data&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/NOAAFormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SolarActivityDataFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory used to read solar activity files and return SolarActivityDataProvider&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityDataFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SolarActivityToolbox&#039;&#039;&#039;&lt;br /&gt;
|Solar activity toolbox. Has methods to compute mean flux values, to convert from ap to kp.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/SolarActivityToolbox.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MarshallSolarActivityFutureEstimation&#039;&#039;&#039;&lt;br /&gt;
|This class reads and provides solar activity data needed by atmospheric models: F107 solar flux and Kp indexes.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/specialized/MarshallSolarActivityFutureEstimation.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ExtendedSolarActivityWrapper&#039;&#039;&#039;&lt;br /&gt;
|This class extends a solar activity provider out of its timespan with constant values.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/ExtendedSolarActivityWrapper.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ocean Tides Coefficients&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FES2004FormatReader&#039;&#039;&#039;&lt;br /&gt;
|Reader for FES2004 format coefficients files.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/FES2004FormatReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTidesCoefficientsFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory used to read ocean tides coefficients files in different formats and return an OceanTidesCoefficientsProvider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTidesCoefficientsReader&#039;&#039;&#039;&lt;br /&gt;
|This abstract class represents a Ocean Tides Coefficients file reader.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTidesCoefficientsSet&#039;&#039;&#039;&lt;br /&gt;
|Represents a line from the ocean tides data file.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsSet.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Geomagnetic Field&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticElements&#039;&#039;&#039;&lt;br /&gt;
|This class contains all the elements about a magnetic field : the magnetic field vector and associated caracteristics Inclination, Declination, Total Intensity, Horizontal Intensity.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticElements.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticField&#039;&#039;&#039;&lt;br /&gt;
|These objects are produced by the factory and are based on a model for a decimal year date and allows to compute GeomagneticElements &lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticField.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticFieldFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory to produce GeoMagneticField.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticFieldFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeoMagneticModelReader&#039;&#039;&#039;&lt;br /&gt;
|To load the model from an input file&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/GeoMagneticModelReader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;COFFileFormatReader&#039;&#039;&#039;&lt;br /&gt;
|Class loading the geomagnetic data from COF files.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/models/earth/COFFileFormatReader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Orbit_Propagation]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Events:_orbital&amp;diff=4168</id>
		<title>User Manual 4.18 Events: orbital</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Events:_orbital&amp;diff=4168"/>
		<updated>2026-06-10T10:28:19Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
Here are presented all the events detectors of the theme &amp;quot;orbital&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
Those event detectors are available in the packages :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detecors/package-summary.html Package fr.cnes.sirius.patrius.events.detectors]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Detectors ===&lt;br /&gt;
This section describes the meaning of the g switching function for the &amp;quot;orbital&amp;quot; event detectors, and their particularities :&lt;br /&gt;
&lt;br /&gt;
==== Alignment Detector ====&lt;br /&gt;
&lt;br /&gt;
This detector computes the difference &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; between the alignment angle &amp;lt;math&amp;gt;\beta_{threshold}&amp;lt;/math&amp;gt; and the angle between the satellite position, the central body and the second body position projection in the orbital plane.&amp;lt;br&amp;gt;&lt;br /&gt;
If &amp;lt;math&amp;gt;\theta_1 =-\pi - \theta&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\theta_2 = \pi - \theta&amp;lt;/math&amp;gt;, the g switching function will be:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\theta_1&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;\theta &amp;lt; \theta_1&amp;lt;/math&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;\theta &amp;lt; \theta_2&amp;lt;/math&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
and &amp;lt;math&amp;gt;\theta_2&amp;lt;/math&amp;gt; otherwise.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{threshold}&amp;lt;/math&amp;gt; is an oriented angle and is positive when is oriented as the orbital momentum.&lt;br /&gt;
&lt;br /&gt;
[[File:alignmentDetector.png|750x400px]]&lt;br /&gt;
&lt;br /&gt;
Axes &amp;lt;math&amp;gt;\vec a&amp;lt;/math&amp;gt; (satellite normalized position) and &amp;lt;math&amp;gt;\vec b&amp;lt;/math&amp;gt; (satellite normalized velocity) are transformed into axes &amp;lt;math&amp;gt;\vec x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec y&amp;lt;/math&amp;gt; knowing the value of &amp;lt;math&amp;gt;\beta_{threshold}&amp;lt;/math&amp;gt; angle; g is found projecting the target body position in the orbital plane and computing its &amp;lt;math&amp;gt;\vec x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec y&amp;lt;/math&amp;gt; components.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; target body projection is in the half-plane &amp;lt;math&amp;gt;y&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; target body projection is in the half-plane &amp;lt;math&amp;gt;y&amp;lt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; target body projection belongs to the straight line &amp;lt;math&amp;gt;y=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Altitude Detector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function measures the difference between the current altitude &amp;lt;math&amp;gt;h_{sat}&amp;lt;/math&amp;gt; and the threshold altitude &amp;lt;math&amp;gt;h_{thr}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g &amp;gt; 0 : h_{sat} &amp;gt; h_{thr}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 : h_{sat} &amp;lt; h_{thr}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ApsideDetector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function is the dot product of the satellite position and velocity vectors: &amp;lt;math&amp;gt;g =\vec p \cdot \vec v&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; the satellite is in the half-orbit from perigee to apogee;&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; the satellite is in the half-orbit from apogee to perigee.&lt;br /&gt;
&lt;br /&gt;
[[File:apside.png|center|539x316px]]&lt;br /&gt;
&lt;br /&gt;
==== DateDetector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function is the value of the difference between the current date and the target date. If no event dates have been added i.e. if no target dates have been initialized, &amp;lt;math&amp;gt;g=-1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== RelativeDateDetector ====&lt;br /&gt;
This detector extends of DateDetector. The g switching function is the same as the  [[#DateDetector|DateDetector]].&lt;br /&gt;
&lt;br /&gt;
==== EclipseDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector is in charge of the umbra/penumbra eclipse events detection.&amp;lt;br&amp;gt;&lt;br /&gt;
Different features are available:&lt;br /&gt;
* the occulted and occulting bodies are both spherical;&lt;br /&gt;
* the occulted body is a direction;&lt;br /&gt;
* the occulting body has an ellipsoid shape.&lt;br /&gt;
&lt;br /&gt;
In addition to that, the &amp;lt;code&amp;gt;EclipseDetector&amp;lt;/code&amp;gt; can detect eclipse events based on a threshold lighting ratio &amp;lt;math&amp;gt;\epsilon_{0}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;0&amp;lt;=\epsilon_{0}&amp;lt;=1&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
When &amp;lt;math&amp;gt;\epsilon_{0}=0&amp;lt;/math&amp;gt;, an eclipse event is triggered only if whole occulted body is hidden by the occulting body (total eclipse); when &amp;lt;math&amp;gt;\epsilon_{0}=1&amp;lt;/math&amp;gt;, an event is immediately triggered when the occulted body is partially hidden (penumbra eclipse).&amp;lt;br&amp;gt;&lt;br /&gt;
As a general rule, the lighting ratio is equal to:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\epsilon = 1-\frac{A_{occulted}}{\pi r_{occulted}^2}&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
where &amp;lt;math&amp;gt;r_{occulted}&amp;lt;/math&amp;gt; is the apparent radius of the occulted body. &amp;lt;br&amp;gt;&lt;br /&gt;
The g function is: &amp;lt;math&amp;gt;g=\epsilon_{0}-\epsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The g switching function computation needs the satellite position vector (&amp;lt;math&amp;gt;\vec P_{sat}&amp;lt;/math&amp;gt;), the occulted body (&amp;lt;math&amp;gt;\vec P_{ted}&amp;lt;/math&amp;gt;) and occulting body (&amp;lt;math&amp;gt;\vec P_{ing}&amp;lt;/math&amp;gt;) position vectors.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\vec {PS}=\vec {P_{ted}}-\vec {P_{sat}}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;sin(\widehat{rs})=\dfrac{r_{ted}}{|\vec {PS}|}&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\vec {PO}=\vec {P_{ing}}-\vec {P_{sat}}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;sin(\widehat{ro})=\dfrac{r_{ing}}{|\vec {PO}|}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; is the angle between &amp;lt;math&amp;gt;\vec {PS}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec {PO}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Distinction is made between total eclipse and partial eclipse.&amp;lt;br&amp;gt;&lt;br /&gt;
The following diagrams show the evolution of the g function value for an eclipse scenario with two spherical bodies. &lt;br /&gt;
&lt;br /&gt;
===== Total eclipse =====&lt;br /&gt;
&lt;br /&gt;
The passage to umbra is detected. The g switching function is &amp;lt;math&amp;gt;g = \alpha- \widehat{ro} + \widehat{rs}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; satellite is not in eclipse:&lt;br /&gt;
[[File:eclipse1.png|576x274px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; beginning of umbra:&lt;br /&gt;
[[File:eclipse2.png|570x161px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; umbra:&lt;br /&gt;
[[File:eclipse3.png|574x180px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; end of umbra:&lt;br /&gt;
[[File:eclipse4.png|570x182px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; satellite is not in eclipse:&lt;br /&gt;
[[File:eclipse5.png|588x264px]]&lt;br /&gt;
&lt;br /&gt;
===== Partial eclipse =====&lt;br /&gt;
&lt;br /&gt;
The passage to penumbra is detected. The g switching function is &amp;lt;math&amp;gt;g = \alpha- \widehat {ro} - \widehat {rs}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; satellite is not in eclipse:&lt;br /&gt;
[[File:eclipse6.png|566x273px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; beginning of penumbra:&lt;br /&gt;
[[File:eclipse7.png|552x198px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; penumbra:&lt;br /&gt;
[[File:eclipse8.png|581x178px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; end of penumbra:&lt;br /&gt;
[[File:eclipse9.png|578x217px]]&lt;br /&gt;
&lt;br /&gt;
Another feature of the &amp;lt;code&amp;gt;EclipseDetector&amp;lt;/code&amp;gt; is the detection of partial and total eclipse by a spheroid.&lt;br /&gt;
&lt;br /&gt;
[[File:ellipsoideclipse.png|center]]&lt;br /&gt;
&lt;br /&gt;
The point on the horizon (H) is calculated as the point of the ellipsoid that is in the same plane as A, C and S (respectively center of occulted body, center of occulting body and satellite). The distance of H to the center C of the ellipsoid is then projected onto a plane orthogonal to the Satellite / Occulting (SA) body direction, and the resulting length is considered as the radius of an &amp;quot;apparent&amp;quot; sphere representing the occulting body. The partial and total eclipse are then computed as per above.&lt;br /&gt;
&lt;br /&gt;
===== Particular case =====&lt;br /&gt;
&lt;br /&gt;
A specific case is having a spacecraft lower than the occulting body radius (i.e. spacecraft altitude &amp;lt; occulting body radius).&amp;lt;br&amp;gt;&lt;br /&gt;
Two cases are possible:&lt;br /&gt;
* The satellite is behind the occulted body (angle occulted body- occulting body - satellite &amp;gt; Pi/2): satellite is considered to be in total eclipse.&lt;br /&gt;
* The satellite is in front of the occulted body (angle occulted body- occulting body - satellite &amp;lt;= Pi/2): apparent radius of occulting body cannot be computed. Hence it is considered to be equal to Pi/2 (slight approximation since it means satellite is considered to be lying exactly on the surface of the occulting body). Then usual computation of g function applies.&lt;br /&gt;
&lt;br /&gt;
==== BodyInEclipseDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector is in charge of the umbra/penumbra eclipse events detection for a non-point target body. 3 bodies are considered to compute the BodyInEclipse events:&lt;br /&gt;
&lt;br /&gt;
*Target body: body on which the eclipse events are to be detected.&lt;br /&gt;
&lt;br /&gt;
*Occulted body: this is the body that is no longer visible from the target body due to the presence of the occulting body in the line of sight (the occulted body is generally the sun).&lt;br /&gt;
&lt;br /&gt;
*Occulting body: body that causes the eclipse.&lt;br /&gt;
[[Fichier:BodyInEclipseDetector1.png|centré|683x683px]]&lt;br /&gt;
The following assumptions are made:&lt;br /&gt;
* The three bodies are considered spherical during calculations (the apparent radius of the bodies are used).&lt;br /&gt;
* For the cases where the target body is fully in eclipse, the target body must be much smaller than the possible irregularities of the occulting body to avoid false positives. (Further explanation of this point in the edge cases section).&lt;br /&gt;
* No atmospheric effect is taken into account.&lt;br /&gt;
*The propagation delay can be activated or not.&lt;br /&gt;
&lt;br /&gt;
The core of the algorithm consists of selecting a point on the surface of the target that is representative of the surface of the target as a whole, and then calculating the illumination rate at that point. &lt;br /&gt;
&lt;br /&gt;
The calculation of g is therefore done in three steps:&lt;br /&gt;
*Selection of the reference point: This depends on the type of eclipse targeted (partial or total; whether the body is completely eclipsed or not), the chosen model (complete or simplified), and the relative position of the bodies involved.&lt;br /&gt;
* Calculation of the illumination rate at the selected target point.&lt;br /&gt;
*Comparison of the obtained illumination rate with the target illumination rate (0 if we are looking for total eclipses, 1 if we are looking for partial eclipses).&lt;br /&gt;
2 modes are available for the computation of eclipse events:&lt;br /&gt;
&lt;br /&gt;
1.   Exact model: &lt;br /&gt;
&lt;br /&gt;
In this model, the occulted body is considered as non-punctual. 4 points are of interest to detect the eclipse events: &lt;br /&gt;
*H&amp;lt;sub&amp;gt;PPU&amp;lt;/sub&amp;gt; = point of interest for entry partially in penumbra&lt;br /&gt;
*H&amp;lt;sub&amp;gt;PU&amp;lt;/sub&amp;gt; = point of interest for entry partially in umbra&lt;br /&gt;
* H&amp;lt;sub&amp;gt;TPU&amp;lt;/sub&amp;gt; = point of interest for entry totally in penumbra&lt;br /&gt;
*H&amp;lt;sub&amp;gt;TU&amp;lt;/sub&amp;gt; = point of interest for entry totally in umbra&lt;br /&gt;
[[Fichier:BodyInEclipseDetector2.png|centré|776x776px]]&lt;br /&gt;
2.   Approximative model&lt;br /&gt;
&lt;br /&gt;
In this model, the occulted body is considered as punctual. In this case, only 2 interest points exists to detect eclipse events:  &lt;br /&gt;
*H&amp;lt;sub&amp;gt;P&amp;lt;/sub&amp;gt; = point of interest for entry partially in eclipse&lt;br /&gt;
*H&amp;lt;sub&amp;gt;T&amp;lt;/sub&amp;gt; = point of interest for entry totally in eclipse&lt;br /&gt;
[[Fichier:BodyInEclipseDetector3.png|centré|771x771px]]&lt;br /&gt;
For any of the models, the lighting ratio of the corresponding interest points is computed to detect the events.&lt;br /&gt;
&lt;br /&gt;
The lighting ratio is then compared against the target lighting ratio (0 if we want to detect total eclipses and 1 for partial eclipses), and the value of the g function (switching function) is returned for a given date. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Edge Cases:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Occulting body &amp;lt;&amp;lt; Target Body:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
If the occulting body is smaller than the target body, it might happen that none of the 4 points of interest is in eclipse, however the target body is partially in eclipse as shown in the figure below:&lt;br /&gt;
[[Fichier:BodyInEclipseDetector4.png|centré|806x806px]]&lt;br /&gt;
This case is possible only if the line SA intersects the target body. In this case, none of the interest points of the exact model or of the approximative model are used to compute the lighting ratio. In this case it is the intersection point H&amp;lt;sub&amp;gt;C&amp;lt;/sub&amp;gt; that is used to compute the lighting ratio (to know if it is inside umbra or only inside penumbra).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Shape of occulting body non spherical:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In the hypotheses section it was said that the 3 bodies are considered spherical. However, it is really only the occulted and the target bodies that have to be spherical. The occulting body might have any other shape. It is during the computation that we model the occulting body as spherical by using the getApparentRadius method. &lt;br /&gt;
&lt;br /&gt;
In certain edge cases, a BodyInEclipse event might be raised by the propagator, even though this is not actually the case. This type of situation can occur when the occulting body is elongated in the direction of the plane of the eclipse. &lt;br /&gt;
[[Fichier:BodyInEclipseDetector5.png|centré]]&lt;br /&gt;
The calculation method considers a planar projection of the problem. When an object is detected as &amp;quot;completely in the shadow&amp;quot; of another, it is ensured that the furthest point of the eclipse cone in the plane containing the centers of the three objects is in eclipse. This guarantees that all points of the target object belonging to this plane are in eclipse. However, there is no guarantee for points outside of the plane. This is not an issue when the obscuring object is spherical, but it can become one when it is elongated. In the example below, the target is considered &amp;quot;entirely&amp;quot; eclipsed by the detector, even though some points are illuminated. &lt;br /&gt;
&lt;br /&gt;
This type of case is unlikely to occur in the Earth-Moon scenario, where the obscuring body is very close to a sphere, but it is not impossible in the case of asteroids, which have non-regular shapes. Other problems of this kind can arise when the body is not convex, but such cases become extremely rare.&lt;br /&gt;
&lt;br /&gt;
This is why for the cases where the target body is fully in eclipse, the target body must be much smaller than the possible irregularities of the occulting body to avoid false positives.&lt;br /&gt;
&lt;br /&gt;
====PlaneCrossingDetector====&lt;br /&gt;
The detector allows to detect if a spacecraft crosses a plane defined in a specific reference frame. The following entries are needed to define a &amp;lt;code&amp;gt;PlaneCrossingDetector&amp;lt;/code&amp;gt;:&lt;br /&gt;
*plane reference frame ;&lt;br /&gt;
*point which is contained in the plane ;&lt;br /&gt;
* normal vector to plane.&lt;br /&gt;
&lt;br /&gt;
The detection function &amp;lt;math&amp;gt;g()&amp;lt;/math&amp;gt; monitors the dot product between the normal vector to plane and the distance position vector of the spacecraft with respect to the origin of the point of the plan:&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt;the satellite is over the plane;&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt;the satellite is under the plane.&lt;br /&gt;
&lt;br /&gt;
==== NodeDetector ====&lt;br /&gt;
The &amp;lt;code&amp;gt;NodeDetector&amp;lt;/code&amp;gt; detects the orbital nodes; the user can choose what the detect (ascending nodes, descending nodes or both) through the &amp;lt;code&amp;gt;slopeSelection &amp;lt;/code&amp;gt; parameter. It is a particular application case of the &amp;lt;code&amp;gt;PlaneCrossingDetector&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
The g switching function returns the Z component of the satellite position in the geocentric frame:&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt;the satellite is over the equatorial plane (in its orbit from ascending node to descending node);&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt;the satellite is under the equatorial plane (in its orbit from descending node to ascending node).&lt;br /&gt;
&lt;br /&gt;
====DistanceDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;DistanceDetector &amp;lt;/code&amp;gt; detects the time when the distance between the spacecraft and a point of space reaches a given value.&lt;br /&gt;
&lt;br /&gt;
The point of space is given as a &amp;lt;code&amp;gt;PVcoordinatesProvider&amp;lt;/code&amp;gt; : it can be either a celestial body (as a &amp;lt;code&amp;gt;CelestialBody&amp;lt;/code&amp;gt;), a point at the surface of a body (as a &amp;lt;code&amp;gt;TopocentricFrame&amp;lt;/code&amp;gt;), or any another class that implements that interface.&lt;br /&gt;
&lt;br /&gt;
Here is the example for a point on the surface of a body :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// earth shape&lt;br /&gt;
final BodyShape earth = new OneAxisEllipsoid(earthRadius, ea, ITRFFrame);&lt;br /&gt;
&lt;br /&gt;
// considered point&lt;br /&gt;
final EllipsoidPoint point = new EllipsoidPoint(ellipsoid, LLHCoordinatesSystem.ELLIPSODETIC, latitude, longitude, altitude, &amp;quot;point &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// associated topocentric frame : this object is a PVCoordinatesProvider&lt;br /&gt;
final TopocentricFrame topoFramePoint = new TopocentricFrame(point, &amp;quot;Gstation&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// detector&lt;br /&gt;
final DistanceDetector detector = new DistanceDetector(topoFramePoint, distance);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Its g switching function computes the difference between the spacecraft position and the point position (in the same frame), and then subtracts the given distance from its norm. &lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt;the distance spacecraft/point is bigger than the distance threshold value;&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt;the distance spacecraft/point is smaller than the distance threshold value;&lt;br /&gt;
&lt;br /&gt;
====ExtremaDistanceDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaDistanceDetector&amp;lt;/code&amp;gt; detects if the spacecraft is at a local extremum for the distance relative to a point of space, defined the same way as in the previous DistanceDetector. The choice of the extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;distanceType&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the square norm of the velocity for the vector representing this distance, thus the sign change is indeed a local extremum. &lt;br /&gt;
&lt;br /&gt;
====ExtremaLatitudeDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaLatitudeDetector&amp;lt;/code&amp;gt; detects if the spacecraft is at a local extremum for the geodetic latitude. The choice of the extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;latitudeType&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the z-component of the spacecraft velocity in the orbit definition frame.&lt;br /&gt;
&lt;br /&gt;
====LatitudeDetector====&lt;br /&gt;
The &amp;lt;code&amp;gt;LatitudeDetector&amp;lt;/code&amp;gt; detects the time when the spacecraft reaches a given geodetic latitude, the &amp;lt;code&amp;gt;BodyShape&amp;lt;/code&amp;gt; of the earth being known to compute it.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the difference between the current latitude and the one to detect.&lt;br /&gt;
&lt;br /&gt;
====ExtremaLongitudeDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaLongitudeDetector&amp;lt;/code&amp;gt; detects if the spacecraft is at a local extremum for the longitude. The choice of the extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;extremumType&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
The g switching function is the dot vector of the position with the result of the cross product of the velocity relative to the body and unitary vector Z :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g =\vec P \cdot (\vec Vrel \wedge \vec Vz)&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The main part of this function is the cross product which switches when the relative velocity is colinear to Z.&lt;br /&gt;
&lt;br /&gt;
====LongitudeDetector====&lt;br /&gt;
The &amp;lt;code&amp;gt;LongitudeDetector&amp;lt;/code&amp;gt; detects the time when the spacecraft reaches a given longitude.&lt;br /&gt;
&lt;br /&gt;
Working with longitude always gives a problem of continuity when longitude pass from PI rad to- PI rad. The best solution find to avoid this is to save some information from the last computation of the g function. &lt;br /&gt;
&lt;br /&gt;
In this way the g function is the following difference expressed between-PI rad and PI rad : currentLongitude - longitudeToDetect&lt;br /&gt;
&lt;br /&gt;
At each g function call, this difference is saved, and each time the difference between the current difference and the last difference is greater than PI rad, it means there is a discontinuity, the g fonction is opposed. This avoids discontinuity. Then all zero are detected.&lt;br /&gt;
&lt;br /&gt;
This solution, also avoids problem about detecting a longitude at PI rad further (that we meet with a sin(a- b) g function).&lt;br /&gt;
&lt;br /&gt;
==== Safety Margin Detector ====&lt;br /&gt;
&lt;br /&gt;
This detector computes the safety margin ∆ with respect to the escape velocity. Users have the choice between two methods for the safety margin computation:&lt;br /&gt;
* INSTANTANEOUS: The safety margin is computed using the spacecraft&#039;s current velocity v and the escape velocity v_esc evaluated at the satellite&#039;s current position (v_esc=√(2μ/r)): ∆ = v/v_esc-1&lt;br /&gt;
* PERICENTRE: The safety margin is computed at the orbit&#039;s pericenter (where the satellite speed is maximum) using the orbital eccentricity e: ∆ = √((1+e)/2)-1&lt;br /&gt;
&lt;br /&gt;
Note: For circular orbits (e=0 and v=√(μ/r)), both methods are equivalent and yield ∆ = 1/√2-1.&lt;br /&gt;
&lt;br /&gt;
The g switching function is the difference between the computed safety margin ∆ and a user-defined safety margin threshold t (safetyMarginIn): g = ∆-t&lt;br /&gt;
&lt;br /&gt;
====AOLDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;AOLDetector&amp;lt;/code&amp;gt; detects when the spacecraft reaches a predetermined argument of latitude (true, mean or eccentric supportes) with respect to a given equator ; the argument of latitude is the angle between the spacecraft position and the ascending node.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the sinus of the difference between the spacecraft current angular position &amp;lt;math&amp;gt;\beta&amp;lt;/math&amp;gt; and the threshold position value &amp;lt;math&amp;gt;\beta_{input}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g=sin(\beta- \beta_{input})&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
An AOL event is triggered only if the g-function slope is positive at its zero.&lt;br /&gt;
&lt;br /&gt;
====AnomalyDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;AnomalyDetector&amp;lt;/code&amp;gt; detects when the spacecraft reaches a predetermined anomaly; the anomaly is the angle between the spacecraft position and the perigee.&amp;lt;br&amp;gt;&lt;br /&gt;
Three types of anomaly can be detected: true, mean and eccentric anomaly.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the sinus of the difference between the spacecraft current anomaly and the threshold anomaly value:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g=sin(\alpha- \alpha_{input})&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
(This g function is identical to the AOLDetector g function).&amp;lt;br&amp;gt;&lt;br /&gt;
Like the &amp;lt;code&amp;gt;AOLDetector&amp;lt;/code&amp;gt;, an anomaly event is triggered only if the g-function slope is positive at its zero.&lt;br /&gt;
&lt;br /&gt;
Using precaution : This detector is unusable on a circular orbit where the perigee always moves very fast and in any way.&lt;br /&gt;
&lt;br /&gt;
====ThreeBodiesAngleDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ThreeBodiesAngleDetector&amp;lt;/code&amp;gt; detects when the angle between three bodies (they can be celestial bodies, spacecrafts, ground stations, ...) is equal to a predetermined value.&amp;lt;br&amp;gt;&lt;br /&gt;
If &amp;lt;math&amp;gt;\vec{P_{1}}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\vec{P_{2}}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec{P_{3}}&amp;lt;/math&amp;gt; are the positions of the three bodies, and &amp;lt;math&amp;gt;\vec{P_{21}}&amp;lt;/math&amp;gt; is the difference &amp;lt;math&amp;gt;\vec{P_{2}}-\vec{P_{1}}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec{P_{23}}&amp;lt;/math&amp;gt; the difference &amp;lt;math&amp;gt;\vec{P_{2}}-\vec{P_{3}}&amp;lt;/math&amp;gt;, the computed angle will be: &amp;lt;math&amp;gt;\widehat{\vec{P_{21}} \vec{P_{23}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:threeBodies.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the difference between the current angle between the three bodies and the threshold angle. The threshold angle is not oriented and its value is between 0 and PI.&lt;br /&gt;
&lt;br /&gt;
====ExtremaThreeBodiesAngleDetector====&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaThreeBodiesAngleDetector&amp;lt;/code&amp;gt; detects when the angle between three bodies (defined the same way as in the &amp;lt;code&amp;gt;ThreeBodiesAngleDetector&amp;lt;/code&amp;gt;) reaches its minimal or maximal value.&amp;lt;br&amp;gt;&lt;br /&gt;
The choice of the detected extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;extremumType&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the derivative of the angle value (in fact, part of the derivative : a factor with a &lt;br /&gt;
constant sign has been ignored).&amp;lt;br&amp;gt;&lt;br /&gt;
This derivative is obtained by expressing all the positions and velocities of the two extreme points (&amp;lt;math&amp;gt;P_{1}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;P_{3}&amp;lt;/math&amp;gt;) in a frame linked to the one at the angle origin (&amp;lt;math&amp;gt;P_{2}&amp;lt;/math&amp;gt;).&amp;lt;br&amp;gt;&lt;br /&gt;
If the two vectors from the new origin are &amp;lt;math&amp;gt;\vec{P_{21}}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec{P_{23}}&amp;lt;/math&amp;gt; the angle expression is : &amp;lt;math&amp;gt;\arccos(\vec{P_{21}}.\vec{P_{23}} / (|\vec{P_{21}}|.|\vec{P_{23}}|))&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Once derivated as &amp;lt;math&amp;gt;(gof)&#039; = (g&#039;of).f&#039;&amp;lt;/math&amp;gt; and the &amp;lt;math&amp;gt;arccos&amp;lt;/math&amp;gt; derivative being always negative, the switching function is minus the derivative of the inner expression &amp;lt;math&amp;gt;\vec{P_{21}}.\vec{P_{23}} / (|\vec{P_{21}}|.|\vec{P_{23}}|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====BetaAngleDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;BetaAngleDetector&amp;lt;/code&amp;gt; detects when the beta angle reaches a predetermined value; the beta angle is the angle between the orbit plane and the vector to the Sun.&lt;br /&gt;
[[File:BetaAngle.png|center]]&lt;br /&gt;
&lt;br /&gt;
The beta angle belongs to [- π/2 , π/2 ]; its sign is positive when the Sun is in the half-plane containing the spacecraft&#039;s momentum.&lt;br /&gt;
&lt;br /&gt;
==== LocalTimeAngleDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;LocalTimeAngleDetector&amp;lt;/code&amp;gt; detects when the spacecraft local time is equal to a predetermined value; the spacecraft local time is the angle between the projections of the Earth-Sun vector and the Earth-spacecraft vector in the equatorial plane plus PI. In PATRIUS, local time is expressed as an angle in the range [-PI; PI[. Local time angle is PI (or 12.00h) when the geometric angle Sun-Earth-Spacecraft is 0 and 0 (or 0.00h) when this angle is PI.&amp;lt;br&amp;gt;&lt;br /&gt;
The local time is increasing for prograde orbits and decreasing for retrograde orbits. The events are detected in both cases.&lt;br /&gt;
&lt;br /&gt;
The g function is the following difference expressed between-PI rad and PI rad : &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;currentLocalTime- localTimeToDetect&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At each g function call, this difference is saved, and each time the difference between the current difference and the last difference is greater than PI rad, it means there is a discontinuity, the g fonction is opposed. This avoids discontinuity. Then all zero are detected.&lt;br /&gt;
&lt;br /&gt;
This solution, also avoids problem about detecting a local time at PI rad further (that we meet with a sin(a- b) g function).&lt;br /&gt;
&lt;br /&gt;
====BodyPointLocalTimeAngleDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;BodyPointLocalTimeAngleDetector&amp;lt;/code&amp;gt; follows the same logic as its parent class &amp;lt;code&amp;gt;LocalTimeAngleDetector&amp;lt;/code&amp;gt; but, instead of computing the events for a certain position of the spacecraft, the events are computed with respect to a point of the surface of the body, by using the zenithal direction (normal to the surface). &lt;br /&gt;
&lt;br /&gt;
To compute the local time of a certain point in a body, first the Frame is verified (it cannot be null). Then, the normal direction of the body point is computed. Afterwards, the sun position is obtained. The local time corresponds to the angle between the projections of the Earth-Sun and the normal direction over the equatorial plane plus PI.&lt;br /&gt;
&lt;br /&gt;
====SolarTimeAngleDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;SolarTimeAngleDetector&amp;lt;/code&amp;gt; detects when the spacecraft solar time is equal to a predetermined value; the spacecraft solar time is the angle between the the Earth-Sun projection in the orbital plane and the Earth-spacecraft vector plus PI. In PATRIUS, solar time is expressed as an angle in the range [-PI; PI[. Solar time angle is PI (or 12.00h) when the geometric angle Sun-Earth-Spacecraft is 0 and 0 (or 0.00h) when this angle is PI. &amp;lt;br&amp;gt;&lt;br /&gt;
The solar time is always increasing with time. It is mesured around the orbit momentum.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the sinus of the difference between the spacecraft current solar time &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; and the threshold solar time value &amp;lt;math&amp;gt;\theta_{t}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g=sin(\theta- \theta_{t})&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Like the &amp;lt;code&amp;gt;AOLDetector&amp;lt;/code&amp;gt;, a solar time event is triggered only if the g-function slope is positive at its zero.&lt;br /&gt;
&lt;br /&gt;
====NadirSolarIncidenceDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;NadirSolarIncidenceDetector&amp;lt;/code&amp;gt; detects when the solar incidence, seen from the nadir point of the spacecraft, reaches a predetermined value.&amp;lt;br&amp;gt;&lt;br /&gt;
The solar incidence is the angle between the nadir- satellite vector and the nadir - sun vector.&lt;br /&gt;
&lt;br /&gt;
[[File:nadirsolarincidence.png|center]]&lt;br /&gt;
&lt;br /&gt;
====BodyPointSolarIncidenceDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;BodyPointSolarIncidenceDetector&amp;lt;/code&amp;gt; detects when the solar incidence angle reaches a predetermined value. The solar incidence is the angle between the interest point-satellite vector and the interest point-sun vector. The interest point being described by a BodyPoint.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:BodyPointSolarIncidenceDetector.png|center]]&lt;br /&gt;
&lt;br /&gt;
====EarthZoneDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;EarthZoneDetector&amp;lt;/code&amp;gt; detects when the spacecraft enters and leaves an earth zone. Several separated zones can be defined for one detector instance. In that case, the EarthZoneDetector detects the entery of the satellite NADIR point in any of the zones.&lt;br /&gt;
&lt;br /&gt;
The zones can be described two ways : &lt;br /&gt;
*As an array of {latitude, longitudes} that define the geodetic points with a zero altitude on a BodyShape. With this definition, the test made will be the entering of the spacecraft&#039;s NADIR point in the zone.&lt;br /&gt;
*As an array of vectors expressed in a given frame. With this definition, the entering of the spacecraft itself in the conic field from the center of the given frame to those points will be detected. Note that the given frame must be a terrestrial frame for the detection of earth zones entering, but the use of other frames is possible (other bodies, inertial frames…).&lt;br /&gt;
&lt;br /&gt;
In both cases, the points must respect the following conditions : &lt;br /&gt;
*At least 3 points are needed to define a zone&lt;br /&gt;
*two consecutive points must not be too close (1.e-10 on the difference of thier normalized values)&lt;br /&gt;
*the arc between two consecutive points must not cross the one between two consecutive others of the same zone.&lt;br /&gt;
&lt;br /&gt;
The points must also be given in the right order : from the point i to the point i + 1, if the associated vector from the center of the earth are &amp;lt;math&amp;gt;v_{i}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;v_{i + 1}&amp;lt;/math&amp;gt;, the inside of the zone is on the left, e.g. the side of the positive cross vector &amp;lt;math&amp;gt;v_{i} . v_{i + 1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Constructors with default maxCheck and threshold values are available, but beware of their values, and use the other constructors if needed  : if the zone is complex and the MaxCheck too large, the event detection could fail, because it would not manage to converge. To compute the event with enough precision to converge, set a small enough MaxCheck. To compute an approximative event even if the zone is precise and complex, set a large enough Threshold.&lt;br /&gt;
&lt;br /&gt;
===Particular detections===&lt;br /&gt;
All those detectors can be used for the following particular cases :&lt;br /&gt;
&lt;br /&gt;
*sub-solar point reaching  : use the SolarTimeAngleDetector with a &amp;quot;12h&amp;quot; time to detect.&lt;br /&gt;
*generic masking by a spherical body : use the GenericEclipseDetector, or the ThreeBodiesAngleDetector.&lt;br /&gt;
*terminator reaching (the nadir point reaches the night / day limit) : use the NadirSolarIncidenceDetector with a zero incidence.&lt;br /&gt;
*Sun interference in ground antennas : use the ThreeBodiesAngleDetector.&lt;br /&gt;
*RF interference between the main spacecraft and another one : use the ThreeBodiesAngleDetector&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
{{specialInclusion prefix=$theme_sub section=&amp;quot;GettingStarted&amp;quot;/}}&lt;br /&gt;
&lt;br /&gt;
== Contents==&lt;br /&gt;
===Interfaces===&lt;br /&gt;
All the detectors implement the interface :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Javadoc &lt;br /&gt;
|-&lt;br /&gt;
|EventDetector&lt;br /&gt;
|This interface represents an event finder.&lt;br /&gt;
|[&amp;lt;nowiki/&amp;gt;{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/EventDetector.html EventDetector ]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Classes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|AlignmentDetector&lt;br /&gt;
|This class handles (satellite/central body/projection in the orbital plane of secondary body) alignment events.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AlignmentDetector.html AlignmentDetector]&lt;br /&gt;
|-&lt;br /&gt;
|AltitudeDetector&lt;br /&gt;
|This class handles satellite altitude crossing events.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AltitudeDetector.html AltitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ApsideDetector&lt;br /&gt;
|This class handles satellite apogee and perigee crossing events.&lt;br /&gt;
| [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ApsideDetector.html ApsideDetector]&lt;br /&gt;
|-&lt;br /&gt;
|BodyInEclipseDetector&lt;br /&gt;
|This class handles the umbra/penumbra eclipse events detection for a non-point target body&lt;br /&gt;
|[{{JavaDoc4.18}}&amp;lt;nowiki&amp;gt;/fr/cnes/sirius/patrius/events/detectors/BodyInEclipseDetector.html BodyInEclipseDetector]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|BodyPointLocalTimeAngleDetector &lt;br /&gt;
|This class handles events representing the fact that a point on the surface of a spacecraft reaches a certain local time angle&lt;br /&gt;
|[{{JavaDoc4.18}}&amp;lt;nowiki&amp;gt;/fr/cnes/sirius/patrius/events/detectors/BodyPointLocalTimeAngleDetector.html BodyPointLocalTimeAngleDetector]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|DateDetector &lt;br /&gt;
|This class handles the occurrence of predefined dates.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/DateDetector.html DateDetector]&lt;br /&gt;
|-&lt;br /&gt;
|EclipseDetector&lt;br /&gt;
|This class handles total or partial eclipse events.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/EclipseDetector.html EclipseDetector]&lt;br /&gt;
|-&lt;br /&gt;
|NodeDetector&lt;br /&gt;
|This class handles satellite equator crossing events.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/NodeDetector.html NodeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|DistanceDetector&lt;br /&gt;
|This class handles events relating to the distance between the satellite and a given body.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/DistanceDetector.html DistanceDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ExtremaDistanceDetector&lt;br /&gt;
|This class handles events representing the reaching of extrema for the distance to a given body.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ExtremaDistanceDetector.html ExtremaDistanceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| ExtremaLatitudeDetector&lt;br /&gt;
|This class handles events representing the reaching of extrema for the geodetic latitude.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ExtremaLatitudeDetector.html ExtremaLatitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ExtremaLongitudeDetector&lt;br /&gt;
|This class handles events representing the reaching of extrema for the longitude.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ExtremaLongitudeDetector.html ExtremaLongitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|LatitudeDetector&lt;br /&gt;
|This class handles events representing the reaching of a given geodetic latitude, the earth shape being known.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/LatitudeDetector.html LatitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|LongitudeDetector&lt;br /&gt;
|This class handles events representing the reaching of a given longitude&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/LongitudeDetector.html LongitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|AnomalyDetector&lt;br /&gt;
|This class handles events representing the reaching of an anomaly angle.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AnomalyDetector.html AnomalyDetector]&lt;br /&gt;
|-&lt;br /&gt;
|SafetyMarginDetector&lt;br /&gt;
| This class handles escape velocity crossing detection.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/SafetyMarginDetector.html SafetyMarginDetector]|-&lt;br /&gt;
|-&lt;br /&gt;
|AOLDetector&lt;br /&gt;
| This class handles events representing the reaching of an argument of latitude value.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AOLDetector.html AOLDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ThreeBodiesAngleDetector&lt;br /&gt;
|This class handles events representing the reaching of a predetermined angle between three bodies.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ThreeBodiesAngleDetector.html ThreeBodiesAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ExtremaThreeBodiesAngleDetector&lt;br /&gt;
|This class handles events representing the reaching of of extrema for the angle between three bodies.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ExtremaThreeBodiesAngleDetector.html ExtremaThreeBodiesAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|BetaAngleDetector&lt;br /&gt;
|This class handles the event : reaching a given beta angle value for a spacecraft.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/BetaAngleDetector.html BetaAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|LocalTimeAngleDetector&lt;br /&gt;
|This class handles events representing the reaching of a predetermined spacecraft local time angle.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/LocalTimeAngleDetector.html LocalTimeAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|SolarTimeAngleDetector&lt;br /&gt;
|This class handles events representing the reaching of a predetermined spacecraft solar time angle.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/SolarTimeAngleDetector.html SolarTimeAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|NadirSolarIncidenceDetector&lt;br /&gt;
|This class handles events representing the reaching of a predetermined spacecraft nadir point solar incidence.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/NadirSolarIncidenceDetector.html NadirSolarIncidenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
|EarthZoneDetector&lt;br /&gt;
|This class handles events representing the entering and leaving of earth zones.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/EarthZoneDetector.html EarthZoneDetector]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
[[Category:User Manual 4.18 Mission]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Events:_orbital&amp;diff=4167</id>
		<title>User Manual 4.18 Events: orbital</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Events:_orbital&amp;diff=4167"/>
		<updated>2026-06-10T10:26:54Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
Here are presented all the events detectors of the theme &amp;quot;orbital&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
Those event detectors are available in the packages :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detecors/package-summary.html Package fr.cnes.sirius.patrius.events.detectors]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Detectors ===&lt;br /&gt;
This section describes the meaning of the g switching function for the &amp;quot;orbital&amp;quot; event detectors, and their particularities :&lt;br /&gt;
&lt;br /&gt;
==== Alignment Detector ====&lt;br /&gt;
&lt;br /&gt;
This detector computes the difference &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; between the alignment angle &amp;lt;math&amp;gt;\beta_{threshold}&amp;lt;/math&amp;gt; and the angle between the satellite position, the central body and the second body position projection in the orbital plane.&amp;lt;br&amp;gt;&lt;br /&gt;
If &amp;lt;math&amp;gt;\theta_1 =-\pi - \theta&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\theta_2 = \pi - \theta&amp;lt;/math&amp;gt;, the g switching function will be:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\theta_1&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;\theta &amp;lt; \theta_1&amp;lt;/math&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; if &amp;lt;math&amp;gt;\theta &amp;lt; \theta_2&amp;lt;/math&amp;gt;,&amp;lt;br&amp;gt;&lt;br /&gt;
and &amp;lt;math&amp;gt;\theta_2&amp;lt;/math&amp;gt; otherwise.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\beta_{threshold}&amp;lt;/math&amp;gt; is an oriented angle and is positive when is oriented as the orbital momentum.&lt;br /&gt;
&lt;br /&gt;
[[File:alignmentDetector.png|750x400px]]&lt;br /&gt;
&lt;br /&gt;
Axes &amp;lt;math&amp;gt;\vec a&amp;lt;/math&amp;gt; (satellite normalized position) and &amp;lt;math&amp;gt;\vec b&amp;lt;/math&amp;gt; (satellite normalized velocity) are transformed into axes &amp;lt;math&amp;gt;\vec x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec y&amp;lt;/math&amp;gt; knowing the value of &amp;lt;math&amp;gt;\beta_{threshold}&amp;lt;/math&amp;gt; angle; g is found projecting the target body position in the orbital plane and computing its &amp;lt;math&amp;gt;\vec x&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec y&amp;lt;/math&amp;gt; components.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; target body projection is in the half-plane &amp;lt;math&amp;gt;y&amp;gt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; target body projection is in the half-plane &amp;lt;math&amp;gt;y&amp;lt;0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; target body projection belongs to the straight line &amp;lt;math&amp;gt;y=0&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Altitude Detector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function measures the difference between the current altitude &amp;lt;math&amp;gt;h_{sat}&amp;lt;/math&amp;gt; and the threshold altitude &amp;lt;math&amp;gt;h_{thr}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g &amp;gt; 0 : h_{sat} &amp;gt; h_{thr}&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 : h_{sat} &amp;lt; h_{thr}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ApsideDetector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function is the dot product of the satellite position and velocity vectors: &amp;lt;math&amp;gt;g =\vec p \cdot \vec v&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; the satellite is in the half-orbit from perigee to apogee;&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; the satellite is in the half-orbit from apogee to perigee.&lt;br /&gt;
&lt;br /&gt;
[[File:apside.png|center|539x316px]]&lt;br /&gt;
&lt;br /&gt;
==== DateDetector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function is the value of the difference between the current date and the target date. If no event dates have been added i.e. if no target dates have been initialized, &amp;lt;math&amp;gt;g=-1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== RelativeDateDetector ====&lt;br /&gt;
This detector extends of DateDetector. The g switching function is the same as the  [[#DateDetector|DateDetector]].&lt;br /&gt;
&lt;br /&gt;
==== EclipseDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector is in charge of the umbra/penumbra eclipse events detection.&amp;lt;br&amp;gt;&lt;br /&gt;
Different features are available:&lt;br /&gt;
* the occulted and occulting bodies are both spherical;&lt;br /&gt;
* the occulted body is a direction;&lt;br /&gt;
* the occulting body has an ellipsoid shape.&lt;br /&gt;
&lt;br /&gt;
In addition to that, the &amp;lt;code&amp;gt;EclipseDetector&amp;lt;/code&amp;gt; can detect eclipse events based on a threshold lighting ratio &amp;lt;math&amp;gt;\epsilon_{0}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;0&amp;lt;=\epsilon_{0}&amp;lt;=1&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
When &amp;lt;math&amp;gt;\epsilon_{0}=0&amp;lt;/math&amp;gt;, an eclipse event is triggered only if whole occulted body is hidden by the occulting body (total eclipse); when &amp;lt;math&amp;gt;\epsilon_{0}=1&amp;lt;/math&amp;gt;, an event is immediately triggered when the occulted body is partially hidden (penumbra eclipse).&amp;lt;br&amp;gt;&lt;br /&gt;
As a general rule, the lighting ratio is equal to:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\epsilon = 1-\frac{A_{occulted}}{\pi r_{occulted}^2}&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
where &amp;lt;math&amp;gt;r_{occulted}&amp;lt;/math&amp;gt; is the apparent radius of the occulted body. &amp;lt;br&amp;gt;&lt;br /&gt;
The g function is: &amp;lt;math&amp;gt;g=\epsilon_{0}-\epsilon&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The g switching function computation needs the satellite position vector (&amp;lt;math&amp;gt;\vec P_{sat}&amp;lt;/math&amp;gt;), the occulted body (&amp;lt;math&amp;gt;\vec P_{ted}&amp;lt;/math&amp;gt;) and occulting body (&amp;lt;math&amp;gt;\vec P_{ing}&amp;lt;/math&amp;gt;) position vectors.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\vec {PS}=\vec {P_{ted}}-\vec {P_{sat}}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;sin(\widehat{rs})=\dfrac{r_{ted}}{|\vec {PS}|}&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\vec {PO}=\vec {P_{ing}}-\vec {P_{sat}}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;sin(\widehat{ro})=\dfrac{r_{ing}}{|\vec {PO}|}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\alpha&amp;lt;/math&amp;gt; is the angle between &amp;lt;math&amp;gt;\vec {PS}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec {PO}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Distinction is made between total eclipse and partial eclipse.&amp;lt;br&amp;gt;&lt;br /&gt;
The following diagrams show the evolution of the g function value for an eclipse scenario with two spherical bodies. &lt;br /&gt;
&lt;br /&gt;
===== Total eclipse =====&lt;br /&gt;
&lt;br /&gt;
The passage to umbra is detected. The g switching function is &amp;lt;math&amp;gt;g = \alpha- \widehat{ro} + \widehat{rs}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; satellite is not in eclipse:&lt;br /&gt;
[[File:eclipse1.png|576x274px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; beginning of umbra:&lt;br /&gt;
[[File:eclipse2.png|570x161px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; umbra:&lt;br /&gt;
[[File:eclipse3.png|574x180px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; end of umbra:&lt;br /&gt;
[[File:eclipse4.png|570x182px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; satellite is not in eclipse:&lt;br /&gt;
[[File:eclipse5.png|588x264px]]&lt;br /&gt;
&lt;br /&gt;
===== Partial eclipse =====&lt;br /&gt;
&lt;br /&gt;
The passage to penumbra is detected. The g switching function is &amp;lt;math&amp;gt;g = \alpha- \widehat {ro} - \widehat {rs}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; satellite is not in eclipse:&lt;br /&gt;
[[File:eclipse6.png|566x273px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; beginning of penumbra:&lt;br /&gt;
[[File:eclipse7.png|552x198px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; penumbra:&lt;br /&gt;
[[File:eclipse8.png|581x178px]]&lt;br /&gt;
* &amp;lt;math&amp;gt;g=0 :&amp;lt;/math&amp;gt; end of penumbra:&lt;br /&gt;
[[File:eclipse9.png|578x217px]]&lt;br /&gt;
&lt;br /&gt;
Another feature of the &amp;lt;code&amp;gt;EclipseDetector&amp;lt;/code&amp;gt; is the detection of partial and total eclipse by a spheroid.&lt;br /&gt;
&lt;br /&gt;
[[File:ellipsoideclipse.png|center]]&lt;br /&gt;
&lt;br /&gt;
The point on the horizon (H) is calculated as the point of the ellipsoid that is in the same plane as A, C and S (respectively center of occulted body, center of occulting body and satellite). The distance of H to the center C of the ellipsoid is then projected onto a plane orthogonal to the Satellite / Occulting (SA) body direction, and the resulting length is considered as the radius of an &amp;quot;apparent&amp;quot; sphere representing the occulting body. The partial and total eclipse are then computed as per above.&lt;br /&gt;
&lt;br /&gt;
===== Particular case =====&lt;br /&gt;
&lt;br /&gt;
A specific case is having a spacecraft lower than the occulting body radius (i.e. spacecraft altitude &amp;lt; occulting body radius).&amp;lt;br&amp;gt;&lt;br /&gt;
Two cases are possible:&lt;br /&gt;
* The satellite is behind the occulted body (angle occulted body- occulting body - satellite &amp;gt; Pi/2): satellite is considered to be in total eclipse.&lt;br /&gt;
* The satellite is in front of the occulted body (angle occulted body- occulting body - satellite &amp;lt;= Pi/2): apparent radius of occulting body cannot be computed. Hence it is considered to be equal to Pi/2 (slight approximation since it means satellite is considered to be lying exactly on the surface of the occulting body). Then usual computation of g function applies.&lt;br /&gt;
&lt;br /&gt;
==== BodyInEclipseDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector is in charge of the umbra/penumbra eclipse events detection for a non-point target body. 3 bodies are considered to compute the BodyInEclipse events:&lt;br /&gt;
&lt;br /&gt;
*Target body: body on which the eclipse events are to be detected.&lt;br /&gt;
&lt;br /&gt;
*Occulted body: this is the body that is no longer visible from the target body due to the presence of the occulting body in the line of sight (the occulted body is generally the sun).&lt;br /&gt;
&lt;br /&gt;
*Occulting body: body that causes the eclipse.&lt;br /&gt;
[[Fichier:BodyInEclipseDetector1.png|centré|683x683px]]&lt;br /&gt;
The following assumptions are made:&lt;br /&gt;
* The three bodies are considered spherical during calculations (the apparent radius of the bodies are used).&lt;br /&gt;
* For the cases where the target body is fully in eclipse, the target body must be much smaller than the possible irregularities of the occulting body to avoid false positives. (Further explanation of this point in the edge cases section).&lt;br /&gt;
* No atmospheric effect is taken into account.&lt;br /&gt;
*The propagation delay can be activated or not.&lt;br /&gt;
&lt;br /&gt;
The core of the algorithm consists of selecting a point on the surface of the target that is representative of the surface of the target as a whole, and then calculating the illumination rate at that point. &lt;br /&gt;
&lt;br /&gt;
The calculation of g is therefore done in three steps:&lt;br /&gt;
*Selection of the reference point: This depends on the type of eclipse targeted (partial or total; whether the body is completely eclipsed or not), the chosen model (complete or simplified), and the relative position of the bodies involved.&lt;br /&gt;
* Calculation of the illumination rate at the selected target point.&lt;br /&gt;
*Comparison of the obtained illumination rate with the target illumination rate (0 if we are looking for total eclipses, 1 if we are looking for partial eclipses).&lt;br /&gt;
2 modes are available for the computation of eclipse events:&lt;br /&gt;
&lt;br /&gt;
1.   Exact model: &lt;br /&gt;
&lt;br /&gt;
In this model, the occulted body is considered as non-punctual. 4 points are of interest to detect the eclipse events: &lt;br /&gt;
*H&amp;lt;sub&amp;gt;PPU&amp;lt;/sub&amp;gt; = point of interest for entry partially in penumbra&lt;br /&gt;
*H&amp;lt;sub&amp;gt;PU&amp;lt;/sub&amp;gt; = point of interest for entry partially in umbra&lt;br /&gt;
* H&amp;lt;sub&amp;gt;TPU&amp;lt;/sub&amp;gt; = point of interest for entry totally in penumbra&lt;br /&gt;
*H&amp;lt;sub&amp;gt;TU&amp;lt;/sub&amp;gt; = point of interest for entry totally in umbra&lt;br /&gt;
[[Fichier:BodyInEclipseDetector2.png|centré|776x776px]]&lt;br /&gt;
2.   Approximative model&lt;br /&gt;
&lt;br /&gt;
In this model, the occulted body is considered as punctual. In this case, only 2 interest points exists to detect eclipse events:  &lt;br /&gt;
*H&amp;lt;sub&amp;gt;P&amp;lt;/sub&amp;gt; = point of interest for entry partially in eclipse&lt;br /&gt;
*H&amp;lt;sub&amp;gt;T&amp;lt;/sub&amp;gt; = point of interest for entry totally in eclipse&lt;br /&gt;
[[Fichier:BodyInEclipseDetector3.png|centré|771x771px]]&lt;br /&gt;
For any of the models, the lighting ratio of the corresponding interest points is computed to detect the events.&lt;br /&gt;
&lt;br /&gt;
The lighting ratio is then compared against the target lighting ratio (0 if we want to detect total eclipses and 1 for partial eclipses), and the value of the g function (switching function) is returned for a given date. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Edge Cases:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Occulting body &amp;lt;&amp;lt; Target Body:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
If the occulting body is smaller than the target body, it might happen that none of the 4 points of interest is in eclipse, however the target body is partially in eclipse as shown in the figure below:&lt;br /&gt;
[[Fichier:BodyInEclipseDetector4.png|centré|806x806px]]&lt;br /&gt;
This case is possible only if the line SA intersects the target body. In this case, none of the interest points of the exact model or of the approximative model are used to compute the lighting ratio. In this case it is the intersection point H&amp;lt;sub&amp;gt;C&amp;lt;/sub&amp;gt; that is used to compute the lighting ratio (to know if it is inside umbra or only inside penumbra).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Shape of occulting body non spherical:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
In the hypotheses section it was said that the 3 bodies are considered spherical. However, it is really only the occulted and the target bodies that have to be spherical. The occulting body might have any other shape. It is during the computation that we model the occulting body as spherical by using the getApparentRadius method. &lt;br /&gt;
&lt;br /&gt;
In certain edge cases, a BodyInEclipse event might be raised by the propagator, even though this is not actually the case. This type of situation can occur when the occulting body is elongated in the direction of the plane of the eclipse. &lt;br /&gt;
[[Fichier:BodyInEclipseDetector5.png|centré]]&lt;br /&gt;
The calculation method considers a planar projection of the problem. When an object is detected as &amp;quot;completely in the shadow&amp;quot; of another, it is ensured that the furthest point of the eclipse cone in the plane containing the centers of the three objects is in eclipse. This guarantees that all points of the target object belonging to this plane are in eclipse. However, there is no guarantee for points outside of the plane. This is not an issue when the obscuring object is spherical, but it can become one when it is elongated. In the example below, the target is considered &amp;quot;entirely&amp;quot; eclipsed by the detector, even though some points are illuminated. &lt;br /&gt;
&lt;br /&gt;
This type of case is unlikely to occur in the Earth-Moon scenario, where the obscuring body is very close to a sphere, but it is not impossible in the case of asteroids, which have non-regular shapes. Other problems of this kind can arise when the body is not convex, but such cases become extremely rare.&lt;br /&gt;
&lt;br /&gt;
This is why for the cases where the target body is fully in eclipse, the target body must be much smaller than the possible irregularities of the occulting body to avoid false positives.&lt;br /&gt;
&lt;br /&gt;
====PlaneCrossingDetector====&lt;br /&gt;
The detector allows to detect if a spacecraft crosses a plane defined in a specific reference frame. The following entries are needed to define a &amp;lt;code&amp;gt;PlaneCrossingDetector&amp;lt;/code&amp;gt;:&lt;br /&gt;
*plane reference frame ;&lt;br /&gt;
*point which is contained in the plane ;&lt;br /&gt;
* normal vector to plane.&lt;br /&gt;
&lt;br /&gt;
The detection function &amp;lt;math&amp;gt;g()&amp;lt;/math&amp;gt; monitors the dot product between the normal vector to plane and the distance position vector of the spacecraft with respect to the origin of the point of the plan:&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt;the satellite is over the plane;&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt;the satellite is under the plane.&lt;br /&gt;
&lt;br /&gt;
==== NodeDetector ====&lt;br /&gt;
The &amp;lt;code&amp;gt;NodeDetector&amp;lt;/code&amp;gt; detects the orbital nodes; the user can choose what the detect (ascending nodes, descending nodes or both) through the &amp;lt;code&amp;gt;slopeSelection &amp;lt;/code&amp;gt; parameter. It is a particular application case of the &amp;lt;code&amp;gt;PlaneCrossingDetector&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
The g switching function returns the Z component of the satellite position in the geocentric frame:&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt;the satellite is over the equatorial plane (in its orbit from ascending node to descending node);&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt;the satellite is under the equatorial plane (in its orbit from descending node to ascending node).&lt;br /&gt;
&lt;br /&gt;
====DistanceDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;DistanceDetector &amp;lt;/code&amp;gt; detects the time when the distance between the spacecraft and a point of space reaches a given value.&lt;br /&gt;
&lt;br /&gt;
The point of space is given as a &amp;lt;code&amp;gt;PVcoordinatesProvider&amp;lt;/code&amp;gt; : it can be either a celestial body (as a &amp;lt;code&amp;gt;CelestialBody&amp;lt;/code&amp;gt;), a point at the surface of a body (as a &amp;lt;code&amp;gt;TopocentricFrame&amp;lt;/code&amp;gt;), or any another class that implements that interface.&lt;br /&gt;
&lt;br /&gt;
Here is the example for a point on the surface of a body :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// earth shape&lt;br /&gt;
final BodyShape earth = new OneAxisEllipsoid(earthRadius, ea, ITRFFrame);&lt;br /&gt;
&lt;br /&gt;
// considered point&lt;br /&gt;
final EllipsoidPoint point = new EllipsoidPoint(ellipsoid, LLHCoordinatesSystem.ELLIPSODETIC, latitude, longitude, altitude, &amp;quot;point &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// associated topocentric frame : this object is a PVCoordinatesProvider&lt;br /&gt;
final TopocentricFrame topoFramePoint = new TopocentricFrame(point, &amp;quot;Gstation&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// detector&lt;br /&gt;
final DistanceDetector detector = new DistanceDetector(topoFramePoint, distance);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Its g switching function computes the difference between the spacecraft position and the point position (in the same frame), and then subtracts the given distance from its norm. &lt;br /&gt;
&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt;the distance spacecraft/point is bigger than the distance threshold value;&lt;br /&gt;
*&amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt;the distance spacecraft/point is smaller than the distance threshold value;&lt;br /&gt;
&lt;br /&gt;
====ExtremaDistanceDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaDistanceDetector&amp;lt;/code&amp;gt; detects if the spacecraft is at a local extremum for the distance relative to a point of space, defined the same way as in the previous DistanceDetector. The choice of the extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;distanceType&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the square norm of the velocity for the vector representing this distance, thus the sign change is indeed a local extremum. &lt;br /&gt;
&lt;br /&gt;
====ExtremaLatitudeDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaLatitudeDetector&amp;lt;/code&amp;gt; detects if the spacecraft is at a local extremum for the geodetic latitude. The choice of the extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;latitudeType&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the z-component of the spacecraft velocity in the orbit definition frame.&lt;br /&gt;
&lt;br /&gt;
====LatitudeDetector====&lt;br /&gt;
The &amp;lt;code&amp;gt;LatitudeDetector&amp;lt;/code&amp;gt; detects the time when the spacecraft reaches a given geodetic latitude, the &amp;lt;code&amp;gt;BodyShape&amp;lt;/code&amp;gt; of the earth being known to compute it.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the difference between the current latitude and the one to detect.&lt;br /&gt;
&lt;br /&gt;
====ExtremaLongitudeDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaLongitudeDetector&amp;lt;/code&amp;gt; detects if the spacecraft is at a local extremum for the longitude. The choice of the extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;extremumType&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
The g switching function is the dot vector of the position with the result of the cross product of the velocity relative to the body and unitary vector Z :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g =\vec P \cdot (\vec Vrel \wedge \vec Vz)&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The main part of this function is the cross product which switches when the relative velocity is colinear to Z.&lt;br /&gt;
&lt;br /&gt;
====LongitudeDetector====&lt;br /&gt;
The &amp;lt;code&amp;gt;LongitudeDetector&amp;lt;/code&amp;gt; detects the time when the spacecraft reaches a given longitude.&lt;br /&gt;
&lt;br /&gt;
Working with longitude always gives a problem of continuity when longitude pass from PI rad to- PI rad. The best solution find to avoid this is to save some information from the last computation of the g function. &lt;br /&gt;
&lt;br /&gt;
In this way the g function is the following difference expressed between-PI rad and PI rad : currentLongitude - longitudeToDetect&lt;br /&gt;
&lt;br /&gt;
At each g function call, this difference is saved, and each time the difference between the current difference and the last difference is greater than PI rad, it means there is a discontinuity, the g fonction is opposed. This avoids discontinuity. Then all zero are detected.&lt;br /&gt;
&lt;br /&gt;
This solution, also avoids problem about detecting a longitude at PI rad further (that we meet with a sin(a- b) g function).&lt;br /&gt;
&lt;br /&gt;
==== Safety Margin Detector ====&lt;br /&gt;
&lt;br /&gt;
This detector computes the safety margin ∆ with respect to the escape velocity. Users have the choice between two methods for the safety margin computation:&lt;br /&gt;
* INSTANTANEOUS: The safety margin is computed using the spacecraft&#039;s current velocity v and the escape velocity v_esc evaluated at the satellite&#039;s current position (v_esc=√(2μ/r)): ∆ = v/v_esc-1&lt;br /&gt;
* PERICENTRE: The safety margin is computed at the orbit&#039;s pericenter (where the satellite speed is maximum) using the orbital eccentricity e: ∆ = √((1+e)/2)-1&lt;br /&gt;
&lt;br /&gt;
Note: For circular orbits (e=0 and v=√(μ/r)), both methods are equivalent and yield ∆ = 1/√2-1.&lt;br /&gt;
&lt;br /&gt;
The g switching function is the difference between the computed safety margin ∆ and a user-defined safety margin threshold t (safetyMarginIn): g = ∆-t&lt;br /&gt;
&lt;br /&gt;
====AOLDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;AOLDetector&amp;lt;/code&amp;gt; detects when the spacecraft reaches a predetermined argument of latitude (true, mean or eccentric supportes) with respect to a given equator ; the argument of latitude is the angle between the spacecraft position and the ascending node.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the sinus of the difference between the spacecraft current angular position &amp;lt;math&amp;gt;\beta&amp;lt;/math&amp;gt; and the threshold position value &amp;lt;math&amp;gt;\beta_{input}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g=sin(\beta- \beta_{input})&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
An AOL event is triggered only if the g-function slope is positive at its zero.&lt;br /&gt;
&lt;br /&gt;
====AnomalyDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;AnomalyDetector&amp;lt;/code&amp;gt; detects when the spacecraft reaches a predetermined anomaly; the anomaly is the angle between the spacecraft position and the perigee.&amp;lt;br&amp;gt;&lt;br /&gt;
Three types of anomaly can be detected: true, mean and eccentric anomaly.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the sinus of the difference between the spacecraft current anomaly and the threshold anomaly value:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g=sin(\alpha- \alpha_{input})&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
(This g function is identical to the AOLDetector g function).&amp;lt;br&amp;gt;&lt;br /&gt;
Like the &amp;lt;code&amp;gt;AOLDetector&amp;lt;/code&amp;gt;, an anomaly event is triggered only if the g-function slope is positive at its zero.&lt;br /&gt;
&lt;br /&gt;
Using precaution : This detector is unusable on a circular orbit where the perigee always moves very fast and in any way.&lt;br /&gt;
&lt;br /&gt;
====ThreeBodiesAngleDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ThreeBodiesAngleDetector&amp;lt;/code&amp;gt; detects when the angle between three bodies (they can be celestial bodies, spacecrafts, ground stations, ...) is equal to a predetermined value.&amp;lt;br&amp;gt;&lt;br /&gt;
If &amp;lt;math&amp;gt;\vec{P_{1}}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;\vec{P_{2}}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec{P_{3}}&amp;lt;/math&amp;gt; are the positions of the three bodies, and &amp;lt;math&amp;gt;\vec{P_{21}}&amp;lt;/math&amp;gt; is the difference &amp;lt;math&amp;gt;\vec{P_{2}}-\vec{P_{1}}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec{P_{23}}&amp;lt;/math&amp;gt; the difference &amp;lt;math&amp;gt;\vec{P_{2}}-\vec{P_{3}}&amp;lt;/math&amp;gt;, the computed angle will be: &amp;lt;math&amp;gt;\widehat{\vec{P_{21}} \vec{P_{23}}}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:threeBodies.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the difference between the current angle between the three bodies and the threshold angle. The threshold angle is not oriented and its value is between 0 and PI.&lt;br /&gt;
&lt;br /&gt;
====ExtremaThreeBodiesAngleDetector====&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaThreeBodiesAngleDetector&amp;lt;/code&amp;gt; detects when the angle between three bodies (defined the same way as in the &amp;lt;code&amp;gt;ThreeBodiesAngleDetector&amp;lt;/code&amp;gt;) reaches its minimal or maximal value.&amp;lt;br&amp;gt;&lt;br /&gt;
The choice of the detected extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;extremumType&amp;lt;/code&amp;gt; parameter.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the derivative of the angle value (in fact, part of the derivative : a factor with a &lt;br /&gt;
constant sign has been ignored).&amp;lt;br&amp;gt;&lt;br /&gt;
This derivative is obtained by expressing all the positions and velocities of the two extreme points (&amp;lt;math&amp;gt;P_{1}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;P_{3}&amp;lt;/math&amp;gt;) in a frame linked to the one at the angle origin (&amp;lt;math&amp;gt;P_{2}&amp;lt;/math&amp;gt;).&amp;lt;br&amp;gt;&lt;br /&gt;
If the two vectors from the new origin are &amp;lt;math&amp;gt;\vec{P_{21}}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\vec{P_{23}}&amp;lt;/math&amp;gt; the angle expression is : &amp;lt;math&amp;gt;\arccos(\vec{P_{21}}.\vec{P_{23}} / (|\vec{P_{21}}|.|\vec{P_{23}}|))&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Once derivated as &amp;lt;math&amp;gt;(gof)&#039; = (g&#039;of).f&#039;&amp;lt;/math&amp;gt; and the &amp;lt;math&amp;gt;arccos&amp;lt;/math&amp;gt; derivative being always negative, the switching function is minus the derivative of the inner expression &amp;lt;math&amp;gt;\vec{P_{21}}.\vec{P_{23}} / (|\vec{P_{21}}|.|\vec{P_{23}}|)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====BetaAngleDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;BetaAngleDetector&amp;lt;/code&amp;gt; detects when the beta angle reaches a predetermined value; the beta angle is the angle between the orbit plane and the vector to the Sun.&lt;br /&gt;
[[File:BetaAngle.png|center]]&lt;br /&gt;
&lt;br /&gt;
The beta angle belongs to [- π/2 , π/2 ]; its sign is positive when the Sun is in the half-plane containing the spacecraft&#039;s momentum.&lt;br /&gt;
&lt;br /&gt;
==== LocalTimeAngleDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;LocalTimeAngleDetector&amp;lt;/code&amp;gt; detects when the spacecraft local time is equal to a predetermined value; the spacecraft local time is the angle between the projections of the Earth-Sun vector and the Earth-spacecraft vector in the equatorial plane plus PI. In PATRIUS, local time is expressed as an angle in the range [-PI; PI[. Local time angle is PI (or 12.00h) when the geometric angle Sun-Earth-Spacecraft is 0 and 0 (or 0.00h) when this angle is PI.&amp;lt;br&amp;gt;&lt;br /&gt;
The local time is increasing for prograde orbits and decreasing for retrograde orbits. The events are detected in both cases.&lt;br /&gt;
&lt;br /&gt;
The g function is the following difference expressed between-PI rad and PI rad : &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;currentLocalTime- localTimeToDetect&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At each g function call, this difference is saved, and each time the difference between the current difference and the last difference is greater than PI rad, it means there is a discontinuity, the g fonction is opposed. This avoids discontinuity. Then all zero are detected.&lt;br /&gt;
&lt;br /&gt;
This solution, also avoids problem about detecting a local time at PI rad further (that we meet with a sin(a- b) g function).&lt;br /&gt;
&lt;br /&gt;
====BodyPointLocalTimeAngleDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;BodyPointLocalTimeAngleDetector&amp;lt;/code&amp;gt; follows the same logic as its parent class &amp;lt;code&amp;gt;LocalTimeAngleDetector&amp;lt;/code&amp;gt; but, instead of computing the events for a certain position of the spacecraft, the events are computed with respect to a point of the surface of the body, by using the zenithal direction (normal to the surface). &lt;br /&gt;
&lt;br /&gt;
To compute the local time of a certain point in a body, first the Frame is verified (it cannot be null). Then, the normal direction of the body point is computed. Afterwards, the sun position is obtained. The local time corresponds to the angle between the projections of the Earth-Sun and the normal direction over the equatorial plane plus PI.&lt;br /&gt;
&lt;br /&gt;
====SolarTimeAngleDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;SolarTimeAngleDetector&amp;lt;/code&amp;gt; detects when the spacecraft solar time is equal to a predetermined value; the spacecraft solar time is the angle between the the Earth-Sun projection in the orbital plane and the Earth-spacecraft vector plus PI. In PATRIUS, solar time is expressed as an angle in the range [-PI; PI[. Solar time angle is PI (or 12.00h) when the geometric angle Sun-Earth-Spacecraft is 0 and 0 (or 0.00h) when this angle is PI. &amp;lt;br&amp;gt;&lt;br /&gt;
The solar time is always increasing with time. It is mesured around the orbit momentum.&lt;br /&gt;
&lt;br /&gt;
The g switching function returns the sinus of the difference between the spacecraft current solar time &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; and the threshold solar time value &amp;lt;math&amp;gt;\theta_{t}&amp;lt;/math&amp;gt;:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g=sin(\theta- \theta_{t})&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Like the &amp;lt;code&amp;gt;AOLDetector&amp;lt;/code&amp;gt;, a solar time event is triggered only if the g-function slope is positive at its zero.&lt;br /&gt;
&lt;br /&gt;
====NadirSolarIncidenceDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;NadirSolarIncidenceDetector&amp;lt;/code&amp;gt; detects when the solar incidence, seen from the nadir point of the spacecraft, reaches a predetermined value.&amp;lt;br&amp;gt;&lt;br /&gt;
The solar incidence is the angle between the nadir- satellite vector and the nadir - sun vector.&lt;br /&gt;
&lt;br /&gt;
[[File:nadirsolarincidence.png|center]]&lt;br /&gt;
&lt;br /&gt;
====BodyPointSolarIncidenceDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;BodyPointSolarIncidenceDetector&amp;lt;/code&amp;gt; detects when the solar incidence angle reaches a predetermined value. The solar incidence is the angle between the interest point-satellite vector and the interest point-sun vector. The interest point being described by a BodyPoint.&lt;br /&gt;
&lt;br /&gt;
[[Fichier:BodyPointSolarIncidenceDetector.png|center]]&lt;br /&gt;
&lt;br /&gt;
====EarthZoneDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;EarthZoneDetector&amp;lt;/code&amp;gt; detects when the spacecraft enters and leaves an earth zone. Several separated zones can be defined for one detector instance. In that case, the EarthZoneDetector detects the entery of the satellite NADIR point in any of the zones.&lt;br /&gt;
&lt;br /&gt;
The zones can be described two ways : &lt;br /&gt;
*As an array of {latitude, longitudes} that define the geodetic points with a zero altitude on a BodyShape. With this definition, the test made will be the entering of the spacecraft&#039;s NADIR point in the zone.&lt;br /&gt;
*As an array of vectors expressed in a given frame. With this definition, the entering of the spacecraft itself in the conic field from the center of the given frame to those points will be detected. Note that the given frame must be a terrestrial frame for the detection of earth zones entering, but the use of other frames is possible (other bodies, inertial frames…).&lt;br /&gt;
&lt;br /&gt;
In both cases, the points must respect the following conditions : &lt;br /&gt;
*At least 3 points are needed to define a zone&lt;br /&gt;
*two consecutive points must not be too close (1.e-10 on the difference of thier normalized values)&lt;br /&gt;
*the arc between two consecutive points must not cross the one between two consecutive others of the same zone.&lt;br /&gt;
&lt;br /&gt;
The points must also be given in the right order : from the point i to the point i + 1, if the associated vector from the center of the earth are &amp;lt;math&amp;gt;v_{i}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;v_{i + 1}&amp;lt;/math&amp;gt;, the inside of the zone is on the left, e.g. the side of the positive cross vector &amp;lt;math&amp;gt;v_{i} . v_{i + 1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Constructors with default maxCheck and threshold values are available, but beware of their values, and use the other constructors if needed  : if the zone is complex and the MaxCheck too large, the event detection could fail, because it would not manage to converge. To compute the event with enough precision to converge, set a small enough MaxCheck. To compute an approximative event even if the zone is precise and complex, set a large enough Threshold.&lt;br /&gt;
&lt;br /&gt;
===Particular detections===&lt;br /&gt;
All those detectors can be used for the following particular cases :&lt;br /&gt;
&lt;br /&gt;
*sub-solar point reaching  : use the SolarTimeAngleDetector with a &amp;quot;12h&amp;quot; time to detect.&lt;br /&gt;
*generic masking by a spherical body : use the GenericEclipseDetector, or the ThreeBodiesAngleDetector.&lt;br /&gt;
*terminator reaching (the nadir point reaches the night / day limit) : use the NadirSolarIncidenceDetector with a zero incidence.&lt;br /&gt;
*Sun interference in ground antennas : use the ThreeBodiesAngleDetector.&lt;br /&gt;
*RF interference between the main spacecraft and another one : use the ThreeBodiesAngleDetector&lt;br /&gt;
&lt;br /&gt;
==Getting Started==&lt;br /&gt;
{{specialInclusion prefix=$theme_sub section=&amp;quot;GettingStarted&amp;quot;/}}&lt;br /&gt;
&lt;br /&gt;
== Contents==&lt;br /&gt;
===Interfaces===&lt;br /&gt;
All the detectors implement the interface :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Javadoc &lt;br /&gt;
|-&lt;br /&gt;
|EventDetector&lt;br /&gt;
|This interface represents an event finder.&lt;br /&gt;
|[&amp;lt;nowiki/&amp;gt;{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/EventDetector.html EventDetector ]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Classes===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|AlignmentDetector&lt;br /&gt;
|This class handles (satellite/central body/projection in the orbital plane of secondary body) alignment events.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AlignmentDetector.html AlignmentDetector]&lt;br /&gt;
|-&lt;br /&gt;
|AltitudeDetector&lt;br /&gt;
|This class handles satellite altitude crossing events.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AltitudeDetector.html AltitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ApsideDetector&lt;br /&gt;
|This class handles satellite apogee and perigee crossing events.&lt;br /&gt;
| [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ApsideDetector.html ApsideDetector]&lt;br /&gt;
|-&lt;br /&gt;
|BodyInEclipseDetector&lt;br /&gt;
|This class handles the umbra/penumbra eclipse events detection for a non-point target body&lt;br /&gt;
|[{{JavaDoc4.18}}&amp;lt;nowiki&amp;gt;/fr/cnes/sirius/patrius/events/detectors/BodyInEclipseDetector.html BodyInEclipseDetector]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|BodyPointLocalTimeAngleDetector &lt;br /&gt;
|This class handles events representing the fact that a point on the surface of a spacecraft reaches a certain local time angle&lt;br /&gt;
|[{{JavaDoc4.18}}&amp;lt;nowiki&amp;gt;/fr/cnes/sirius/patrius/events/detectors/BodyPointLocalTimeAngleDetector.html BodyPointLocalTimeAngleDetector]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|DateDetector &lt;br /&gt;
|This class handles the occurrence of predefined dates.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/DateDetector.html DateDetector]&lt;br /&gt;
|-&lt;br /&gt;
|EclipseDetector&lt;br /&gt;
|This class handles total or partial eclipse events.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/EclipseDetector.html EclipseDetector]&lt;br /&gt;
|-&lt;br /&gt;
|NodeDetector&lt;br /&gt;
|This class handles satellite equator crossing events.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/NodeDetector.html NodeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|DistanceDetector&lt;br /&gt;
|This class handles events relating to the distance between the satellite and a given body.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/DistanceDetector.html DistanceDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ExtremaDistanceDetector&lt;br /&gt;
|This class handles events representing the reaching of extrema for the distance to a given body.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ExtremaDistanceDetector.html ExtremaDistanceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| ExtremaLatitudeDetector&lt;br /&gt;
|This class handles events representing the reaching of extrema for the geodetic latitude.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ExtremaLatitudeDetector.html ExtremaLatitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ExtremaLongitudeDetector&lt;br /&gt;
|This class handles events representing the reaching of extrema for the longitude.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ExtremaLongitudeDetector.html ExtremaLongitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|LatitudeDetector&lt;br /&gt;
|This class handles events representing the reaching of a given geodetic latitude, the earth shape being known.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/LatitudeDetector.html LatitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|LongitudeDetector&lt;br /&gt;
|This class handles events representing the reaching of a given longitude&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/LongitudeDetector.html LongitudeDetector]&lt;br /&gt;
|-&lt;br /&gt;
|AnomalyDetector&lt;br /&gt;
|This class handles events representing the reaching of an anomaly angle.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AnomalyDetector.html AnomalyDetector]&lt;br /&gt;
|-&lt;br /&gt;
|SafetyMarginDetector&lt;br /&gt;
| This class handles escape velocity crossing detection.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/SafetyMarginDetector.html SafetyMarginDetector]|-&lt;br /&gt;
|AOLDetector&lt;br /&gt;
| This class handles events representing the reaching of an argument of latitude value.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/AOLDetector.html AOLDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ThreeBodiesAngleDetector&lt;br /&gt;
|This class handles events representing the reaching of a predetermined angle between three bodies.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ThreeBodiesAngleDetector.html ThreeBodiesAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|ExtremaThreeBodiesAngleDetector&lt;br /&gt;
|This class handles events representing the reaching of of extrema for the angle between three bodies.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/ExtremaThreeBodiesAngleDetector.html ExtremaThreeBodiesAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|BetaAngleDetector&lt;br /&gt;
|This class handles the event : reaching a given beta angle value for a spacecraft.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/BetaAngleDetector.html BetaAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|LocalTimeAngleDetector&lt;br /&gt;
|This class handles events representing the reaching of a predetermined spacecraft local time angle.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/LocalTimeAngleDetector.html LocalTimeAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|SolarTimeAngleDetector&lt;br /&gt;
|This class handles events representing the reaching of a predetermined spacecraft solar time angle.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/SolarTimeAngleDetector.html SolarTimeAngleDetector]&lt;br /&gt;
|-&lt;br /&gt;
|NadirSolarIncidenceDetector&lt;br /&gt;
|This class handles events representing the reaching of a predetermined spacecraft nadir point solar incidence.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/detectors/NadirSolarIncidenceDetector.html NadirSolarIncidenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
|EarthZoneDetector&lt;br /&gt;
|This class handles events representing the entering and leaving of earth zones.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/events/EarthZoneDetector.html EarthZoneDetector]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
[[Category:User Manual 4.18 Mission]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Main_differences_between_V4.18_and_V4.17&amp;diff=4166</id>
		<title>Main differences between V4.18 and V4.17</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Main_differences_between_V4.18_and_V4.17&amp;diff=4166"/>
		<updated>2026-06-10T10:03:56Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; V4.18 is a major release adding some new features and correcting some bugs.&lt;br /&gt;
&lt;br /&gt;
== New functionalities ==&lt;br /&gt;
* Added a new atmospheric model NRLMSIS 2.0, in addition from the existing NRLMSIS 1.0 model. The solar flux and geomagnetic activity inputs are the same for both versions of the MSIS models. Note that the FORTRAN reference model excludes the NO (Nitric Oxide) element. The same applies to the implemented model in PATRIUS, as it is based on the reference model. Other elements (He, O, N2, etc.), as well as pressure and temperature, are however taken into account.&lt;br /&gt;
&lt;br /&gt;
* Added to the ThirdBodyAttraction constructors the ability to provide a specific gravity model for the indirect terms. If none is provided, the gravity model already supplied for the third-body attraction calculation is used to compute the indirect terms (backward compatibility). To disable the computation of indirect terms, a gravity model that does not include harmonics must be provided.&lt;br /&gt;
* Added a service to the ApparentRadiusProvider interface to calculate the maximum apparent radius of a body as seen by a satellite. This radius, expressed in meters, corresponds to the maximum distance from the body&#039;s center to any point on its surface belonging to the limb ellipse (contour ellipse) viewed by the satellite.&lt;br /&gt;
* Added new constructors to the ModelFunction class to enable the optimization of various function types: ℝⁿ → ℝ : MultivariateFunction, ℝ → ℝ : UnivariateFunction and ℝ → ℝⁿ : UnivariateVectorFunction.&lt;br /&gt;
* Added support of the method StrictLegsSequence#addAll&lt;br /&gt;
* Added systematic acceleration calculation in BSP ephemerides (previously not calculated at all) via Chebyshev polynomial expansion. No regression expected on positions and velocities.&lt;br /&gt;
* Added a class SafetyMarginDetector to detect escape limits crossings. User can choose between two methods to compute escape limit: either at the satellite position or at the orbit’s pericenter.&lt;br /&gt;
* Allows the user to configure the desired TDB time scale prior to instantiating UserIAUPole, BSPEphemerisLoader, and PosVelChebyshev objects. Dates are initialized within their respective constructors based on this TDB scale, rather than being handled in a static way.&lt;br /&gt;
* New AstronomicalNightDetector detector allowing to find for astronomical dawn and dusk events (independent of the actual spacecraft state).&lt;br /&gt;
* Improved matrix toString display: Systematic display of row x column dimensions and large/small numbers are shown in scientific notation without numerical approximation for computing formats (JAVA, OCTAVE, SCILAB and NUMPY).&lt;br /&gt;
* Added support for the Alpha-5 TLE numbering format, extending the range of supported satellite catalog numbers from [0; 99,999] to [0; 339,999].&lt;br /&gt;
&lt;br /&gt;
== Bugs fixes ==&lt;br /&gt;
* In BSPEphemerisLoader, fix the TDB offset extraction by applying a “/ 1000” conversion, fix an error message that could lead to an infinite loop, update the getTDBModel() method so it can be called directly without having to call before the loadCelestialBodyEphemeris method.&lt;br /&gt;
* Fix the method FacetBodyShape#getIntersectionPoint which was using a line defined in the wrong coordinate system to compute the closest triangles.&lt;br /&gt;
* Fix for reading .bsp files when the binary file format is not declared at the correct index (more robust DafHandleManager method).&lt;br /&gt;
* Correction in the AbstractEllipsoidBodyShape#getApparentRadiusDirection method: using the observer&#039;s PVCoordinatesProvider instead of the body&#039;s (this) as the origin for the first direction vector. This incorrect behavior had an impact when the input direction depended on the observer&#039;s trajectory (for example, with a VelocityDirection linked to the observing satellite).&lt;br /&gt;
* Added a cache system to store and manage the “other dates” in AbstractSignalPropagationDetector instead of storing them indefinitely in a Map, which could cause large memory consumption during long propagations.&lt;br /&gt;
* Added validation checks during orbital parameter construction to prevent the creation of physically inconsistent ApsisOrbit, EquatorialOrbit, or KeplerianOrbit objects.&lt;br /&gt;
** KeplerianParameters / EquatorialParameters: the condition “e &amp;gt;= 0” must be satisfied&lt;br /&gt;
** ApsisAltitudeParameters / ApsisRadiusParameters: the condition “periapsis &amp;gt; 0” must be satisfied&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Main_differences_between_V4.18_and_V4.17&amp;diff=4165</id>
		<title>Main differences between V4.18 and V4.17</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Main_differences_between_V4.18_and_V4.17&amp;diff=4165"/>
		<updated>2026-06-10T10:03:00Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; V4.18 is a major release adding some new features and correcting some bugs.&lt;br /&gt;
&lt;br /&gt;
== New functionalities ==&lt;br /&gt;
* Added a new atmospheric model NRLMSIS 2.0, in addition from the existing NRLMSIS 1.0 model. The solar flux and geomagnetic activity inputs are the same for both versions of the MSIS models. &lt;br /&gt;
Note that the FORTRAN reference model excludes the NO (Nitric Oxide) element. The same applies to the implemented model in PATRIUS, as it is based on the reference model. Other elements (He, O, N2, etc.), as well as pressure and temperature, are however taken into account.&lt;br /&gt;
* Added to the ThirdBodyAttraction constructors the ability to provide a specific gravity model for the indirect terms. If none is provided, the gravity model already supplied for the third-body attraction calculation is used to compute the indirect terms (backward compatibility). To disable the computation of indirect terms, a gravity model that does not include harmonics must be provided.&lt;br /&gt;
* Added a service to the ApparentRadiusProvider interface to calculate the maximum apparent radius of a body as seen by a satellite. This radius, expressed in meters, corresponds to the maximum distance from the body&#039;s center to any point on its surface belonging to the limb ellipse (contour ellipse) viewed by the satellite.&lt;br /&gt;
* Added new constructors to the ModelFunction class to enable the optimization of various function types: ℝⁿ → ℝ : MultivariateFunction, ℝ → ℝ : UnivariateFunction and ℝ → ℝⁿ : UnivariateVectorFunction.&lt;br /&gt;
* Added support of the method StrictLegsSequence#addAll&lt;br /&gt;
* Added systematic acceleration calculation in BSP ephemerides (previously not calculated at all) via Chebyshev polynomial expansion. No regression expected on positions and velocities.&lt;br /&gt;
* Added a class SafetyMarginDetector to detect escape limits crossings. User can choose between two methods to compute escape limit: either at the satellite position or at the orbit’s pericenter.&lt;br /&gt;
* Allows the user to configure the desired TDB time scale prior to instantiating UserIAUPole, BSPEphemerisLoader, and PosVelChebyshev objects. Dates are initialized within their respective constructors based on this TDB scale, rather than being handled in a static way.&lt;br /&gt;
* New AstronomicalNightDetector detector allowing to find for astronomical dawn and dusk events (independent of the actual spacecraft state).&lt;br /&gt;
* Improved matrix toString display: Systematic display of row x column dimensions and large/small numbers are shown in scientific notation without numerical approximation for computing formats (JAVA, OCTAVE, SCILAB and NUMPY).&lt;br /&gt;
* Added support for the Alpha-5 TLE numbering format, extending the range of supported satellite catalog numbers from [0; 99,999] to [0; 339,999].&lt;br /&gt;
&lt;br /&gt;
== Bugs fixes ==&lt;br /&gt;
* In BSPEphemerisLoader, fix the TDB offset extraction by applying a “/ 1000” conversion, fix an error message that could lead to an infinite loop, update the getTDBModel() method so it can be called directly without having to call before the loadCelestialBodyEphemeris method.&lt;br /&gt;
* Fix the method FacetBodyShape#getIntersectionPoint which was using a line defined in the wrong coordinate system to compute the closest triangles.&lt;br /&gt;
* Fix for reading .bsp files when the binary file format is not declared at the correct index (more robust DafHandleManager method).&lt;br /&gt;
* Correction in the AbstractEllipsoidBodyShape#getApparentRadiusDirection method: using the observer&#039;s PVCoordinatesProvider instead of the body&#039;s (this) as the origin for the first direction vector. This incorrect behavior had an impact when the input direction depended on the observer&#039;s trajectory (for example, with a VelocityDirection linked to the observing satellite).&lt;br /&gt;
* Added a cache system to store and manage the “other dates” in AbstractSignalPropagationDetector instead of storing them indefinitely in a Map, which could cause large memory consumption during long propagations.&lt;br /&gt;
* Added validation checks during orbital parameter construction to prevent the creation of physically inconsistent ApsisOrbit, EquatorialOrbit, or KeplerianOrbit objects.&lt;br /&gt;
** KeplerianParameters / EquatorialParameters: the condition “e &amp;gt;= 0” must be satisfied&lt;br /&gt;
** ApsisAltitudeParameters / ApsisRadiusParameters: the condition “periapsis &amp;gt; 0” must be satisfied&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Main_differences_between_V4.18_and_V4.17&amp;diff=4164</id>
		<title>Main differences between V4.18 and V4.17</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Main_differences_between_V4.18_and_V4.17&amp;diff=4164"/>
		<updated>2026-06-10T09:03:59Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « &amp;lt;font color=#556B2F&amp;gt;&amp;#039;&amp;#039;&amp;#039;PATRIUS&amp;#039;&amp;#039;&amp;#039;&amp;lt;/font&amp;gt; V4.18 is a major release adding some new features and correcting some bugs.  == New functionalities == * When reading SP3 files, if the accuracy was not present, the parsing failed. This behavior has been modified to allow the parsing of files without accuracy. In that case, the accuracy is set to “0”. This is an impossible value of accuracy since in the SP3 file it is expressed as 2^n, so it is easy for the user to id... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; V4.18 is a major release adding some new features and correcting some bugs.&lt;br /&gt;
&lt;br /&gt;
== New functionalities ==&lt;br /&gt;
* When reading SP3 files, if the accuracy was not present, the parsing failed. This behavior has been modified to allow the parsing of files without accuracy. In that case, the accuracy is set to “0”. This is an impossible value of accuracy since in the SP3 file it is expressed as 2^n, so it is easy for the user to identify the values that have not been read.&lt;br /&gt;
* To construct a SurfaceDistanceDetector, the CelestialBody attribute has been replaced by a BodyShape. Moreover, the getBody() method from DistanceDetector has been renamed getTarget().&lt;br /&gt;
* The LaguerreSolver has been modifier to accept as input the maximum number of iterations allowed as well as multiple initial guesses (and their respective maximum iterations)&lt;br /&gt;
* A new solver PolynomialRootsFinder that computes the roots for a polynomial using the eigenvalues of the companion matrix A of the input polynomial has been added to Patrius&lt;br /&gt;
* It is now possible to define an extrapolation function builder in TimeStampedInterpolableEphemeris to complete the interpolation with an extrapolation feature on the left and right side of the samples. A new TimeStampedExtrapolationFunctionBuilder interface is created with no standard implementation.&lt;br /&gt;
* New feature in ApparentRadiusProvider allowing to compute the apparent radius of the occulting body from the spacecraft (observer) position given a specific direction to describe the computation plane. In comparison, the existing method predefine this plane with the direction of the occulted object. The rest of the method / behavior stays identical.&lt;br /&gt;
* BodyShape implements ApparentRadiusProvider and VariableRadiusProvider is deleted.&lt;br /&gt;
* New feature RealMatrix#getDeterminant() to compute the determinant value directly from the matrix instead of having to use the appropriate decomposition solver on the matrix. Also, new feature in ArithmeticUtilsTest to compute all the permutations from a double vector (equivalent to “perms” function in MatLab).&lt;br /&gt;
* New class AnomalyUtils to centralize every conversion methods between mean, eccentric and true anomalies.&lt;br /&gt;
* It is now possible to accept the non-optimal range interpolation in AbstractBoundedPVProvider (i.e. : EphemerisPvLagrange and EphemerisPvHermite)&lt;br /&gt;
* New constructors to build a LofOffset directly from a Rotation object&lt;br /&gt;
* New constructor in SensorVisibilityDetector to describe the SatToSatLinkType/LinkType (before it was forced to be in SECONDARY_TO_MAIN mode)&lt;br /&gt;
* Users can now read special TDB segments contained in BSP files in order to build a TDB model with TT-TDB offsets.&lt;br /&gt;
* New body point solar incidence detector based on the angle between the interest point-satellite vector and the interest point-sun vector.&lt;br /&gt;
* Possibility to provide an AbstractHarmonicGravityModel to a ThirdBodyAttraction in order to take into account the gravitational effects of the central body on this third body. The implemented modifications model the attraction of the third body γ as follows: γ = γ(third body → spacecraft) - γ(third body → central body).&lt;br /&gt;
* CELESTLAB inspired mission analysis functionalities added: InterplanetaryUtils (SOI computation, DV needed to join / leave an hyperbolic orbit from / to an elliptical one), ProgDetectorUtils (EventDetector wrapper used to compute intervals), EventUtils (Computation of shadow zones, visibility windows and geometry between a satellite and its target), KeplerianParamUtils (computation and conversion of several kerplerian orbit characteristics) and KeplerianParamComputer (Computation of all keplerian characteristics pertaining to an orbit defined with a semi-major axis, eccentricity and true anomaly)&lt;br /&gt;
&lt;br /&gt;
== Bugs fixes ==&lt;br /&gt;
* The class StrictAttitudeLegsSequence can now be serialized (also, the interfaces MultiEventDetector, TimeSequence &amp;amp; TimeStamped extend Serializable).&lt;br /&gt;
* SP3 format expresses the accuracy in mm but Patrius interprets it as m. The conversion was missing.&lt;br /&gt;
* The interface MultiOrbitalCovarianceProvider (since 4.16) define a default implementation for its getOrbitalCovarianceProvider method.&lt;br /&gt;
* Fix the local time’s signal propagation computation in BodyPointLocalTimeAngleDetector.&lt;br /&gt;
* Fix the ConvergenceException exist only when the threshold value is reached in CartesianOrbit#meanToEccentric, CartesianOrbit#meanToHyperbolicEccentric, FacetBodyShape#getApparentRadius, CircularParameters#hyperbolicMeanToEccentric and KeplerianParameters#meanToHyperbolicEccentric&lt;br /&gt;
* Generalize the behavior to throw a ConvergenceException when the convergence algorithm failed in AlternateEquinoctialParameters#getLE, CircularParameters#ellipticMeanToEccentric and EquinoctialParameters#meanToEccentric&lt;br /&gt;
* Fix the use of the deprecated PatriusMessages.DIMENSIONS_MISMATCH error message using an explicit message instead.&lt;br /&gt;
* In AbstractEllipsoidBodyShape#getApparentRadius the ellipsoid’s B radius was defined uncorrectly which may result in incorrect radius computation.&lt;br /&gt;
* In the LineMaskingDetector detector, the case when mainElement isn’t null is now well managed.&lt;br /&gt;
* In AbstractBodyAttraction, the acceleration derivatives with respect to the parameter K is now computed in the input frame instead of being computed in the body frame.&lt;br /&gt;
* In SolarTimeAngleDetector and in AlignmentDetector the sun (respectively the body) is now expressed in the working frame, corresponding to the first pseudo-inertial frame ancestor, when the spacecraft state’s frame isn’t pseudo-inertial.&lt;br /&gt;
* Fix the body masking distance and the spacecraft masking distance computation in in SensorVisibilityDetector#g (uses LinkType.DOWNLINK instead of LinkType.UPLINK)&lt;br /&gt;
* Fix the UserIAUPole#getAngularCoordinates#ICRF_TO_INERTIAL computation by using Euler angles&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.18&amp;diff=4163</id>
		<title>Catégorie:User Manual 4.18</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.18&amp;diff=4163"/>
		<updated>2026-06-10T09:03:29Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec «  == Introduction == This document is the main user manual of the PATRIUS library, which provides Java classes in a wide range of themes related with space flight dynamics.  The library has several purposes :  * to be a basis for the next generation FDS development * to be used in mission analysis and internal studies  Its classes contain the main basis algorithms and objects representation that shall be used in further developments.  For each theme, a specific ma... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This document is the main user manual of the PATRIUS library, which provides Java classes in a wide range of themes related with space flight dynamics.&lt;br /&gt;
&lt;br /&gt;
The library has several purposes :&lt;br /&gt;
&lt;br /&gt;
* to be a basis for the next generation FDS development&lt;br /&gt;
* to be used in mission analysis and internal studies&lt;br /&gt;
&lt;br /&gt;
Its classes contain the main basis algorithms and objects representation that shall be used in further developments.&lt;br /&gt;
&lt;br /&gt;
For each theme, a specific manual is available.&lt;br /&gt;
&lt;br /&gt;
== Applicable and Reference Documents ==&lt;br /&gt;
=== Applicable Documents ===&lt;br /&gt;
&#039;&#039;&#039;[A1]&#039;&#039;&#039;      &#039;&#039;CDCF- Fonctions de Base du Patrimoine de Dynamique du Vol&#039;&#039;, V1.2, SIRIUS-CF-DV-0049-CN, 2011.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;[A2]&#039;&#039;&#039;      &#039;&#039;Dossier de réutilisation Orekit et Commons Math&#039;&#039;, V1.0, SIRIUS-DLR-DV-0080-CN, 2010.&lt;br /&gt;
&lt;br /&gt;
== Glossary ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- &lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| SDD&lt;br /&gt;
| Software Design Document&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| SRS&lt;br /&gt;
| Software Requirements Specification&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| SUM&lt;br /&gt;
| Software User Manual&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| SValP&lt;br /&gt;
| Software Validation Plan&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| SVerP&lt;br /&gt;
| Software Verification Plan&lt;br /&gt;
|-&lt;br /&gt;
!scope=&amp;quot;row&amp;quot;| SVS&lt;br /&gt;
| Software Validation Specification&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Conventions ==&lt;br /&gt;
All the user manuals contain some java code sample as use examples.&lt;br /&gt;
&lt;br /&gt;
These samples are recognizable by the following colors convention :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Vector3D originCone = new Vector3D(1.0, 1.0, 1.0);&lt;br /&gt;
Vector3D direction = new Vector3D(2.0, 0.0, 0.0);&lt;br /&gt;
double angle = FastMath.PI / 4.0;&lt;br /&gt;
double height = 5.0;&lt;br /&gt;
RightCircularCone cone = new RightCircularCone(originCone, axis, angle, height);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PATRIUS uses the &#039;&#039;&#039;International System of Units (SI units)&#039;&#039;&#039; (m, kg, s, N, etc.). It is used for all PATRIUS input/output as well as internally for any computation.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
This document is an aid for developers coding software using the PATRIUS library. The library provides Java classes to represent basis objects and contains low level algorithms to be used in the new FDS and mission analysis softwares.&lt;br /&gt;
The user guide describes and explains the use of every class and functionality available.&lt;br /&gt;
&lt;br /&gt;
Each theme of the library is the object of a specific document. These themes are :&lt;br /&gt;
&lt;br /&gt;
* Math basis&lt;br /&gt;
* Flight dynamics basis&lt;br /&gt;
* Attitude&lt;br /&gt;
* Spacecraft&lt;br /&gt;
* Orbits&lt;br /&gt;
* Mission&lt;br /&gt;
* Tools&lt;br /&gt;
* Support&lt;br /&gt;
&lt;br /&gt;
PATRIUS is under Apache Licence 2.0.&lt;br /&gt;
&lt;br /&gt;
== Quick Start==&lt;br /&gt;
Here is a description of each theme of the PATRIUS library and an overview of its contents. See each associated document for the details.&lt;br /&gt;
&lt;br /&gt;
=== Mathematics ===&lt;br /&gt;
This theme is not directly linked to flight dynamics. It include. It provides the mathematical tools for the rest of the library. &lt;br /&gt;
&lt;br /&gt;
Its contains classes for :&lt;br /&gt;
&lt;br /&gt;
* function analysis (interpolations, polynomials, ...)&lt;br /&gt;
* numerical intergrators&lt;br /&gt;
* geometry (planes, lines, shapes, rotations, 3d vectors and matrixes...)&lt;br /&gt;
* low level functions and constants (sine, cosine, PI, ...)&lt;br /&gt;
* linear algebra (real matrix and vectors, decompositions and other matrix computations, ...&lt;br /&gt;
&lt;br /&gt;
The Mathematics User Manual can be found [[:Category:User_Manual_4.18_Mathematics|here]].&lt;br /&gt;
&lt;br /&gt;
=== Flight Dynamics ===&lt;br /&gt;
This theme contains the basis of orbital mechanics :&lt;br /&gt;
&lt;br /&gt;
* position-velocity and orbital parameters conversions&lt;br /&gt;
* frames and frames transforms&lt;br /&gt;
* dates and time scales&lt;br /&gt;
* time intervals&lt;br /&gt;
&lt;br /&gt;
The Flight Dynamics User Manual can be found [[:Category:User_Manual_4.18_Flight_Dynamics|here]].&lt;br /&gt;
&lt;br /&gt;
=== Spacecraft ===&lt;br /&gt;
This theme contains everything useful to describe a spacecraft and its use :&lt;br /&gt;
&lt;br /&gt;
* general architecture (describing the spacecraft by one or several parts)&lt;br /&gt;
* geometry&lt;br /&gt;
* mass caracteristics&lt;br /&gt;
* equipments (GS, antenna, instruments and associated computations...)&lt;br /&gt;
* caracteristics used in forces computations (radiative, drag...)&lt;br /&gt;
* torques computations&lt;br /&gt;
&lt;br /&gt;
The Spacecraft User Manual can be found [[:Category:User_Manual_4.18_Spacecraft|here]].&lt;br /&gt;
&lt;br /&gt;
=== Attitude ===&lt;br /&gt;
This theme contains the tools to predict the spacecraft attitude:&lt;br /&gt;
&lt;br /&gt;
* attitude laws&lt;br /&gt;
* cinematics and guidance&lt;br /&gt;
&lt;br /&gt;
The Attitude User Manual can be found [[:Category:User_Manual_4.18_Attitude|here]].&lt;br /&gt;
&lt;br /&gt;
=== Orbits ===&lt;br /&gt;
This theme contains everything useful to propagate an orbit in time and perform orbits restitutions :&lt;br /&gt;
&lt;br /&gt;
* numerical and analytical propagators&lt;br /&gt;
* physical models (for forces)&lt;br /&gt;
* Measures and filtering tools&lt;br /&gt;
&lt;br /&gt;
The Orbits User Manual can be found [[:Category:User_Manual_4.18_Orbit_Propagation|here]].&lt;br /&gt;
&lt;br /&gt;
=== Mission ===&lt;br /&gt;
This theme regroups the events computation, projections and use tools.&lt;br /&gt;
&lt;br /&gt;
The Mission User Manual can be found [[:Category:User_Manual_4.18_Mission|here]].&lt;br /&gt;
&lt;br /&gt;
=== Tools ===&lt;br /&gt;
This theme comprises some external tools such as the ephemeris comparator.&lt;br /&gt;
&lt;br /&gt;
The Tools User Manual can be found [[User_Manual_4.18_Tools|here]].&lt;br /&gt;
&lt;br /&gt;
=== Support ===&lt;br /&gt;
This theme is cross-functional. It contains for example the explaination of the data manager use and action.&lt;br /&gt;
&lt;br /&gt;
The Support User Manual can be found [[User_Manual_4.18_Support|here]].&lt;br /&gt;
&lt;br /&gt;
== Patrius Configuration ==&lt;br /&gt;
As of PATRIUS version 4.14, some propagation models and optimization algorithms are backward compatible to the PATRIUS version 4.12. &#039;&#039;&#039;Without any action done by the user, the backward compatibility is activated by default&#039;&#039;&#039;. More details about this important option are reported [[:Category:Patrius_Backward_Compatibility_4.18|here]].&lt;br /&gt;
&lt;br /&gt;
== Thread-Safety ==&lt;br /&gt;
For all content belonging to the PATRIUS library, the thread safety of every class will be evaluated,&lt;br /&gt;
and the results listed here.&lt;br /&gt;
&lt;br /&gt;
The known levels of thread safety for a class are:&lt;br /&gt;
&lt;br /&gt;
* immutable: the contents of an instance never change after creation, therefore the class is thread-safe.&lt;br /&gt;
* unconditionally thread-safe / thread-safe: the whole class is thread-safe by design.&lt;br /&gt;
* conditionally thread-safe: the class is thread-safe if certain conditions (specific to the class) are met.&lt;br /&gt;
* not thread-safe: the class is not thread-safe. If the class is used in a threaded environment, all accesses to the class must be synchronized.&lt;br /&gt;
* thread-hostile: the class is known to break threads, even when no instance is shared between threads!&lt;br /&gt;
&lt;br /&gt;
=== About the comments ===&lt;br /&gt;
&lt;br /&gt;
Some recurring comments are explained here :&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Exposed mutable attributes.&amp;quot;: the class contains attributes that either &amp;quot;come&amp;quot; from outside the class, or whose reference can be obtained from the class. Unless the attributes are thread-safe or accessed in a thread-safe manner somehow, this breaks the thread safety of the class.&lt;br /&gt;
* &amp;quot;documented as immutable, but technically untrue&amp;quot;: Patrius document classes that are non-final as immutable- but the (quite strict) usual definition of immutability mandates that an immutable class &#039;&#039;must&#039;&#039; be final, because a non-final class can be subclassed and this subclass can break immutability &amp;quot;silently&amp;quot; (an user could access this subclass through the superclass reference and believe it is immutable due to the superclasses&#039; documentation.) Therefore: when a class is documented as immutable, it means &#039;&#039;only the documented implementation&#039;&#039; is immutable. For safety, we chose to document these classes here as &amp;quot;unconditionally thread-safe&amp;quot;, a statement that is not assumed to be preserved by subclassing.&lt;br /&gt;
&lt;br /&gt;
=== Thread safety ===&lt;br /&gt;
Details concerning the thread safety for each of the PATRIUS classes can be found [[:Category:Thread_Safety_4.18|here]].&lt;br /&gt;
&lt;br /&gt;
==== Note : Frames and thread-safety ====&lt;br /&gt;
&lt;br /&gt;
It was determined that several Frame implementations were thread-hostile.&lt;br /&gt;
&lt;br /&gt;
The current evaluation of these changes from a thread-safety point of view leads us to state the following :&lt;br /&gt;
&lt;br /&gt;
* The IERS frames (GCRF, CIRF, TIRF and ITRF) are thread-safe.&lt;br /&gt;
&lt;br /&gt;
== Known Issues ==&lt;br /&gt;
None.&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Patrius_Backward_Compatibility_4.18&amp;diff=4162</id>
		<title>Catégorie:Patrius Backward Compatibility 4.18</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Patrius_Backward_Compatibility_4.18&amp;diff=4162"/>
		<updated>2026-06-10T09:03:06Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec «  == Introduction == A specific backward compatibility mechanism is implemented in PATRIUS allowing by default to have a backward compatibility with PATRIUS version 4.12 propagation models and/or optimisation algorithms. If any action is provided by the user, the &amp;#039;&amp;#039;&amp;#039;backward compatibility is activated by default in PATRIUS&amp;#039;&amp;#039;&amp;#039; : this means that external users will see their code/functions working with some of the propagation models/optimisation algorithms of PATRIU... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Introduction ==&lt;br /&gt;
A specific backward compatibility mechanism is implemented in PATRIUS allowing by default to have a backward compatibility with PATRIUS version 4.12 propagation models and/or optimisation algorithms.&lt;br /&gt;
If any action is provided by the user, the &#039;&#039;&#039;backward compatibility is activated by default in PATRIUS&#039;&#039;&#039; : this means that external users will see their code/functions working with some of the propagation models/optimisation algorithms of PATRIUS version 4.12.&lt;br /&gt;
&lt;br /&gt;
== Backward compatibility functionalities ==&lt;br /&gt;
&lt;br /&gt;
=== Available options ===&lt;br /&gt;
Three options are available for users via the enum &amp;lt;code&amp;gt;PatriusVersionCompatibility&amp;lt;/code&amp;gt; of the class &amp;lt;code&amp;gt;PatriusConfiguration&amp;lt;/code&amp;gt;:&lt;br /&gt;
* OLD_MODELS : the user will use the propagation models and optimisation algorithms coded in PATRIUS version 4.12;&lt;br /&gt;
* MIXED_MODELS : the user will just use propagation models coded in PATRIUS version 4.12 (no backward compatibility on optimisation algorithms);&lt;br /&gt;
* NEW_MODELS : no backward compatibility mechanism is used.&lt;br /&gt;
&lt;br /&gt;
=== Backward compatibility for propagation models ===&lt;br /&gt;
As previously mentioned,  types &amp;lt;code&amp;gt;PatriusVersionCompatibility.OLD_MODELS&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;MIXED_MODELS&amp;lt;/code&amp;gt; allow to restore some of the propagation models to the state of PATRIUS version 4.12 for the following functionalities:&lt;br /&gt;
* eclipse detection via the class &amp;lt;code&amp;gt;EclipseDetector&amp;lt;/code&amp;gt;;&lt;br /&gt;
* solar radiation pressure computation with the class &amp;lt;code&amp;gt;SolarRadiationPressure&amp;lt;/code&amp;gt;;&lt;br /&gt;
* use of previous obliquity coefficients in the class &amp;lt;code&amp;gt;EclipticMODProvider&amp;lt;/code&amp;gt; ;&lt;br /&gt;
* allows the use of previous entries in the factory &amp;lt;code&amp;gt;PrecessionNutationModelFactory&amp;lt;/code&amp;gt; and pole coordinates computation in the class &amp;lt;code&amp;gt;IERS20032010PrecessionNutation&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Backward compatibility for optimisation algorithms ===&lt;br /&gt;
The type of compatibility configuration OLD_MODELS allows to restore also the behaviour of the optimisation algorithm for matrix conversion existing in PATRIUS 4.12 and implemented in the method &amp;lt;code&amp;gt;convertMatrixFromAToB&amp;lt;/code&amp;gt; of the class &amp;lt;code&amp;gt;AbstractBodyAttraction&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== How to set our own Patrius compatibility configuration ==&lt;br /&gt;
The class &amp;lt;code&amp;gt;PatriusConfiguration&amp;lt;/code&amp;gt; contains a setter &amp;lt;code&amp;gt;setPatriusCompatibilityMode(PatriusVersionCompatibility)&amp;lt;/code&amp;gt; that allows to switch our own configuration as a function of the user needs.&lt;br /&gt;
A specific getter &amp;lt;code&amp;gt;getPatriusCompatibilityMode&amp;lt;/code&amp;gt; allows to retrieve the used configuration at any moment if needed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Thread_Safety_4.18&amp;diff=4161</id>
		<title>Catégorie:Thread Safety 4.18</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Thread_Safety_4.18&amp;diff=4161"/>
		<updated>2026-06-10T09:02:31Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « The following tables contains information about the different class of PATRIUS and their thread-safety properties.  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Class (total number : 43) ! scope=&amp;quot;col&amp;quot;| Concurrency ! scope=&amp;quot;col&amp;quot;| Comment |- |fr.cnes.sirius.patrius.math.UtilsCommonsMath |immutable | |- |fr.cnes.sirius.patrius.math.analysis.differentiation.RiddersDifferentiator |immutable | |- |fr.cnes.sirius.patrius.math.analysis.interpolation.BiLinearIntervalsFunction |... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following tables contains information about the different class of PATRIUS and their thread-safety properties.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class (total number : 43)&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Concurrency&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Comment&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.UtilsCommonsMath&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.differentiation.RiddersDifferentiator&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.interpolation.BiLinearIntervalsFunction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|input ISearchIndex not thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.interpolation.BiLinearIntervalsInterpolator&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.interpolation.TriLinearIntervalsFunction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|input ISearchIndex not thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.interpolation.TriLinearIntervalsInterpolator&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.interpolation.UniLinearIntervalsFunction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|input ISearchIndex not thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.interpolation.UniLinearIntervalsInterpolator&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.polynomials.ElementaryMultiplicationTypes&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-utility class without attributes&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.polynomials.FourierDecompositionEngine&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|not thread safe because of the setFunction method that can change the UnivariateFunction being decomposed&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.polynomials.FourierSeries&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.polynomials.FourierSeriesApproximation&lt;br /&gt;
|immutable if function is immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.polynomials.TrigonometricPolynomialFunction&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.polynomials.TrigonometricPolynomialPrimitive&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.Disk&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.Ellipse&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.Ellipsoid&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.EllipticCone&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.EllipticCylinder&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.InfiniteEllipticCone&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.InfiniteEllipticCylinder&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.InfiniteRectangleCone&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.InfiniteRectangleCylinder&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.InfiniteRightCircularCone&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.InfiniteRightCircularCylinder&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.LineSegment&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.Matrix3D&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.Parallelepiped&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.Plate&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.RectangleCone&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.RightCircularCone&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.RightCircularCylinder&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.Sphere&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.SphericalCap&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.Spheroid&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.linear.UDDecompositionImpl&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.ode.nonstiff.RungeKutta6Integrator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.ode.nonstiff.RungeKutta6StepInterpolator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.random.UniformlyCorrelatedRandomVectorGenerator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.utils.BinarySearchIndexClosedOpen&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.utils.BinarySearchIndexOpenClosed&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.utils.RecordSegmentSearchIndex&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.utils.SearchIndexLibrary&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class (total number : 103)&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Concurrency&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Comment&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.AttitudeChronologicalComparator&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.AttitudeFrame&lt;br /&gt;
|not thread safe&lt;br /&gt;
|it is a Frame.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.AttitudeLawLeg&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|The use of an AttitudeLaw makes it thread-safe only if the AttitudeLaw is.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.AttitudeLegLaw&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|The use of an AttitudeLegLaw makes it thread-safe only if      the two AttitudeLaw and the AttitudeLeg are.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.AttitudeLegsSequence&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.AttitudeTransformProvider&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|is thread-safe if all attributes are.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.ComposedAttitudeLaw&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|is thread-safe if the AttitudeLaw attribute is.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.ConstantSpinSlew&lt;br /&gt;
|not thread safe&lt;br /&gt;
|this class is not thread safe because the slew can be re-computed while the method                     getAttitude(PVCoordinatesProvider, AbsoluteDate, Frame) is called.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.DirectionTrackingOrientation&lt;br /&gt;
|conditionally thread safe&lt;br /&gt;
|the IDirection object has to be thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.FixedStepAttitudeEphemerisGenerator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The AttitudeLegsSequence attribute is mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.OrientationFrame&lt;br /&gt;
|not thread safe&lt;br /&gt;
|it is a Frame.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.OrientationTransformProvider&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if all attributes are.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.RelativeTabulatedAttitudeLaw&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|The use of an RelativeTabulatedAttitudeLaw makes it thread-safe only if     the AttitudeLeglaw is&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.RelativeTabulatedAttitudeLeg&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.SunPointing&lt;br /&gt;
|unconditionally thread safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.TabulatedAttitude&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.TwoDirectionsAttitude&lt;br /&gt;
|unconditionally thread safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.TwoSpinBiasSlew&lt;br /&gt;
|not thread safe&lt;br /&gt;
|this class is not thread safe because the local attitude ephemeris is changed.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.VariableStepAttitudeEphemerisGenerator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The AttitudeLegsSequence attribute is mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.directions.CelestialBodyPolesAxisDirection&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|this class is thread-safe only if the underlying CelestialBody is too.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.directions.CentralBodyCenterDirection&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.directions.ConstantVectorDirection&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The use of a frame linked to the tree of frames makes this class not thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.directions.CrossProductDirection&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|this class is not thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.directions.GenericTargetDirection&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Not thread-safe by default.No use case for sharing an instance between threads found.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.directions.GlintApproximatePointingDirection&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Not thread-safe by default.No use case for sharing an instance between threads found.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.directions.GroundVelocityDirection&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|The use of a celestial body linked to the tree of frames                     makes this class thread-safe only if the underlying CelestialBody is too.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.directions.MomentumDirection&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|The use of a celestial body linked to the tree of frames makes this class thread-safe only if the underlying CelestialBody is too.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.directions.NadirDirection&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|The use of a celestial body linked to the tree of frames                     makes this class thread-safe only if the underlying CelestialBody is too.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.directions.ToCelestialBodyCenterDirection&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|The use of a celestial body linked to the tree of frames                     makes this class thread-safe only if the underlying CelestialBody is too.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.directions.VelocityDirection&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Not thread-safe by default. No use case for sharing an instance between threads found.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.kinematics.SlerpInterpolator&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.bodies.ExtendedOneAxisEllipsoid&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the use of frames makes this class not thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.bodies.MeeusMoon&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.bodies.MeeusSun&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.MSIS2000.ApCoef&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.MSIS2000.Flags&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.MSIS2000.Input&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.MSIS2000.NRLMSISE00&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.MSIS2000.NRLMSISE00Data&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.MSIS2000.Output&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.MSISE2000&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|The direct use of thread hostile objects makes this class thread hostile itself.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.US76&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|The direct use of thread hostile objects makes this class thread hostile itself.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.US76Data&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.ACSOLFormatReader&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|instance is mutable&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.ConstantSolarActivity&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.NOAAFormatReader&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|instance is mutable&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.SolarActivityDataFactory&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|uses {@link DataProvidersManager} which is thread hostile&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.SolarActivityToolbox&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.specialized.ClassicalMSISE2000SolarData&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if SolarActivityDataProvider is thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.specialized.ContinuousMSISE2000SolarData&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if SolarActivityDataProvider is thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.atmospheres.solarActivity.specialized.DTM2000SolarData&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if SolarActivityDataProvider is thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.EarthGravitationalModelFactory&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the presence of static methods makes this class not thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.tides.OceanTides&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|not thread safe because of the method updateCoefficientsCandS().&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.tides.OceanTidesDataProvider&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.tides.OceanTidesWaves&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.tides.TerrestrialTides&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|not thread safe because of the method updateCoefficientsCandS().&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.tides.TerrestrialTidesDataProvider&lt;br /&gt;
|thread safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.tides.TidesStandards&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.tides.TidesToolbox&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.tides.coefficients.FES2004FormatReader&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|instance is mutable&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.tides.coefficients.OceanTidesCoefficientsFactory&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|uses a thread-hostile DataProvidersManager&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.tides.coefficients.OceanTidesCoefficientsSet&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.variations.VariablePotentialAttractionModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|not thread-safe because of global arrays&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.variations.coefficients.GRGSRL02FormatReader&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|because of static fields&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.variations.coefficients.VariableGravityFieldFactory&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|because of static fields&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.variations.coefficients.VariablePotentialCoefficientsSet&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.maneuvers.ConstantThrustError&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|internal mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.maneuvers.VariableThrustManeuver&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|internal mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.radiation.ElementaryFlux&lt;br /&gt;
|immutable&lt;br /&gt;
|immutable class&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.radiation.KnockeRiesModel&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.radiation.RediffusedFlux&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if all constructor parameters are too.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.radiation.RediffusedRadiationPressure&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if the CelestialBody attribute is.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.analytical.covariance.CovarianceInterpolation&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|internal mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.analytical.covariance.OrbitCovariance&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.analytical.twod.Analytical2DOrbitModel&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread safe if the underlying Analytical2DParameterModel andAbsoluteDate objects are thread safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.analytical.twod.Analytical2DParameterModel&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.analytical.twod.Analytical2DPropagator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|extends the AbstractPropagator class&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.analytical.twod.DateIntervalLinearFunction&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.analytical.twod.DateIntervalParabolicFunction&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.analytical.twod.DatePolynomialFunction&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.AOLDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.AnomalyDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.BetaAngleDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.DistanceDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.ExtremaDistanceDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.ExtremaElevationDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the link to the tree of frames makes this class not thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.ExtremaLatitudeDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.ExtremaLongitudeDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.ExtremaThreeBodiesAngleDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.LatitudeDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.LocalTimeDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.LongitudeDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.NadirSolarIncidenceDetector&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|the earth celestial body is thread hostile itself.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.NthOccurrenceDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|use of internal mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.SolarTimeDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.ThreeBodiesAngleDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.precomputed.HermiteEphemeris&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|internal mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.precomputed.LagrangeEphemeris&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|instances are mutable&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.LocalTime&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.utils.AbsoluteDateIntervalsList&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|thread safety is not required for this class. And, TreeSet is not thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.utils.EphemerisPvHermite&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|internal mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.utils.EphemerisPvLagrange&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|internal mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.utils.ReferencePointsDisplacement&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|is thread-safe if the celestial body is too.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class (total number : 162)&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Concurrency&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Comment&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.utils.UtilsPatrius&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.Assembly&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The use of a frame linked to the tree of frames in each of the parts makes this class not                     thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.AssemblyBuilder&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The assembly is not thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.MainPart&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The use of a frame linked to the tree of frames makes this class not thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.Part&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The use of a frame linked to the tree of frames makes this class not thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.models.AeroModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The use of a frame (Assembly attribute) linked to the tree of frames in each of the parts makes                     this class not thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.models.AeroWrenchModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|class uses internal mutable attributes and frames&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.models.DirectRadiativeModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The use of a frame (Assembly attribute) linked to the tree of frames in each of the parts makes                     this class not thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.models.DirectRadiativeWrenchModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|class uses internal mutable attributes and frames&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.models.DragLiftModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The use of a frame (Assembly attribute) linked to the tree of frames in each of the parts makes                     this class not thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.models.InertiaComputedModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the direct use of a not thread-safe Assembly makes this class                     not thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.models.InertiaSimpleModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the frame and setters makes this class not thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.models.MagneticMoment&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if the underlying frame is thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.models.MassModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|uses internal mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.models.RFLinkBudgetModel&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.models.RediffusedRadiativeModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The use of a frame (Assembly attribute) linked to the treeof frames in each of the parts makes this class not thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.models.SensorModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the direct use of a not thread-safe Assembly makes this classnot thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.AeroApplicationPoint&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.AeroFacetProperty&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.AeroGlobalProperty&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.AeroSphereProperty&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.CrossSectionProviderProperty&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|the CrossSectionProvider object must be immutable. In this case, thisclass is immutable itself and thus, is not subject to thread safety tests.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.GeometricProperty&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|the SolidShape object must be immutable. In this case, thisclass is immutable itself and thus, is not subject to thread safety tests.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.InertiaCylinderProperty&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the use of frames makes this class not thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.InertiaParallelepipedProperty&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the use of frames makes this class not thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.InertiaSimpleProperty&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the use of frames makes this class not thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.InertiaSphereProperty&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the use of frames makes this class not thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.MassEquation&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|internal mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.MassProperty&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.RFAntennaProperty&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.RadiativeApplicationPoint&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.RadiativeFacetProperty&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.RadiativeIRProperty&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.RadiativeProperty&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.RadiativeSphereProperty&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.SensorProperty&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.assembly.properties.features.Facet&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.bodies.BasicBoardSun&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.CentralBodyMaskCircularFOVDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|one attribute not thread-safe and one conditionally thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.CodedEvent&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.CodedEventsList&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|no thread-sharing use case was identified for this class, so thread safety is not required.                     Though, some precautions are taken, as an example, the method getList() returns a copy of the                     list and not directly the attribute list itself.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.CodedEventsLogger&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|no thread-sharing use case was identified for this class, so thread safety is not required.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.CombinedPhenomenaDetector&lt;br /&gt;
|not thread-safe or thread-hostile&lt;br /&gt;
|As of now, existing EventDetector implementations are either not thread-safe                     or thread-hostile, so this class also is.                     But this class could probably become conditionally thread-safe,                     the main thread safety condition would then be that the included EventDetector                     should be thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.EarthZoneDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.GenericCodingEventDetector&lt;br /&gt;
|not thread-safe or thread-hostile&lt;br /&gt;
|As of now, existing EventDetector implementations are either not thread-safe                     or thread-hostile, so this class also is.                     But this class could probably become conditionally thread-safe,                     the main thread safety condition would then be that the included EventDetector                     should be thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.PhenomenaList&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|no thread-sharing use case was identified for this class, so thread safety is not required.                     Though, some precautions are taken, as an example, the method getList() returns a copy of the                     list and not directly the attribute list itself.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.Phenomenon&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.multi.MultiCodedEventsLogger&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|no thread-sharing use case was identified for this class, so thread safety is not required.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.multi.MultiEventsLogger&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.multi.MultiGenericCodingEventDetector&lt;br /&gt;
|not thread-safe or thread-hostile&lt;br /&gt;
|As of now, existing MultiEventDetector implementations are either not thread-safe                     or thread-hostile, so this class also is.                     But this class could probably become conditionally thread-safe,                     the main thread safety condition would then be that the included MultiEventDetector                     should be thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.AndCriterion&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.DelayCriterion&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.ElementTypeFilter&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.EventsDuringPhenomenaFilter&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.MergePhenomenaCriterion&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.MergeTimelines&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.OccurrenceFilter&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.OrCriterion&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.PhenomenonDurationFilter&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.PolarizationSingleSelection&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.PolarizationSwitch&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.TimeFilter&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.postprocessing.Timeline&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the timeline is not thread safe due to the methods removeCodedEvent(CodedEvent) and                     removePhenomenon(Phenomenon)&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.sensor.ExtremaSightAxisDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation,                     and the direct use of a not thread-safe Assembly makes this class not thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.sensor.MaskingDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The use of a not thread-safe SensorModel makes this class not thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.sensor.RFVisibilityDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the direct use of a not thread-safe Assembly makes this classnot thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.sensor.SatToSatMutualVisibilityDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the direct use of a not thread-safe Assembly makes this class                     not thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.sensor.SecondarySpacecraft&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the direct use of a not thread-safe Assembly makes this classnot thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.sensor.SensorInhibitionDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the direct use of a not thread-safe Assembly makes this classnot thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.sensor.SensorVisibilityDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the direct use of a not thread-safe Assembly makes this classnot thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.sensor.StationToSatMutualVisibilityDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the direct use of a not thread-safe Assembly makes this classnot thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.sensor.TargetInFieldOfViewDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the direct use of a not thread-safe Assembly makes this classnot thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.events.sensor.VisibilityFromStationDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the direct use of a not thread-safe Assembly makes this classnot thread-safe itself&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.fieldsofview.AzimuthElevationField&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.fieldsofview.BooleanField&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|the used fields must be thread-safe themselves.All available fields are immutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.fieldsofview.CircularField&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.fieldsofview.EllipticField&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.fieldsofview.FieldAngularFace&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.fieldsofview.InvertField&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|the used field must be thread-safe itself.All available fields are immutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.fieldsofview.OmnidirectionalField&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.fieldsofview.PyramidalField&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.fieldsofview.RectangleField&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.fieldsofview.SectorField&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.EmpiricalForce&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.maneuvers.ManeuversSequence&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|The instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.radiation.SolarRadiationPressureEllipsoidCircular&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|fields use Frames&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.groundstation.GeometricStationAntenna&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|link to the tree of frames&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.groundstation.RFStationAntenna&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|link to the tree of frames&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.guidance.AngularVelocitiesHarmonicProfile&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if the Frame attribute is thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.guidance.AngularVelocitiesPolynomialProfile&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if the attributes are thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.guidance.GuidanceProfileBuilder&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.guidance.QuaternionHarmonicProfile&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if the Frame attribute is thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.guidance.QuaternionPolynomialProfile&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if the attributes are thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.guidance.QuaternionPolynomialSegment&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if the UnivariateFunction attributes are thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.guidance.Vector3DPolynomialSegment&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if the UnivariateFunction attributes are thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.PVCoordinatePropagator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|extends the AbstractPropagator class&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.SimpleAdditionalStateProvider&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.multi.AdaptedMonoEventDetector&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|Conditionally thread-safe if all attributes are thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.multi.AdaptedMultiEventDetector&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|Conditionally thread-safe if all attributes are thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.multi.OneSatEventDetectorWrapper&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.numerical.multi.MultiEphemerisModeHandler&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.numerical.multi.MultiNumericalPropagator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|attributes are mutable and related to propagation.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.numerical.multi.MultiStateVectorInfo&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.precomputed.multi.MultiIntegratedEphemeris&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.sampling.multi.MultiAdaptedStepHandler&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.sampling.multi.MultiPatriusStepNormalizer&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.signalpropagation.AzoulayModel&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.signalpropagation.SignalPropagation&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|use of the frames tree&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.signalpropagation.SignalPropagationModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|use of the frames tree&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.signalpropagation.iono.BentModel&lt;br /&gt;
|thread-safe&lt;br /&gt;
| with the use of a synchronized tag&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.signalpropagation.iono.R12Loader&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|the instance is mutable, but no longer changes after the first call to getR12() (the first call                     triggers the DataProvidersManager on the instance).                     This means : an instance can be shared and used in several threads, if getR12() is called once                     in a single thread context first.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.signalpropagation.iono.USKData&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.signalpropagation.iono.USKLoader&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|the instance is mutable, but no longer changes after the first call to getData() (the first call                     triggers the DataProvidersManager on the instance).                     This means : an instance can be shared and used in several threads, if getData() is called once                     in a single thread context first.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.JavaMathAdapter&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.PerigeeAltitudeDetector&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|the OrbitNatureConverter attribute needs to be thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.StelaSpacecraftFactory&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|access to the only static field is synchronized&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.bodies.EarthRotation&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.bodies.GeodPosition&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.bodies.MeeusMoonStela&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.bodies.MeeusSunStela&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.Squaring&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.StelaLagrangeEquations&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|not thread-safe because two threads can simultaneously modify global attributes of the class&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.atmospheres.MSIS00Adapter&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|The direct use of thread hostile objects makes this class thread hostile itself.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.drag.StelaAeroModel&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.drag.StelaAtmosphericDrag&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|not thread-safe due to use of mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.drag.StelaCd&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.gravity.StelaTesseralAttraction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|not thread-safe due to use of mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.gravity.StelaThirdBodyAttraction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|not thread-safe because two threads can simultaneously modify attributes of the class&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.gravity.StelaZonalAttraction&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread safe if the PotentialCoefficientsProvider used is thread safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.gravity.StelaZonalAttractionJ10&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.gravity.StelaZonalAttractionJ11&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.gravity.StelaZonalAttractionJ12&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.gravity.StelaZonalAttractionJ13&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.gravity.StelaZonalAttractionJ14&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.gravity.StelaZonalAttractionJ15&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.gravity.StelaZonalAttractionJ8&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.gravity.StelaZonalAttractionJ9&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.gravity.TesseralQuad&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|use of internal mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.noninertial.NonInertialContribution&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.radiation.SRPPotential&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread safe if the CelestialBody used is thread safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.radiation.SRPSquaring&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if the given sun is thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.forces.radiation.StelaSRPSquaring&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if the SRPSquaring and SRPPotential models are thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.orbits.JacobianConverter&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.orbits.OrbitNatureConverter&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|instances are mutable&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.orbits.StelaEquinoctialOrbit&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.propagation.ForcesStepHandler&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.propagation.StelaBasicInterpolator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.propagation.StelaDifferentialEquations&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|not thread-safe due to use of mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.propagation.StelaGTOPropagator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|use of mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.propagation.StelaPartialDerivativesEquations&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|use of mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.stela.propagation.data.TimeDerivativeData&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.orbits.pvcoordinates.AlmanacPVCoordinates&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.interval.AngleInterval&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.interval.AngleTools&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.Comparators&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.utils.GPSGalileoAlmanacParameter&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.interval.GenericInterval&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.wrenches.DragWrench&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|class uses internal mutable attributes and frames&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.wrenches.GenericWrenchModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|uses frames&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.wrenches.GravitationalAttractionWrench&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if the inertia model is thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.wrenches.MagneticWrench&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if the underlying geo magnetic field is also thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.wrenches.SolarRadiationWrench&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|class uses internal mutable attributes and frames&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Patrius-tools thread safety ===&lt;br /&gt;
&lt;br /&gt;
Here is a list of all patrius-tools classes and thread-safety:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- &lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class (total number : 23)&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Concurrency&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Comment&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.ComparisonData&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|this class is not thread safe due to setThresholds(ArrayList)&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.Data&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|matches the concurrency of the parameter type : using an immutable type is HIGHLY recommended&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.DateDPFacade&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.DeviationProviderFactory&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.DoubleDPFacade&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.EphemerisComparator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|it uses non thread-safe objects&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.EphemerisComparatorMain&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|it uses non thread-safe objects&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.MeaningfulData&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.MeaningfulDataComparator&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.PSimuDataLoader&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|the file could be tampered with while reading it&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.PVCoordinatesDPFacade&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.QuaternionDPFacade&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.RawDataComparator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|this class is not thread safe due to the attribute &#039;relative&#039; which can change&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.Report&lt;br /&gt;
|thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.RotationDPFacade&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.Setup&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|this class is not thread safe due to the fact that some attributes are not private&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.ThresholdsData&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|this class is not thread safe due to getFirstRefusedLines()&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.ephemerisComparator.VectorDPFacade&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.exception.EphemerisComparatorException&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|extends Exception&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.exception.EphemerisComparatorRuntimeException&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|extends Exception&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.force.validation.BasicPVCoordinatesProvider&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.force.validation.PVEphemerisLoader&lt;br /&gt;
|not thread safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.tools.force.validation.Report&lt;br /&gt;
|not thread safe&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- &lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Concurrency&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Comment&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.integration.TrapezoidIntegrator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.integration.SimpsonIntegrator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.interpolation.BicubicSplineInterpolatingFunction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable (unprotected lazy initialization).&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.interpolation.BicubicSplineInterpolator&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.interpolation.TricubicSplineInterpolatingFunction&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.interpolation.TricubicSplineInterpolator&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.polynomials.PolynomialFunction&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.polynomials.PolynomialFunctionLagrangeForm&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable (unprotected lazy initialization).&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.polynomials.PolynomialFunctionNewtonForm&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable (unprotected lazy initialization).&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.polynomials.HelmholtzPolynomial&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.solvers.BrentSolver&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable (inner Incrementor instance).&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.solvers.NewtonSolver&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable (inner Incrementor instance).&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.solvers.BisectionSolver&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable (inner Incrementor instance).&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.analysis.solvers.MullerSolver&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable (inner Incrementor instance).&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.Plane&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.Rotation&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.RotationOrder&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.Vector3D&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.geometry.euclidean.threed.Screw&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.linear.Array2DRowRealMatrix&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.linear.ArrayRealVector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.linear.CholeskyDecompositionImpl&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes (getters on RealMtrix).&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.linear.LUDecompositionImpl&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes (getters on RealMtrix).&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.linear.QRDecompositionImpl&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes (getters on RealMtrix).&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.ode.events.EventHandler&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.ode.events.EventException&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.ode.nonstiff.ClassicalRungeKuttaIntegrator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.ode.nonstiff.DormandPrince54Integrator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.ode.nonstiff.DormandPrince853Integrator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.ode.nonstiff.GraggBulirschStoerIntegrator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.random.JDKRandomGenerator&lt;br /&gt;
|thread-safe&lt;br /&gt;
|Extends a class from the Java API whose thread-safety status is undocumented, but probably thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.stat.StatUtils&lt;br /&gt;
|immutable&lt;br /&gt;
|Final utility class with reentrant static methods only.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.stat.descriptive.rank.Median&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.stat.descriptive.rank.Percentile&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.util.FastMath&lt;br /&gt;
|immutable&lt;br /&gt;
|Final utility class with reentrant static methods only.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.math.util.MathUtils&lt;br /&gt;
|immutable&lt;br /&gt;
|Final utility class with reentrant static methods only.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* when these are documented as &amp;quot;immutable&amp;quot; in their javadoc, it is stated so.&lt;br /&gt;
* the remainder was evaluated by the PATRIUS team.&lt;br /&gt;
&lt;br /&gt;
The list of all validated classes is also available in the SVS.&lt;br /&gt;
&lt;br /&gt;
NOTE : thread hostility has not been systematically researched, so it is not fully documented in this revision.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; &lt;br /&gt;
|- &lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Concurrency&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Comment&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.Attitude&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|Exposed mutable attribute (getter on Frame), Attitude is thread-safe when the Frame is.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.AttitudesSequence&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.BodyCenterPointing&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.CelestialBodyPointed&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.BodyCenterGroundPointing.java&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.FixedRate&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.InertialProvider&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.LofOffset&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|Is thread-safe when the Frame attribute is.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.NadirPointing&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.SpinStabilized&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.TargetGroundPointing.java&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.TargetPointing&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.YawCompensation&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.YawSteering&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.kinematics.KinematicsToolkit&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.kinematics.AbstractOrientationFunction&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|Thread-safe if the attribute differentiator is thread-safe and if the implementation of this abstract class is thread-safe too.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.kinematics.AbstractVector3DFunction&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|Thread-safe if the attributes differentiator and integrator are thread-safe and if the implementation of this abstract class is thread-safe too.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.attitudes.kinematics.DynamicsElements&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.bodies.GeodeticPoint&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.bodies.JPLEphemeridesLoader&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|Unprotected mutable fields are modified by the loadData() method. If this method call is protected, the instance is thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.bodies.OneAxisEllipsoid&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.data.ClasspathCrawler&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|The feed() method modifies a mutable reference (DataLoader) that may not be thread-safe. If the call to feed() is protected and the DataLoader is not thread-hostile, OR if the DataLoader is thread-safe, then the instance is thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.data.DataProvidersManager&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|Contains an unprotected singleton.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.data.DirectoryCrawler&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|The feed() method modifies a mutable reference (DataLoader) that may not be thread-safe. If the call to feed() is protected and the DataLoader is not thread-hostile, OR if the DataLoader is thread-safe, then the instance is thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.data.NetworkCrawler&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|The feed() method modifies a mutable reference (DataLoader) that may not be thread-safe. If the call to feed() is protected and the DataLoader is not thread-hostile, OR if the DataLoader is thread-safe, then the instance is thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.data.PoissonSeries&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Technically non-immutable, but immutable &amp;quot;in practice&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.data.ZipJarCrawler&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|The feed() method modifies a mutable reference (DataLoader) that may not be thread-safe. If the call to feed() is protected and the DataLoader is not thread-hostile, OR if the DataLoader is thread-safe, then the instance is thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.utils.exception.PatriusException&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.utils.exception.PropagationException&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.ConstantFunction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|uses internal mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.IJacobiansParameterizable&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|uses internal mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.IParamDiffFunction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|uses internal mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.IParameterizableFunction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|uses internal mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.LinearFunction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|uses internal mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.Parameter&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|uses internal mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.Parameterizable&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|uses internal mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.PiecewiseFunction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|uses internal mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.BoxAndSolarArraySpacecraft&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.drag.DTM2000&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.drag.DragForce&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.BalminoAttractionModel.java&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|uses internal mutable attributes&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.potential.EGMFormatReader&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.potential.GravityFieldFactory&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Access to mutable fields are synchronized.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.potential.GRGSFormatReader&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.potential.ICGEMFormatReader&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.potential.SHMFormatReader&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.CunninghamAttractionModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.DrozinerAttractionModel&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.GravityToolbox.java&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.NewtonianAttraction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.gravity.ThirdBodyAttraction&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.maneuvers.ConstantThrustManeuver&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.forces.radiation.SolarRadiationPressureCircular&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.Frame&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Unprotected mutable attribute- but thread-safety problems relative to this attribute have yet to be found, so Frame is &amp;quot;almost&amp;quot; thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.FramesFactory&lt;br /&gt;
|unconditionally thres-safe&lt;br /&gt;
|Access to mutable fields are synchronized. NOTE : The IERS frames provided by this class are thread-safe, these are provided by the getGCRF(), getCIRF(), getTIRF() and getITRF() methods.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.LocalOrbitalFrame&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.OrphanFrame&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|No attributes, static methods only.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.TopocentricFrame&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Is a Frame.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.DiurnalRotation&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if constructor parameters are thread safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.FramesConfigurationFactory&lt;br /&gt;
|thread-safe&lt;br /&gt;
|only static methods&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.FramesConfigurationImplementation&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if constructor parameters are thread safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.PolarMotion&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread-safe if constructor parameters are thread safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.AbstractEOPHistory&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|Uses the time stamped cache mechanism. Thread-safe as long as the mechanisms that add entries to the lists do so in a thread-safe manner (see EOPHistoryFactory).&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.BulletinBFilesLoader&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.EOP05C04FilesLoader&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.EOP08C04FilesLoader&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.EOP1980Entry&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.EOP1980History.java&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Uses the time stamped cache mechanism|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.EOP2000Entry&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.EOP2000History&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Uses the time stamped cache mechanism|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.EOPEntry&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.EOPHistoryFactory&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|getters use synchronized keyword were access to loader lists is performed&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.NoEOP2000History&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.NutationCorrection&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.PoleCorrection&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.RapidDataAndPredictionColumnsLoader&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.eop.RapidDataAndPredictionXMLLoader&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.libration.LibrationCorrectionModelFactory&lt;br /&gt;
|immutable&lt;br /&gt;
|only static final fields&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.libration.IERS2010LibrationCorrection&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.libration.NoLibrationCorrection&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.precessionnutation.CIPCoordinates&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.precessionnutation.CIPCoordinatesGenerator&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|As long as a generator is referenced by one {@link TimeStampedCache cache} only, it is guaranteed to be called in a thread-safe way, even if the cache is used in a multi-threaded environment. &lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.precessionnutation.IERS20032010PrecessionNutation&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.precessionnutation.PrecessionNutationCache&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread safe if precession nutation model is thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.precessionnutation.PrecessionNutationModelFactory&lt;br /&gt;
|immutable&lt;br /&gt;
|only static final fields&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.sp.IERS2010SPCorrection&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.sp.NoSpCorrection&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.sp.SPrimeModelFactory&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.tides.TidelCorrectionCache&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|thread safe if tides model is thread-safe&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.tides.TidalCorrection&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.tides.TidalCorrectionGenerator&lt;br /&gt;
|conditionally thread-safe&lt;br /&gt;
|As long as a generator is referenced by one {@link TimeStampedCache cache} only, it is guaranteed to be called in a thread-safe way, even if the cache is used in a multi-threaded environment. &lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.tides.IERS2000TidalCorrection&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.tides.IERS2010TidalCorrection&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.tides.NoTidalCorrection&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.configuration.tides.TidalCorrectionModelFactory&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.transformations.HelmertTransformation&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.frames.transformations.Transform&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.models.earth.COFFileFormatReader.java&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|instance is mutable&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.models.earth.FixedDelayModel.java&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|instance is mutable&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.models.earth.GeoMagneticModelReader.java&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|instance is mutable&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.models.earth.GeoMagneticElements&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.models.earth.GeoMagneticField&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instance are mutable&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.models.earth.GeoMagneticFieldFactory&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Access to mutable fields are synchronized.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.models.earth.ModelLoader&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Mutable fields&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.orbits.CartesianOrbit&lt;br /&gt;
|immutable&lt;br /&gt;
|Modified by Patrius team.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.orbits.CircularOrbit&lt;br /&gt;
|immutable&lt;br /&gt;
|Modified by Patrius team.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.orbits.EquinoctialOrbit&lt;br /&gt;
|immutable&lt;br /&gt;
|Modified by Patrius team.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.orbits.KeplerianOrbit&lt;br /&gt;
|immutable&lt;br /&gt;
|Modified by Patrius team.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.orbits.ApsisOrbit&lt;br /&gt;
|immutable&lt;br /&gt;
|Created by Patrius team.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.orbits.EquatorialOrbit&lt;br /&gt;
|immutable&lt;br /&gt;
|Created by Patrius team.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.analytical.EcksteinHechlerPropagator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.analytical.KeplerianPropagator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.AdaptedAdditionalStatesEventDetector&lt;br /&gt;
|conditionally thread-safe &lt;br /&gt;
|if all attributes are thread safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.AdaptedEventDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.AdditionalStatesEventsLogger&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.AlignmentDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.AltitudeDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.ApsideDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.CircularFieldOfViewDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.DateDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.DihedralFieldOfViewDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.EclipseDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.ElevationDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.EventShifter&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.EventsLogger&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.EventState&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.GroundMaskElevationDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.NodeDetector&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.numerical.AdditionalStateInfo&lt;br /&gt;
|Immutable&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.numerical.JacobiansMapper&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.numerical.NumericalPropagator&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|As documented.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.events.PartialDerivativesEquations&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.precomputed.Ephemeris&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.precomputed.IntegratedEphemeris&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.sampling.AdaptedStepHandler&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.SpacecraftState&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.propagation.SimpleMassModel.java&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|instance is mutable. WARNING : this class is wrongfully documented as immutable (javadoc)! It is mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.AbsoluteDate&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.DateComponents&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.DateTimeComponents&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.GalileoScale&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.GPSScale&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|A deprecated method calls the thread-hostile TimeScalesFactory. When this method is removed, the class will become thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.TimeComponents&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.TimeScalesFactory&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|Contains unprotected singletons.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.TAIScale&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|A deprecated method calls the thread-hostile TimeScalesFactory. When this method is removed, the class will become thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.TTScale&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|A deprecated method calls the thread-hostile TimeScalesFactory. When this method is removed, the class will become thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.UTCScale&lt;br /&gt;
|thread-hostile&lt;br /&gt;
|A deprecated method calls the thread-hostile TimeScalesFactory. When this method is removed, the class will (likely) become thread-safe.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.UTCTAIHistoryFilesLoader&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.UTCTAIOffset&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Instances are mutable.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.time.UT1Scale&lt;br /&gt;
|not thread-safe&lt;br /&gt;
|Exposed mutable attributes.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.utils.PVCoordinates&lt;br /&gt;
|unconditionally thread-safe&lt;br /&gt;
|Would be immutable if the class were final- documented as immutable, but technically untrue.&lt;br /&gt;
|-&lt;br /&gt;
|fr.cnes.sirius.patrius.wrenches.Wrench.java&lt;br /&gt;
|immutable&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.18_Attitude&amp;diff=4160</id>
		<title>Catégorie:User Manual 4.18 Attitude</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.18_Attitude&amp;diff=4160"/>
		<updated>2026-06-10T09:01:59Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec «  == Introduction == This section describes attitude features of Patrius: attitude laws, slew, guidance, etc.  == Applicable and Reference Documents == === Applicable Documents ===  &amp;#039;&amp;#039;&amp;#039;[A1]&amp;#039;&amp;#039;&amp;#039;      &amp;#039;&amp;#039;CDCF - Fonctions de Base du Patrimoine de Dynamique du Vol&amp;#039;&amp;#039;, V1.2, SIRIUS-CF-DV-0049-CN, 2011.&amp;lt;br&amp;gt; &amp;#039;&amp;#039;&amp;#039;[A2]&amp;#039;&amp;#039;&amp;#039;      &amp;#039;&amp;#039;Dossier de réutilisation Orekit et Commons Math&amp;#039;&amp;#039;, V1.0, SIRIUS-DLR-DV-0080-CN, 2010.  === Reference Documents ===  None applicable.  == Overview ==... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This section describes attitude features of Patrius: attitude laws, slew, guidance, etc.&lt;br /&gt;
&lt;br /&gt;
== Applicable and Reference Documents ==&lt;br /&gt;
=== Applicable Documents ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[A1]&#039;&#039;&#039;      &#039;&#039;CDCF - Fonctions de Base du Patrimoine de Dynamique du Vol&#039;&#039;, V1.2, SIRIUS-CF-DV-0049-CN, 2011.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;[A2]&#039;&#039;&#039;      &#039;&#039;Dossier de réutilisation Orekit et Commons Math&#039;&#039;, V1.0, SIRIUS-DLR-DV-0080-CN, 2010.&lt;br /&gt;
&lt;br /&gt;
=== Reference Documents ===&lt;br /&gt;
&lt;br /&gt;
None applicable.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Attitude package of the PATRIUS library has been developed according to the SIRIUS Scope Statement &#039;&#039;&#039;[A1]&#039;&#039;&#039;. The themes developed are described hereafter :&lt;br /&gt;
&lt;br /&gt;
; Directions&lt;br /&gt;
: Implementation of directions of space that can evolve in time.&lt;br /&gt;
&lt;br /&gt;
; Attitude laws&lt;br /&gt;
: Several attitude laws are available. These laws were originally designed for orbit determination needs: in order to broaden their applications, a wrapper object has been created to meet the spacecraft attitude field needs.&lt;br /&gt;
&lt;br /&gt;
; Attitudes sequence&lt;br /&gt;
: Implementation of an attitudes sequence for orbit determination: it is possible to define an attitude law as a series of attitude laws in the context of a propagation.&lt;br /&gt;
&lt;br /&gt;
; Attitude legs sequence&lt;br /&gt;
: Implementation for spacecraft attitude field of an attitude sequence: it is possible to define an attitude leg as a series of attitude legs.&lt;br /&gt;
&lt;br /&gt;
; Attitude composition&lt;br /&gt;
: Implementation of an object that enables to define an attitude law as a composition of several laws.&lt;br /&gt;
&lt;br /&gt;
; Orientation&lt;br /&gt;
: Orientations are similar to attitude providers except that it returns only one angle.&lt;br /&gt;
&lt;br /&gt;
; Slew&lt;br /&gt;
: Implementation of slew. Slews are used in the attitudes sequence to define the transition between two laws. Slews are splits into two functions: slew computations through dedicated classes and slew realization.&lt;br /&gt;
&lt;br /&gt;
; Kinematics&lt;br /&gt;
: Implementation of a tool box for kinematics calculations.&lt;br /&gt;
&lt;br /&gt;
; Guidance command&lt;br /&gt;
: Implementation of the ground and the on-board guidance commands. The first one is computed, the second one is simulated. In both cases, it should be possible to compute the guidance command from a law and to consider the guidance command itself as a law.&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Slew&amp;diff=4159</id>
		<title>User Manual 4.18 Slew</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Slew&amp;diff=4159"/>
		<updated>2026-06-10T09:01:34Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === A slew performs the transition between two attitude laws.  === Javadoc === The attitude objects linked to slews are available in the package fr.cnes.sirius.patrius.attitudes.  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=&amp;quot;col&amp;quot;| Javadoc |- |Patrius |[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/package-summary.html Package fr.cnes.sirius.patrius.attitudes] |}  === Links === None as of now.  === Useful Docum... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
A slew performs the transition between two attitude laws.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The attitude objects linked to slews are available in the package fr.cnes.sirius.patrius.attitudes.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/package-summary.html Package fr.cnes.sirius.patrius.attitudes]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The slew conception is split into two features:&lt;br /&gt;
* The slew computation. Classes &#039;&#039;computing&#039;&#039; the slew are provided in PATRIUS.&lt;br /&gt;
* The slew realization. All classes realizing a slew implements the &amp;lt;code&amp;gt;Slew&amp;lt;/code&amp;gt; interface. Slews are mainly of two types:&lt;br /&gt;
** Analytical slews (such as &amp;lt;code&amp;gt;ConstantSpinSlew&amp;lt;/code&amp;gt;&lt;br /&gt;
** Pre-computed slews stored in a &amp;lt;code&amp;gt;TabulatedSlew&amp;lt;/code&amp;gt;. In this case, a slew &#039;&#039;computer&#039;&#039; will compute the tabulated ephemeris of the slew.&lt;br /&gt;
&lt;br /&gt;
A slew is bounded in time and as a result inherits the [ATT_LEG_Home AttitudeLeg] interface.&lt;br /&gt;
&lt;br /&gt;
== Features ==&lt;br /&gt;
=== Constant spin slew ===&lt;br /&gt;
The constant spin slew is a basic slew maneuver type. Between the initial quaternion and the final one, a spherical linear interpolation describes the behavior of the spacecraft.&lt;br /&gt;
Two constraint types are available:&lt;br /&gt;
* Duration constraint: spin is computed to match constraint.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final Slew slew = new ConstantSpinSlew(firstAttitude, secondAttitude);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Angular velocity constraint: initial slew date or final slew date is computed to match constraint.&lt;br /&gt;
** Initial slew date is known:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final Slew slew = new ConstantSpinSlewComputer(angularConstraint).compute(pvProvider, initialLaw, initialDate, finalLaw, null);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
** Final slew date is known:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final Slew slew = new ConstantSpinSlewComputer(angularConstraint).compute(pvProvider, initialLaw, null, finalLaw, finalDate);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Spin bias slew ===&lt;br /&gt;
The two spin bias slew is a slew maneuver type. The velocity depends on the value of the slew angle.&lt;br /&gt;
&lt;br /&gt;
In order to compute properly the slew, the user must specify the initial and final laws, the parameters of the two angular velocity fields, plus the stabilisation margin:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final TwoSpinBiasSlewComputer computer = new TwoSpinBiasSlewComputer( &lt;br /&gt;
    step, theta_max, tau, epsInRall, omega2, theta, epsOutRall, omega1, dtStab);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the slew maneuver is defined, the computation can be performed on an orbital state using the following method:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final TabulatedSlew slew = computer.compute(startLaw, initialDate, finalLaw, null);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The slew is then represented by a generic &amp;lt;code&amp;gt;TabulatedSlew&amp;lt;/code&amp;gt; which stores the slew under a tabulated ephemeris.&lt;br /&gt;
&lt;br /&gt;
=== ISIS Spin bias slew ===&lt;br /&gt;
This spin bias slew is a slew with a trapezoidal angular velocity profile:&lt;br /&gt;
- Constant acceleration phase&lt;br /&gt;
- Constant angular velocity phase (zero acceleration phase)&lt;br /&gt;
- Constant decceleration phase&lt;br /&gt;
&lt;br /&gt;
[[File:ISISSpin2.png|center]]&lt;br /&gt;
&lt;br /&gt;
This slew can be computed using methods:&amp;lt;br&amp;gt;&lt;br /&gt;
- &amp;lt;code&amp;gt;IsisSpinBiasSlewComputer.computeAnalytical&amp;lt;/code&amp;gt;: this class provides an analytical solution to the slew&amp;lt;br&amp;gt;&lt;br /&gt;
- &amp;lt;code&amp;gt;IsisSpinBiasSlewComputer.computeNumerical&amp;lt;/code&amp;gt;: this class provides an numerical solution to the slew&lt;br /&gt;
The two classes returns close results ( &amp;lt; 1E-2 rad), though analytical solution is more accurate.&lt;br /&gt;
&lt;br /&gt;
The slews can be used in two ways:&amp;lt;br&amp;gt;&lt;br /&gt;
- Provide an initial law, an initial date and a target final law&amp;lt;br&amp;gt;&lt;br /&gt;
- Provide an final law, a final date and a target initial law&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: slew computed in both ways will never be exactly the same depending on user-chosen convergence threshold and maximum number of iterations (result will be exactly the same if convergence threshold is lower than machine precision and number of allowed iterations high enough to support convergence). In case the maximum number of iterations is reached, the user is prevented by a warning message (if the option &amp;lt;code&amp;gt;throwExceptionOnMaxIterations&amp;lt;/code&amp;gt; is at false).&lt;br /&gt;
&lt;br /&gt;
The slew has then to be calculated using method &amp;lt;code&amp;gt;compute()&amp;lt;/code&amp;gt;.&lt;br /&gt;
The slew is then represented by a generic &amp;lt;code&amp;gt;TabulatedSlew&amp;lt;/code&amp;gt; which stores the slew under a tabulated ephemeris.&lt;br /&gt;
Finally the slew can be used like any other slew.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
{{specialInclusion prefix=$theme_sub section=&amp;quot;GettingStarted&amp;quot;/}}&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AttitudeLeg&#039;&#039;&#039;&lt;br /&gt;
|This interface extends the AttitudeProvider interface and adds the time interval of validity notion to the attitude laws.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/AttitudeLeg.html AttitudeLeg]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Slew&#039;&#039;&#039;&lt;br /&gt;
|This interface implements a generic slew model set.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/Slew.html Slew]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ConstantSpinSlew&#039;&#039;&#039;&lt;br /&gt;
|This class implements the constant spin slew maneuver profile.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/ConstantSpinSlew.html ConstantSpinSlew]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TabulatedSlew&#039;&#039;&#039;&lt;br /&gt;
|This class implements a generic tabulated slew, once computed with one of the computer classes.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/TabulatedSlew.html TabulatedSlew]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AngularVelocitiesPolynomialSlew&#039;&#039;&#039;&lt;br /&gt;
|This class implements a generic angular velocities polynomial slew.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/AngularVelocitiesPolynomialSlew.html AngularVelocitiesPolynomialSlew]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ConstantSpinSlewComputer&#039;&#039;&#039;&lt;br /&gt;
|This class computes a constant spin slew into a ConstantSpinSlew.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/slew/ConstantSpinSlewComputer.html ConstantSpinSlewComputer]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TwoSpinBiasSlewComputer&#039;&#039;&#039;&lt;br /&gt;
|This class computes a two spin bias slew into a TabulatedSlew.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/slew/TwoSpinBiasSlewComputer.html TwoSpinBiasSlewComputer]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IsisSpinBiasSlewComputer&#039;&#039;&#039;&lt;br /&gt;
|This class computes an ISIS spin bias slew into a TabulatedSlew.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/slew/IsisSpinBiasSlewComputer.html IsisSpinBiasSlewComputer]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Rotation,_AngularCoordinates,_Tranform_and_Attitude_:_how_to_use_them&amp;diff=4158</id>
		<title>User Manual 4.18 Rotation, AngularCoordinates, Tranform and Attitude : how to use them</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Rotation,_AngularCoordinates,_Tranform_and_Attitude_:_how_to_use_them&amp;diff=4158"/>
		<updated>2026-06-10T09:01:13Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == In PATRIUS, several objects allow the user to represent rotations and perform some frame transformations, from simplest to most complex: * &amp;lt;code&amp;gt;Rotation&amp;lt;/code&amp;gt;: this class defines a rotation. No frame and date is associated. * &amp;lt;code&amp;gt;AngularCoordinates&amp;lt;/code&amp;gt;: this class defines a rotation, a rotation rate and optionally a rotation acceleration. No frame and date is associated. * &amp;lt;code&amp;gt;Transform&amp;lt;/code&amp;gt;: this class defines angular coo... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
In PATRIUS, several objects allow the user to represent rotations and perform some frame transformations, from simplest to most complex:&lt;br /&gt;
* &amp;lt;code&amp;gt;Rotation&amp;lt;/code&amp;gt;: this class defines a rotation. No frame and date is associated.&lt;br /&gt;
* &amp;lt;code&amp;gt;AngularCoordinates&amp;lt;/code&amp;gt;: this class defines a rotation, a rotation rate and optionally a rotation acceleration. No frame and date is associated.&lt;br /&gt;
* &amp;lt;code&amp;gt;Transform&amp;lt;/code&amp;gt;: this class defines angular coordinates and PV coordinates at a given date.&lt;br /&gt;
* &amp;lt;code&amp;gt;Attitude&amp;lt;/code&amp;gt;: this class defines angular coordinates at a given date with respect to a reference frame.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Rotation ==&lt;br /&gt;
=== Definition ===&lt;br /&gt;
&lt;br /&gt;
A rotation is represented by the object &amp;lt;code&amp;gt;Rotation&amp;lt;/code&amp;gt; (see [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidian/threed/Rotation.html Javadoc]).&lt;br /&gt;
&lt;br /&gt;
A rotation is a transformation that transforms a reference frame (in black) into a frame of interest (in blue). The result is expressed in the reference frame.&lt;br /&gt;
&lt;br /&gt;
[[File:Orientation.png|center]]&lt;br /&gt;
&lt;br /&gt;
The formula giving the transformation are the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\vec{X_{int / ref}} = R(\vec{X_{ref / ref}})&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\vec{Y_{int / ref}} = R(\vec{Y_{ref / ref}})&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\vec{Z_{int / ref}} = R(\vec{Z_{ref / ref}})&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The rotation object is not linked to any frame, so remember, the rotation is can be applied to any set of coordinates as long as it is consistent with how you defined your rotation.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;Rotation&amp;lt;/code&amp;gt; objects can be defined by several manners:&lt;br /&gt;
* Using quaternions (used as internal representation), see [MAT_ROT_Home Quaternions]&lt;br /&gt;
* Using a 3x3 rotation matrix&lt;br /&gt;
* Using an axis and an angle&lt;br /&gt;
* Using Euler angles&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;Rotation&amp;lt;/code&amp;gt; offers several features:&lt;br /&gt;
* Rotate a vector expressed in the reference frame to the frame of interest (= express this vector in the frame of interest): &amp;lt;code&amp;gt;Rotation.applyInverseTo(Vector3D)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Rotate a vector expressed in the frame of interest to the reference frame (= express this vector in the reference frame): &amp;lt;code&amp;gt;Rotation.applyTo(Vector3D)&amp;lt;/code&amp;gt;&lt;br /&gt;
* Compose two rotation: &amp;lt;code&amp;gt;Rotation.applyInverseTo(Rotation)&amp;lt;/code&amp;gt;. R2.applyInverseTo(R1) returns R2^^-1^^ o R1&lt;br /&gt;
* Compose two rotation: &amp;lt;code&amp;gt;Rotation.applyTo(Rotation)&amp;lt;/code&amp;gt;.  R2.applyTo(R1) returns R2 o R1&lt;br /&gt;
* Get Euler angles (given an Euler sequence): &amp;lt;code&amp;gt;Rotation.getAngles()&amp;lt;/code&amp;gt;&lt;br /&gt;
* Get rotation matrix associated to rotation: &amp;lt;code&amp;gt;Rotation.getMatrix()&amp;lt;/code&amp;gt;&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
=== Code examples ===&lt;br /&gt;
&lt;br /&gt;
Let&#039;s consider:&lt;br /&gt;
* A frame F1 [x1, y1, z1]&lt;br /&gt;
* A frame F2 [x2, y2, z2] with x2 = y1, y2 =-x1, z2 = z1&lt;br /&gt;
Then F2 is obtained by a rotation of 90° around z1 of F1&lt;br /&gt;
&lt;br /&gt;
The following code defines the frames F1 and F2 and performs some transformations:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Define the rotation transforming F1 into F2: the axis is [0, 0, 1] and the angle is (Pi / 2)&lt;br /&gt;
final Rotation rotation = new Rotation(Vector3D.PLUS_K, FastMath.PI / 2.);&lt;br /&gt;
// Defines a vector v1 in F1&lt;br /&gt;
final Vector3D v1 = new Vector3D(1., 1., 1.);&lt;br /&gt;
// Express v1 in F2 = v2 = [1,-1, 1]&lt;br /&gt;
final Vector3D v2 = rotation.applyInverseTo(v1);&lt;br /&gt;
// Express v2 in F1 = v3. v3 is then equal to v1&lt;br /&gt;
final Vector3D v3 = rotation.applyTo(v2);&lt;br /&gt;
// Retrieve axis of rotation [0, 0, 1] and angle&lt;br /&gt;
final Vector3D axis = rotation.getAxis();&lt;br /&gt;
final double angle = rotation.getAngle();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Other methods are used in a similar fashion.&lt;br /&gt;
&lt;br /&gt;
== Angular coordinates ==&lt;br /&gt;
=== Definition ===&lt;br /&gt;
&lt;br /&gt;
Angular coordinates are represented by the object &amp;lt;code&amp;gt;AngularCoordinates&amp;lt;/code&amp;gt; (see [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/utils/AngularCoordinates.html Javadoc]).&lt;br /&gt;
Angular coordinates contain:&lt;br /&gt;
* A rotation defined with a &amp;lt;code&amp;gt;Rotation&amp;lt;/code&amp;gt; object (see above)&lt;br /&gt;
* A rotation rate defined with a &amp;lt;code&amp;gt;Vector3D&amp;lt;/code&amp;gt; object.&lt;br /&gt;
* A rotation rate derivative (or rotation acceleration) defined with a &amp;lt;code&amp;gt;Vector3D&amp;lt;/code&amp;gt; object.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The convention used to describe the orientation of the frame of interest in &amp;lt;code&amp;gt;AngularCoordinates&amp;lt;/code&amp;gt; is the same used in &amp;lt;code&amp;gt;Rotation&amp;lt;/code&amp;gt;&#039;&#039;&#039;: the rotation represents the transformation from a reference frame to a frame of interest, expressed in reference frame. However &amp;lt;code&amp;gt;AngularCoordinates.applyTo()&amp;lt;/code&amp;gt; returns the opposite of &amp;lt;code&amp;gt;Rotation.applyTo()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Orientation&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The orientation is described by a rotation (see above).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rotation Rate&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The Rotation Rate is a 3D vector expressed&#039;&#039;&#039;in the frame of interest&#039;&#039;&#039;.&lt;br /&gt;
Its norm is the angular velocity of the frame of interest. Its direction is the instant axis of spin.&lt;br /&gt;
Here is the case of a spin around the Z axis :&lt;br /&gt;
&lt;br /&gt;
[[File:rotationRate.png|center]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Rotation Acceleration&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The Rotation Acceleration is a 3D vector expressed&#039;&#039;&#039;in the frame of interest&#039;&#039;&#039;.&lt;br /&gt;
Its norm is the angular acceleration of the frame of interest. As the rotation rate, its direction is the instant axis of spin (see image above).&lt;br /&gt;
&lt;br /&gt;
This computation is optional. All methods are doubled:&lt;br /&gt;
* One provides computation without rotation rate derivative.&lt;br /&gt;
* One provides computation with or without rotation rate derivative (a boolean is provided):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
AngularCoordinates(final PVCoordinates u1, final PVCoordinates u2,&lt;br /&gt;
                   final PVCoordinates v1, final PVCoordinates v2,&lt;br /&gt;
                   final double tolerance, final boolean spinDerivativesComputation)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Don&#039;t compute spin derivative if you don&#039;t need to since it is time consuming.&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;AngularCoordinates&amp;lt;/code&amp;gt; class offers several features:&lt;br /&gt;
* Rotate a vector expressed in the reference frame to the frame of interest (= express this vector in the frame of interest): &amp;lt;code&amp;gt;AngularCoordinates.applyTo()&amp;lt;/code&amp;gt;. Warning: this is opposite from &amp;lt;code&amp;gt;Rotation.applyTo()&amp;lt;/code&amp;gt;!&lt;br /&gt;
* Given a time shift, shift internal rotation using rotation rate and derivative if provided: &amp;lt;code&amp;gt;AngularCoordinates.shiftedBy()&amp;lt;/code&amp;gt;&lt;br /&gt;
* Internal rotation as a &amp;lt;code&amp;gt;Rotation&amp;lt;/code&amp;gt; object can be retrieved and methods shown in the Rotation section are available. Retrieved rotation has the same convention as Rotation class.&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
=== Code examples ===&lt;br /&gt;
&lt;br /&gt;
Here is an examples of how to time-shift a rotation using the rotation rate. This example involves different frames and helps understand them.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Get the content of angular coordinates&lt;br /&gt;
// Rotation represent a transformation from a reference frame F1 to a frame of interest F2, expressed in F1&lt;br /&gt;
// Rotation acceleration and rotation rate are expressed in frame of interest F2&lt;br /&gt;
Vector3D rotation_acceleration = angularCoordinates.getRotationAcceleration()&lt;br /&gt;
Vector3D rotation_rate = angularCoordinates.getRotationRate();&lt;br /&gt;
Rotation orientation = angularCoordinates.getRotation();&lt;br /&gt;
&lt;br /&gt;
// To compose two rotations, they must be expressed in the same frame (here F1).&lt;br /&gt;
// The orientation is expressed in the reference frame F1, so the shift (evolution of the rotation) has to be expressed in the reference frame F1 too. &lt;br /&gt;
// To create it, the rotation rate has itself to be expressed in the reference frame F1.&lt;br /&gt;
&lt;br /&gt;
// Get rotation rate which is expressed in F2 in reference frame F1&lt;br /&gt;
Vector3D rotation_rate_in_ref_frame = orientation.applyTo(rotation_rate);&lt;br /&gt;
&lt;br /&gt;
// The rotation shift can then be created (&amp;quot;dt&amp;quot; is the time duration of the shift). This rotation shift is expressed in F1&lt;br /&gt;
Rotation shift = new Rotation(rotation_rate_in_ref_frame, rotation_rate_in_ref_frame.getNorm()* dt);&lt;br /&gt;
&lt;br /&gt;
// The time-shifted orientation can finally be computed: this rotation represents the transformation from the reference frame F1 to a frame of interest F3 which is shifted from F2.&lt;br /&gt;
Rotation finalRotation = shift.applyTo(orientation);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For information, the shifted rotation can be directly retrieved using the method &amp;lt;code&amp;gt;shyftedBy()&amp;lt;/code&amp;gt; of &amp;lt;code&amp;gt;AngularCoordinates&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
AngularCoordinates shifted = angularCoordinates.shiftedBy(dt);&lt;br /&gt;
Rotation shiftedRotation = shifted.getRotation();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Transform ==&lt;br /&gt;
&lt;br /&gt;
[[File:rotationRate.png|center]]&lt;br /&gt;
&lt;br /&gt;
=== Definition ===&lt;br /&gt;
&lt;br /&gt;
Transform are represented by the object &amp;lt;code&amp;gt;Transform&amp;lt;/code&amp;gt; (see [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/transformations/Transform.html Javadoc]).&lt;br /&gt;
A Transform object contains:&lt;br /&gt;
* A date of the transformation&lt;br /&gt;
* A position, velocity, acceleration (optional)&lt;br /&gt;
* A rotation, rotation rate, rotation rate derivative (optional)&lt;br /&gt;
of a &amp;quot;destination&amp;quot; frame (or frame of interest) in an &amp;quot;origin&amp;quot; frame (or reference frame).&lt;br /&gt;
&lt;br /&gt;
[[File:transform.png|center]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The convention used to describe the orientation and rotation rate of the &amp;quot;destination&amp;quot; frame in Transform is the same as in Rotation and AngularCoordinates&#039;&#039;&#039; : the rotation returned by &amp;lt;code&amp;gt;Transform.getRotation()&amp;lt;/code&amp;gt; is the one that transforms the basis vectors of the &amp;quot;origin&amp;quot; frame into the ones of the &amp;quot;destination&amp;quot; frame.&lt;br /&gt;
&lt;br /&gt;
The position and velocity of the &amp;quot;destination&amp;quot; are expressed in the &amp;quot;origin&amp;quot; frame. &lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;Transform&amp;lt;/code&amp;gt; class offers several features:&lt;br /&gt;
* Transform a vector expressed in origin frame in destination frame: &amp;lt;code&amp;gt;Transform.transformVector()&amp;lt;/code&amp;gt;&lt;br /&gt;
* Transform a PVCoordinates expressed in origin frame in destination frame: &amp;lt;code&amp;gt;Transform.transformPVCoordinates()&amp;lt;/code&amp;gt;&lt;br /&gt;
* Retrieve jacobian of transformation: &amp;lt;code&amp;gt;Transform.getJacobian()&amp;lt;/code&amp;gt;&lt;br /&gt;
* Internal rotation as a &amp;lt;code&amp;gt;Rotation&amp;lt;/code&amp;gt; object (as well as rotation rate, etc.) can be retrieved and methods shown in the Rotation section are available. Retrieved rotation has the same convention as Rotation class. Other attributes (rotation rate, etc.) have the same convention as AngularCoordinates class.&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
=== Code examples ===&lt;br /&gt;
&lt;br /&gt;
In the following example, the &amp;quot;origin&amp;quot; is a TNW local orbital frame and the &amp;quot;destination&amp;quot; is the GCRF inertial frame.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Build transform from TNW local orbital frame to GCRF&lt;br /&gt;
final Frame lof = new LocalOrbitalFrame(FramesFactory.getGCRF(), LOFType.TNW, orbit, &amp;quot;TNW&amp;quot;);&lt;br /&gt;
final Frame gcrf = FramesFactory.getGCRF();&lt;br /&gt;
final Transform transform = lof.getTransformTo(gcrf, AbsoluteDate.J2000_EPOCH);&lt;br /&gt;
// Define a vector v = [1, 0, 0] in TNW frame&lt;br /&gt;
final Vector3D v_TNW = Vector3D.PLUS_I;&lt;br /&gt;
// Get v in GCRF frame&lt;br /&gt;
final Vector3D v_GCRF = transform.transformVector(v_TNW);&lt;br /&gt;
// Get v back in TNW&lt;br /&gt;
final Vector3D v_TNW2 = transform.getInverse().transformVector(v_GCRF);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Attitude ==&lt;br /&gt;
=== Definition ===&lt;br /&gt;
&lt;br /&gt;
An attitude object contains all information about the satellite&#039;s orientation at a date.&lt;br /&gt;
&lt;br /&gt;
Attitudes are represented by the object &amp;lt;code&amp;gt;Attitude&amp;lt;/code&amp;gt; (see [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/Attitude.html Javadoc]).&lt;br /&gt;
Attitude contain:&lt;br /&gt;
* Angular coordinates.&lt;br /&gt;
* A date.&lt;br /&gt;
* A reference frame.&lt;br /&gt;
Attitude object contains information to rotate the reference frame to a frame of interest (often the satellite frame), expressed in the reference frame.&lt;br /&gt;
For example, attitude laws via the method getAttitude(Frame, etc.) will return the Attitude in provided frame, the attitude being the transformation from provided frame to satellite platform frame).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The convention used to describe the orientation of the frame of interest in &amp;lt;code&amp;gt;Attitude&amp;lt;/code&amp;gt; is the same used in &amp;lt;code&amp;gt;AngularCoordinates&amp;lt;/code&amp;gt;&#039;&#039;&#039;: the rotation represents the transformation from a reference frame to a frame of interest, expressed in reference frame. &lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;Attitude&amp;lt;/code&amp;gt; class offers several features:&lt;br /&gt;
* Change the attitude reference frame: &amp;lt;code&amp;gt;Attitude.withReferenceFrame()&amp;lt;/code&amp;gt;&lt;br /&gt;
* Internal rotation as a &amp;lt;code&amp;gt;Rotation&amp;lt;/code&amp;gt; object (as well as rotation rate, etc.) can be retrieved and methods shown in the Rotation section are available. Retrieved rotation has the same convention as Rotation class. Other attributes (rotation rate, etc.) have the same convention as AngularCoordinates class.&lt;br /&gt;
* Perform interpolation: &amp;lt;code&amp;gt;Attitude.interpolate()&amp;lt;/code&amp;gt;&lt;br /&gt;
* etc.&lt;br /&gt;
&lt;br /&gt;
=== Code examples ===&lt;br /&gt;
&lt;br /&gt;
This example creates an attitude from a reference frame GCRF to the satellite frame, change the reference frame to CIRF and then rotate a vector.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // Define attitude from BodyCenterPointing attitude law, expressed in GCRF frame&lt;br /&gt;
        final AttitudeLaw attitudeLaw = new BodyCenterPointing();&lt;br /&gt;
        final Frame gcrf = FramesFactory.getGCRF();&lt;br /&gt;
        final Attitude attitude_GCRF = attitudeLaw.getAttitude(orbit, AbsoluteDate.J2000_EPOCH, gcrf);&lt;br /&gt;
        // Change attitude reference frame to CIRF&lt;br /&gt;
        final Frame cirf = FramesFactory.getCIRF();&lt;br /&gt;
        final Attitude attitude_CIRF = attitude_GCRF.withReferenceFrame(cirf);&lt;br /&gt;
        &lt;br /&gt;
        // Define a vector v = [1, 0, 0] in satellite frame&lt;br /&gt;
        final Vector3D v_Sat = Vector3D.PLUS_I;&lt;br /&gt;
        // Get attitude rotation (from reference frame = CIRF to frame of interest = satellite frame)&lt;br /&gt;
        final Rotation rotation = attitude_CIRF.getRotation();&lt;br /&gt;
        // Get v in CIRF frame&lt;br /&gt;
        final Vector3D v_CIRF = rotation.applyInverseTo(v_Sat);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==More code examples==&lt;br /&gt;
Here is an example of code that may help understanding the use of rotations in attitudes and frames transformations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// GCRF, reference frame&lt;br /&gt;
final Frame gcrf = FramesFactory.getGCRF();&lt;br /&gt;
&lt;br /&gt;
// Axis of the GCRF frame, expressed in GCRF&lt;br /&gt;
final Vector3D xGCRF_inGCRF = Vector3D.PLUS_I;&lt;br /&gt;
final Vector3D yGCRF_inGCRF = Vector3D.PLUS_J;&lt;br /&gt;
final Vector3D zGCRF_inGCRF = Vector3D.PLUS_K;&lt;br /&gt;
&lt;br /&gt;
// Directions associated to those axis&lt;br /&gt;
final IDirection xGCRF = new ConstantVectorDirection(xGCRF_inGCRF, gcrf);&lt;br /&gt;
final IDirection yGCRF = new ConstantVectorDirection(yGCRF_inGCRF, gcrf);&lt;br /&gt;
final IDirection zGCRF = new ConstantVectorDirection(zGCRF_inGCRF, gcrf);&lt;br /&gt;
&lt;br /&gt;
// Creation of a &amp;quot;zero&amp;quot; PV provider&lt;br /&gt;
final PVCoordinatesProvider pvProv = new PVCoordinatesProvider() {&lt;br /&gt;
public PVCoordinates getPVCoordinates(AbsoluteDate date, Frame frame)&lt;br /&gt;
throws PatriusException {&lt;br /&gt;
return new PVCoordinates(Vector3D.ZERO, Vector3D.ZERO);&lt;br /&gt;
}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// a date...&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2014, 10, 2, 11, 46, 00,&lt;br /&gt;
TimeScalesFactory.getTAI());&lt;br /&gt;
&lt;br /&gt;
// Axis of the satellite frame, expressed in the satellite frame&lt;br /&gt;
final Vector3D xSat_inRSat = Vector3D.PLUS_I;&lt;br /&gt;
final Vector3D ySat_inRSat = Vector3D.PLUS_J;&lt;br /&gt;
final Vector3D zSat_inRSat = Vector3D.PLUS_K;&lt;br /&gt;
&lt;br /&gt;
// The attitude law :&lt;br /&gt;
//- axe Xsat on Y_GCRF,&lt;br /&gt;
//- axe Ysat &amp;quot;as close as possible&amp;quot; to Z_GCRF.&lt;br /&gt;
// We are implicitly defining the orientation of the satellite frame.&lt;br /&gt;
final TwoDirectionAttitudeLaw attLaw = new TwoDirectionAttitudeLaw(yGCRF, zGCRF, xSat_inRSat, ySat_inRSat);&lt;br /&gt;
&lt;br /&gt;
// Attitude computation,&lt;br /&gt;
// and getting of the associated rotation.&lt;br /&gt;
Attitude att = attLaw.getAttitude(pvProv, date, gcrf);&lt;br /&gt;
Rotation rot = att.getRotation ();&lt;br /&gt;
&lt;br /&gt;
// Computation of the axis of the satellite frame in the GCRF&lt;br /&gt;
Vector3D xSat_inGCRF = rot.applyTo(xGCRF_inGCRF);&lt;br /&gt;
Vector3D ySat_inGCRF = rot.applyTo(yGCRF_inGCRF);&lt;br /&gt;
Vector3D zSat_inGCRF = rot.applyTo(zGCRF_inGCRF);&lt;br /&gt;
&lt;br /&gt;
// Print&lt;br /&gt;
System.out.println(&amp;quot;xSat_inGCRF: &amp;quot; + xSat_inGCRF);&lt;br /&gt;
System.out.println(&amp;quot;ySat_inGCRF: &amp;quot; + ySat_inGCRF);&lt;br /&gt;
System.out.println(&amp;quot;zSat_inGCRF: &amp;quot; + zSat_inGCRF);&lt;br /&gt;
&lt;br /&gt;
// getting the attitude quaternion&lt;br /&gt;
Quaternion q = rot.getQuaternion ();&lt;br /&gt;
System.out.println(&amp;quot;quaternion: &amp;quot; + q);&lt;br /&gt;
&lt;br /&gt;
// Printing the axis and angle of the rotation,&lt;br /&gt;
// to visualize its &amp;quot;right&amp;quot; definition.&lt;br /&gt;
System.out.println(&amp;quot; axis: &amp;quot; + rot.getAxis());&lt;br /&gt;
System.out.println(&amp;quot; angle: &amp;quot; + rot.getAngle());&lt;br /&gt;
&lt;br /&gt;
// Creation of the satellite frame&lt;br /&gt;
AttitudeFrame attFrame = new AttitudeFrame(pvProv, attLaw, gcrf);&lt;br /&gt;
&lt;br /&gt;
// getting the transformation from the satellite frame to the GCRF&lt;br /&gt;
Transform transform = attFrame.getTransformTo(gcrf, date);&lt;br /&gt;
&lt;br /&gt;
// Changing the expression frame of Xsat from Rsat into GCRF&lt;br /&gt;
// to match the previous result :&lt;br /&gt;
System.out.println(&amp;quot;xSat_inGCRF: &amp;quot; + xSat_inGCRF);&lt;br /&gt;
System.out.println(&amp;quot;transform.transformVector(xSat_inRSat): &amp;quot; +&lt;br /&gt;
transform.transformVector(xSat_inRSat));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Orientation&amp;diff=4157</id>
		<title>User Manual 4.18 Orientation</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Orientation&amp;diff=4157"/>
		<updated>2026-06-10T09:00:49Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === The purpose of this chapter is to describe the orientation package.  An orientation provider is an interface that provides methods to return an angle as a function of a spacecraft state.  === Javadoc === {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=&amp;quot;col&amp;quot;| Javadoc |- |Patrius |[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/orientations/package-summary.html Package fr.cnes.sirius.patrius.attitudes.orientation... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The purpose of this chapter is to describe the orientation package.&lt;br /&gt;
&lt;br /&gt;
An orientation provider is an interface that provides methods to return an angle as a function of a spacecraft state.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/orientations/package-summary.html Package fr.cnes.sirius.patrius.attitudes.orientations]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
The orientations package is designed similarly to attitude providers:&lt;br /&gt;
* An interface &amp;lt;code&amp;gt;OrientationAngleProvider&amp;lt;/code&amp;gt; returns an angle given a spacecraft state (similarly to  &amp;lt;code&amp;gt;AttitudeProvider&amp;lt;/code&amp;gt; which returns an Attitude)&lt;br /&gt;
* An interface &amp;lt;code&amp;gt;OrientationAngleLaw&amp;lt;/code&amp;gt; gathers orientation laws and is similar to &amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt;&lt;br /&gt;
* An interface &amp;lt;code&amp;gt;OrientationAngleLeg&amp;lt;/code&amp;gt; is a time-bounded leg and is similar to &amp;lt;code&amp;gt;AttitudeLeg&amp;lt;/code&amp;gt;&lt;br /&gt;
* An interface &amp;lt;code&amp;gt;OrientationAngleProfile&amp;lt;/code&amp;gt; is a profile of orientation angles and is similar to &amp;lt;code&amp;gt;AttitudeProfile&amp;lt;/code&amp;gt;&lt;br /&gt;
* A class &amp;lt;code&amp;gt;OrientationAngleLawLeg&amp;lt;/code&amp;gt; is a law leg and is similar to &amp;lt;code&amp;gt;AttitudeLawLeg&amp;lt;/code&amp;gt;&lt;br /&gt;
* A class &amp;lt;code&amp;gt;OrientationAngleLawLegsSequence&amp;lt;/code&amp;gt; is a sequence of &amp;lt;code&amp;gt;OrientationAngleLawLeg&amp;lt;/code&amp;gt; and is similar to &amp;lt;code&amp;gt;AttitudeLawLegsSequence&amp;lt;/code&amp;gt;&lt;br /&gt;
* A class &amp;lt;code&amp;gt;OrientationAngleProfileSequence&amp;lt;/code&amp;gt; is a sequence of &amp;lt;code&amp;gt;OrientationAngleProfile&amp;lt;/code&amp;gt; and is similar to &amp;lt;code&amp;gt;AttitudeProfileSequence&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: the package currently does not provide any implementation of &amp;lt;code&amp;gt;OrientationAngleProvider&amp;lt;/code&amp;gt; interface except for constant angles.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
Use is identical to attitudes. See the [[Catégorie:User Manual 4.4 Attitude|Attitude]] page for examples.&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OrientationAngleProvider&#039;&#039;&#039;&lt;br /&gt;
|Interface for all orientation angles providers.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/orientations/OrientationAngleProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OrientationAngleLaw&#039;&#039;&#039;&lt;br /&gt;
|Interface for all orientation angles lasw.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/orientations/OrientationAngleLaw.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OrientationAngleLeg&#039;&#039;&#039;&lt;br /&gt;
|Interface for all orientation angles legs.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/orientations/OrientationAngleLeg.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OrientationAngleProfile&#039;&#039;&#039;&lt;br /&gt;
|Interface for all orientation angles profiles.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/orientations/OrientationAngleProfile.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OrientationAngleLawLeg&#039;&#039;&#039;&lt;br /&gt;
|Orientation angle law leg.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/OrientationAngleLawLeg.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OrientationAngleLawLegsSequence&#039;&#039;&#039;&lt;br /&gt;
|Sequence of Orientation angle legs.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/OrientationAngleLawLegsSequence.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OrientationAngleProfileSequence&#039;&#039;&#039;&lt;br /&gt;
|Sequence of Orientation angle profiles.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/OrientationAngleProfileSequence.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Kinematics&amp;diff=4156</id>
		<title>User Manual 4.18 Kinematics</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Kinematics&amp;diff=4156"/>
		<updated>2026-06-10T09:00:24Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === The purpose is to extend the attitude package with classes and methods to compute and process kinematics operations.  === Javadoc === The kinematics objects are available in the package fr.cnes.sirius.patrius.attitudes.kinematics.  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=&amp;quot;col&amp;quot;| Javadoc |- |Orekit |[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/kinematics/package-summary.html Package fr.cnes.sirius.patr... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The purpose is to extend the attitude package with classes and methods to compute and process kinematics operations.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The kinematics objects are available in the package fr.cnes.sirius.patrius.attitudes.kinematics.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Orekit&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/kinematics/package-summary.html Package fr.cnes.sirius.patrius.attitudes.kinematics]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The following diagram represents the main classes of the package : &lt;br /&gt;
&amp;lt;code&amp;gt;fr.cnes.sirius.patrius.attitudes.kinematics&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Please note that not all implementations are present in the following diagram for the sake of clarity.&lt;br /&gt;
&lt;br /&gt;
[[File:kinematics.png|center]]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Quaternions differentiation ===&lt;br /&gt;
A quaternion can be differentiated using various methods:&lt;br /&gt;
&lt;br /&gt;
* The quaternion differentiation’s formula &amp;lt;math&amp;gt;\dot{Q}_{S/R} = \frac{1}{2}Q_{S/R}\Omega_{S/R}^{[S]}&amp;lt;/math&amp;gt;.&lt;br /&gt;
This formula connects time derivative of the quaternion q(t) with the vector of angular velocity W(t).&lt;br /&gt;
&lt;br /&gt;
* When the quaternion is represented by a set of differentiable functions (Fourier series or polynomials), a direct analytic computation can be performed to get its derivative;&lt;br /&gt;
&lt;br /&gt;
* Numerical differentiation (using finite difference, Ridders differentiation method, ...)&lt;br /&gt;
&lt;br /&gt;
=== Quaternion integration ===&lt;br /&gt;
A rotation can be integrated, knowing its spin time function, using these methods:&lt;br /&gt;
* Wilcox method, with available approximations orders 1 to 4&lt;br /&gt;
* Edwards method, that corresponds to an order 3 approximation&lt;br /&gt;
&lt;br /&gt;
=== Spin computation ===&lt;br /&gt;
The spin can be represented by a vector (instantaneous spin), or by a time-dependent function. &lt;br /&gt;
The computation of the instantanous value of the spin can be made by one of the following methods:&lt;br /&gt;
&lt;br /&gt;
* estimate the spin from two rotations corresponding to two different dates;&lt;br /&gt;
* using the kinematics equation when a quaternion and its derivative are known;&lt;br /&gt;
* compute the spin from the Euler or Cardan angles and their derivatives;&lt;br /&gt;
* using a direct analytic computation (when the function representing its variation over time is available).&lt;br /&gt;
&lt;br /&gt;
=== Time-dependent orientation function===&lt;br /&gt;
The interface &amp;lt;code&amp;gt;OrientationFunction&amp;lt;/code&amp;gt; and the abstract class &amp;lt;code&amp;gt;AbstractOrientationFunction&amp;lt;/code&amp;gt; have been added to the kinematics package in order to represent a time-dependent orientation function.&lt;br /&gt;
&lt;br /&gt;
These classes provide the following functionalities:&lt;br /&gt;
&lt;br /&gt;
* return the orientation at a date, by the &amp;lt;code&amp;gt;getOrientation(AbsoluteDate)&amp;lt;/code&amp;gt; method; it is an abstract method because it is specific to the orientation (or attitude) law the user wants to implement;&lt;br /&gt;
&lt;br /&gt;
* return the function representing the derivative of the quaternion components, by the &amp;lt;code&amp;gt;derivative()&amp;lt;/code&amp;gt; method. A numerical differentiation method is used to compute the derivatives, nevertheless the classes inheriting the &amp;lt;code&amp;gt;AbstractOrientationFunction&amp;lt;/code&amp;gt; can override this method and return the analytical function representing the derivatives, when possible.&lt;br /&gt;
&lt;br /&gt;
* compute the function representing the spin using the &amp;lt;math&amp;gt;\Omega_{S/R}^{[S]} = 2Q_{S/R}\dot{Q}_{S/R}&amp;lt;/math&amp;gt; formula, by the &amp;lt;code&amp;gt;computeSpinFunction()&amp;lt;/code&amp;gt; method. The derivatives of the quaternion are computed thanks to the &amp;lt;code&amp;gt;derivative()&amp;lt;/code&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
* estimate the function representing the spin using two rotations corresponding to two different dates (the velocity is supposed to be constant during the time interval between the two rotations), by the &amp;lt;code&amp;gt;estimateRateFunction(dt)&amp;lt;/code&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
* return the spin at a date, by the &amp;lt;code&amp;gt;computeSpin(AbsoluteDate)&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;estimateRate(AbsoluteDate, dt)&amp;lt;/code&amp;gt; methods (they call the &amp;lt;code&amp;gt;computeSpinFunction()&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;estimateRateFunction(dt)&amp;lt;/code&amp;gt; methods)&lt;br /&gt;
&lt;br /&gt;
=== Time-dependent spin function===&lt;br /&gt;
The interface &amp;lt;code&amp;gt;Vector3DFunction&amp;lt;/code&amp;gt; and the abstract class &amp;lt;code&amp;gt;AbstractVector3DFunction&amp;lt;/code&amp;gt; have been added to the kinematics package in order to represent a time-dependent vector 3D function; a vector 3D function is used to represent the spin, or the n-th derivative of the spin.&lt;br /&gt;
&lt;br /&gt;
These classes provide the following functionalities:&lt;br /&gt;
&lt;br /&gt;
* return the vector at a date, by the &amp;lt;code&amp;gt;getVector3D(AbsoluteDate)&amp;lt;/code&amp;gt; method; it is an abstract method because it is specific to the spin (or derivative of the spin) the user wants to implement;&lt;br /&gt;
&lt;br /&gt;
* return the function representing the n-th derivative of the vector, by the &amp;lt;code&amp;gt;nthDerivative(order)&amp;lt;/code&amp;gt; method. A numerical differentiation method is used to compute the derivatives, nevertheless the classes inheriting the &amp;lt;code&amp;gt;AbstractVector3DFunction&amp;lt;/code&amp;gt; can override this method and return the analytical function representing the derivatives, when possible. &lt;br /&gt;
This method uses the classes contained in the differentiation package, in particular the &amp;lt;code&amp;gt;DerivativeStructure&amp;lt;/code&amp;gt; class, which allows to compute the n-th derivatives of a function at a point;&lt;br /&gt;
&lt;br /&gt;
* return the integral of the function by the &amp;lt;code&amp;gt;integral(x0, xf)&amp;lt;/code&amp;gt; method. A numerical integration method is used to compute the integral, nevertheless the classes inheriting the &amp;lt;code&amp;gt;AbstractVector3DFunction&amp;lt;/code&amp;gt; can override this method and return the analytical function representing the integral, when possible.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;DynamicsElements&amp;lt;/code&amp;gt; object is created from a spin function and it gathers the n-th derivatives of spin at a given date; an attribute of this class is contained in the &amp;lt;code&amp;gt;Attitude&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
=== Differentiate a quaternion ===&lt;br /&gt;
As a time-dependent quaternion can be represented by the &amp;lt;code&amp;gt;OrientationFunction&amp;lt;/code&amp;gt; interface, the derivative of the quaternion can be computed using the &amp;lt;code&amp;gt;derivative()&amp;lt;/code&amp;gt; method. As this method is implemented by the user, he can choose to use a numerical differentiation method or to compute the exact derivative, when possible. &lt;br /&gt;
&lt;br /&gt;
The derivative of a quaternion can be also computed using the kinematics equation: &amp;lt;math&amp;gt;\dot{Q}_{S/R} = \frac{1}{2}Q_{S/R}\Omega_{S/R}^{[S]}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
This equation is implemented by the following method in the kinematics toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public static Quaternion differentiateQuaternion(final Quaternion q, final Vector3D spin)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Integrate a quaternion ===&lt;br /&gt;
The rotation integration is to be made by the class &amp;lt;code&amp;gt;AngularVelocitiesPolynomialProfileLeg&amp;lt;/code&amp;gt;. This class requires to provide the integration method (Wilcox  up to order 4 or Edwards) as well as the angular rate on each component.&lt;br /&gt;
&lt;br /&gt;
=== Differentiate and integrate a vector ===&lt;br /&gt;
In a similar way to the orientation function, a new class has been added in order to represent a time-dependent 3-D vector function. This class implements the &amp;lt;code&amp;gt;Vector3DFunction&amp;lt;/code&amp;gt; interface, and it contains the methods to compute the derivative of the vector or its integral over a time period. The computation can be done using a numerical method or it can be analytical, when possible.&lt;br /&gt;
&lt;br /&gt;
=== Compute the spin ===&lt;br /&gt;
The Kinematics package contains some methods aiming to compute the instantaneous spin. These methods are listed hereafter:&lt;br /&gt;
&lt;br /&gt;
* Estimation: two rotations corresponding to two different dates are used to compute the spin (the velocity is supposed to be constant during the time interval between the two rotations).&lt;br /&gt;
This function is implemented by the following method in the kinematics toolkit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public static Vector3D estimateSpin(final Rotation start, final Rotation end, final double dt)&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\Omega_{S/R}^{[S]} = 2Q_{S/R}\dot{Q}_{S/R}&amp;lt;/math&amp;gt;, when knowing the derivative of the quaternion.&lt;br /&gt;
This equation is implemented by the following kinematics toolkit method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public static Vector3D computeSpin(final Quaternion q, final Quaternion qd)&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Using the derivative of the Euler or Cardan angles:&lt;br /&gt;
** Euler (not to be used when the angles are small):  &lt;br /&gt;
&amp;lt;math&amp;gt;\Omega_{S/R}^{[S]} = \left[ \begin{array}{c} \dot{\psi}\sin(\theta)\sin(\phi) + \dot{\theta}\cos(\phi) \\ \dot{\psi}\sin(\theta)\cos(\phi)- \dot{\theta}\sin(\phi) \\ \dot{\psi}\cos(\theta) + \dot{\phi} \end{array} \right]&amp;lt;/math&amp;gt;&lt;br /&gt;
** Cardan (only to be used when the angles are small):&lt;br /&gt;
&amp;lt;math&amp;gt;\Omega_{S/R}^{[S]} = \left[ \begin{array}{c}-\dot{\psi}\sin(\theta)+\dot{\phi} \\ \dot{\psi}\cos(\theta)\sin(\phi) + \dot{\theta}\cos(\phi) \\ \dot{\psi}\cos(\theta)\cos(\phi) - \dot{\theta}\sin(\phi) \end{array} \right]&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These formula are implemented by the following kinematics toolkit method:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public static Vector3D computeSpin(final double[] ang, final double[] angd, final RotationOrder order)&amp;lt;/syntaxhighlight&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Analytic computation: if the spin is represented by a function, its instantaneous value must be obtained by direct analytic computation (the &amp;lt;code&amp;gt;IVector3DFunction&amp;lt;/code&amp;gt; classes have been created for this purpose)&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OrientationFunction&#039;&#039;&#039;&lt;br /&gt;
|This interface represents a generic univariate orientation function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/kinematics/OrientationFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Vector3DFunction&#039;&#039;&#039;&lt;br /&gt;
|This interface represents a generic univariate 3-D vector function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/kinematics/Vector3DFunction.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbstractOrientationFunction&#039;&#039;&#039;&lt;br /&gt;
|This class represents an orientation function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/kinematics/AbstractOrientationFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbstractVector3DFunction&#039;&#039;&#039;&lt;br /&gt;
|This class represents a spin function, or a spin n-th derivative function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/kinematics/AbstractVector3DFunction.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Directions&amp;diff=4155</id>
		<title>User Manual 4.18 Directions</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Directions&amp;diff=4155"/>
		<updated>2026-06-10T09:00:01Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__ == Introduction == === Scope === The “direction” objects are used for attitude computation purposes to describe different types of axis in space that can evolve in time. A direction provides a vector in space at any date in a given frame. A direction can be for example &amp;quot;spacecraft-moon&amp;quot; or &amp;quot;nadir direction of the spacecraft&amp;quot;. An attitude law can then be defined using two of those directions.  All available directions belong to the following categori... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The “direction” objects are used for attitude computation purposes to describe different types of axis in space that can evolve in time. A direction provides a vector in space at any date in a given frame.&lt;br /&gt;
A direction can be for example &amp;quot;spacecraft-moon&amp;quot; or &amp;quot;nadir direction of the spacecraft&amp;quot;.&lt;br /&gt;
An attitude law can then be defined using two of those directions.&lt;br /&gt;
&lt;br /&gt;
All available directions belong to the following categories:&lt;br /&gt;
* Defined by a &amp;quot;target&amp;quot; moving point, and a given origin point;&lt;br /&gt;
&lt;br /&gt;
* Defined by a vector only known to be constant in time in a particular frame, or defined by a physical property.&lt;br /&gt;
&lt;br /&gt;
The available features are listed in the description of the general &amp;lt;code&amp;gt;IDirection&amp;lt;/code&amp;gt; interface or of the more specific &amp;lt;code&amp;gt;ITargetDirection&amp;lt;/code&amp;gt; interface (for directions pointing a target).&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The directions are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.attitudes.directions&amp;lt;/code&amp;gt; of the PATRIUS library.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/package-summary.html Package fr.cnes.sirius.patrius.attitudes.directions]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The following diagram represents the two main interfaces of the &amp;quot;directions&amp;quot; package, and for each interface some of the implemented directions.&lt;br /&gt;
&lt;br /&gt;
Please note that not all implementations are present in the following diagram for the sake of clarity.&lt;br /&gt;
&lt;br /&gt;
[[File:PATRIMOINESIRIUSdirections.png]]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Directions ===&lt;br /&gt;
The available directions are:&lt;br /&gt;
&lt;br /&gt;
==== Basic direction ====&lt;br /&gt;
This direction is defined at any date by a vector; this vector can be constant in a frame, or it can be defined by a physical property (for instance the axis of the poles of a celestial body, the orbit momentum, the velocity vector...).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;getVector&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;getLine&amp;lt;/code&amp;gt; methods of this interface use a &amp;lt;code&amp;gt;PVCoordinatesProvider&amp;lt;/code&amp;gt; to represent the origin of the direction, but for some of them this input parameter is unused (for instance for the poles of a celestial body direction). See each javadoc for the associated behavior.&lt;br /&gt;
&lt;br /&gt;
All directions can also provide the line containing the given origin and directed by the vector, expressed in any frame of the tree.&lt;br /&gt;
&lt;br /&gt;
===== Ground velocity direction =====&lt;br /&gt;
This direction is used for instance when it comes to take pictures of the ground. To avoid distortion, the satellite has to compensate the earth rotation around its yaw axis. On the following drawing, the red direction is the one that has to be followed to compensate the earth rotation.&lt;br /&gt;
&lt;br /&gt;
[[File:vitsol.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== Target direction ====&lt;br /&gt;
This direction also implements the methods of basic directions.&lt;br /&gt;
It is defined at any date by the position of two points of space: the target (that defines the direction) and the origin given by the user. The associated vector (and line) is computed from the origin to the target.&lt;br /&gt;
&lt;br /&gt;
=== Aberration corrections ===&lt;br /&gt;
The available aberration corrections are:&lt;br /&gt;
* NONE: no aberration correction is applied.&lt;br /&gt;
* LIGHT_TIME: the light-time aberration correction is applied. This aberration correction takes into account the apparent displacement of the source (from the receiver point of view) or of the observer (from the transmitter point of view) during the time of propagation.&lt;br /&gt;
* STELLAR: the stellar aberration correction is applied. This aberration correction takes into account the observer velocity at reception time (from the receiver point of view) or the source velocity at transmission time (from the transmitter point of view).&lt;br /&gt;
* ALL: both the light-time and the stellar aberration corrections are applied.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Use ===&lt;br /&gt;
==== For all directions ====&lt;br /&gt;
&lt;br /&gt;
All the directions implement the &amp;quot;IDirection&amp;quot; interface and so provide the &amp;quot;getVector&amp;quot; method. This method needs a date and a frame to express the vector, and the PV coordinates of the origin point (unused for some of them). It shall be used this way :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Vector3D directionVector = myDirection.getVector(pvCoordinatesProvider, date, frame);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
They also provide the &amp;quot;getLine&amp;quot; method, with the same arguments. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Line directionLine = myDirection.getLine(pvCoordinatesProvider, date, frame);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
NB : when the PVCoordinatesProvider is null then the origin of the direction is tacitly the frame origin.&lt;br /&gt;
&lt;br /&gt;
==== For target directions ====&lt;br /&gt;
&lt;br /&gt;
The directions that implement the &amp;quot;ITargetDirection&amp;quot; interface also provide the &amp;quot;getTarget&amp;quot; method :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
PVCoordinates directionTarget = myTargetDirection.getTargetPVCoordinates(date, frame);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IDirection &#039;&#039;&#039;&lt;br /&gt;
|General interface for all directions classes. All basic directions implement it.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/IDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ITargetDirection&#039;&#039;&#039;&lt;br /&gt;
|This interface extends IDirection for the particular case of directions defined by a target point. The vector&#039;s direction is oriented from the given origin to the target.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/ITargetDirection.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ConstantVectorDirection&#039;&#039;&#039;&lt;br /&gt;
|Vector constant in one of the frames of the tree.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/ConstantVectorDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VelocityDirection&#039;&#039;&#039;&lt;br /&gt;
|Velocity of the origin point expressed in a reference frame, projected in the given one.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/VelocityDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MomentumDirection&#039;&#039;&#039;&lt;br /&gt;
|Momentum : normal vector to the trajectory plane of the origin point around a celestial body.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/MomentumDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBodyPolesAxisDirection&#039;&#039;&#039;&lt;br /&gt;
|Axis of the poles of a celestial body.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/CelestialBodyPolesAxisDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ToCelestialBodyCenterDirection&#039;&#039;&#039;&lt;br /&gt;
|Vector from the origin to the center of a celestial body.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/ToCelestialBodyCenterDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EarthCenterDirection&#039;&#039;&#039;&lt;br /&gt;
|Vector from the origin to the center of the Earth central body.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/EarthCenterDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GenericTargetDirection&#039;&#039;&#039;&lt;br /&gt;
|Defined by a PVCoordinatesProvider target.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/GenericTargetDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BodyPointTargetDirection&#039;&#039;&#039;&lt;br /&gt;
|Defined by target which is a BodyPoint on a BodyShape.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/BodyPointTargetDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GroundVelocityDirection&#039;&#039;&#039;&lt;br /&gt;
|Defined by the location of the ground target point given by the pointing direction of the satellite and the body shape.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/GroundVelocityDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NadirDirection&#039;&#039;&#039;&lt;br /&gt;
|Defined by the location of the nadir point and the satellite position.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/NadirDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CrossProductDirection&#039;&#039;&#039;&lt;br /&gt;
|Cross Product of two directions.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/CrossProductDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GlintApproximatePointingDirection&#039;&#039;&#039;&lt;br /&gt;
|Direction to the Sun specular reflexion point.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/GlintApproximatePointingDirection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EarthToCelestialBodyCenterDirection&#039;&#039;&#039;&lt;br /&gt;
|Direction from Earth to the celestial body center.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/directions/EarthToCelestialBodyCenterDirection.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Attitude_Profile&amp;diff=4154</id>
		<title>User Manual 4.18 Attitude Profile</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Attitude_Profile&amp;diff=4154"/>
		<updated>2026-06-10T08:59:40Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__ == Introduction == === Scope === An attitude profile is an attitude law providing the computation of an instantaneous attitude without any reference to the satellite orbit, nor to its attitude laws sequence. The purpose of this section is to present the attitude profiles available through the Patrius library.  === Javadoc === The guidance models and classes are available in the attitude profiles package in the Patrius library.  {| class=&amp;quot;wikitable&amp;quot; |- !... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
An attitude profile is an attitude law providing the computation of an instantaneous attitude without any reference to the satellite orbit, nor to its attitude laws sequence. The purpose of this section is to present the attitude profiles available through the Patrius library.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The guidance models and classes are available in the attitude profiles package in the Patrius library.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/profiles/package-summary.html Package fr.cnes.sirius.patrius.attitudes/profiles]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
&lt;br /&gt;
PATRIUS handles different guidance profiles types:&lt;br /&gt;
* Profile expressed as quaternions represented as polynomials by means of UnivariateFunction: &amp;lt;code&amp;gt;QuaternionPolynomialProfile&amp;lt;/code&amp;gt;&lt;br /&gt;
* Profile expressed as quaternions represented as polynomials by means of DatePolynomialFunctionInterface: &amp;lt;code&amp;gt;QuaternionDatePolynomialProfile&amp;lt;/code&amp;gt;&lt;br /&gt;
* Profile expressed as quaternions represented as harmonics: &amp;lt;code&amp;gt;QuaternionHarmonicProfile&amp;lt;/code&amp;gt;&lt;br /&gt;
* Profile expressed as angular velocities represented as polynomials: &amp;lt;code&amp;gt;AngularVelocitiesPolynomialProfile&amp;lt;/code&amp;gt;&lt;br /&gt;
* Profile expressed as angular velocities represented as harmonics: &amp;lt;code&amp;gt;AngularVelocitiesHarmonicProfile&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Harmonic guidance profiles ===&lt;br /&gt;
The functions representing the angular velocity of the satellite and the quaternion (or the Euler angles) expressing its orientation can be represented by an harmonic profile.&lt;br /&gt;
The harmonic profile is a [MAT_TPOL_Home#HFourierSeries Fourier decomposition] of a periodic function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
S_n\left(f(x)\right) = a_0(f) + \sum_{k=1}^n\left(a_k(f)\cos\left(k x {2\pi\over T}\right) + b_k(f)\sin\left(k x {2\pi\over T}\right)\right)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The period T is generally computed knowing the nodes crossing periods.&lt;br /&gt;
&lt;br /&gt;
The Fourier coefficients (n &amp;gt; 0) of &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; (the angular velocity / quaternions / Euler angles function) are given by :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
a_0(f) = {1\over T}\int_{-T/2}^{T/2} \! f(t) \, \mathrm{d}t&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
b_0(f) = 0&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
a_n(f) = {2\over T}\int_{-T/2}^{T/2} \! f(t) \cos\left(n t {2\pi\over T}\right) \, \mathrm{d}t&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
b_n(f) = {2\over T}\int_{-T/2}^{T/2} \! f(t) \sin\left(n t {2\pi\over T}\right) \, \mathrm{d}t&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Polynomial guidance profiles ===&lt;br /&gt;
A polynomial guidance profile is generally composed by several segments (a segment corresponds to a time interval). Each segment contains the coefficients for the computation of a polynomial law representing the quaternion (or the Euler angles), or the angular velocity of the satellite; this polynomial law is valid only inside the time interval associated to the segment.&lt;br /&gt;
&lt;br /&gt;
For a quaternion, the polynomials are defined as :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;Qc_k(t) = \begin{pmatrix}&lt;br /&gt;
 \displaystyle\sum_{i=0}^n {a_0}_k^i \left( t-t_k \over {\Delta t} \right) \\ &lt;br /&gt;
 \displaystyle\sum_{i=0}^n {a_1}_k^i \left( t-t_k \over {\Delta t} \right) \\ &lt;br /&gt;
 \displaystyle\sum_{i=0}^n {a_2}_k^i \left( t-t_k \over {\Delta t} \right) \\ &lt;br /&gt;
 \displaystyle\sum_{i=0}^n {a_3}_k^i \left( t-t_k \over {\Delta t} \right)&lt;br /&gt;
\end{pmatrix}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And for the angular velocity :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\Omega c_k(t) = \begin{pmatrix}&lt;br /&gt;
 \displaystyle\sum_{i=0}^n {a_x}_k^i \left( \frac{t-t_k}{\Delta t} \right) \\ &lt;br /&gt;
 \displaystyle\sum_{i=0}^n {a_y}_k^i \left( \frac{t-t_k}{\Delta t} \right) \\ &lt;br /&gt;
 \displaystyle\sum_{i=0}^n {a_z}_k^i \left( \frac{t-t_k}{\Delta t} \right) &lt;br /&gt;
\end{pmatrix}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Build an harmonic profile from an attitude law ===&lt;br /&gt;
&lt;br /&gt;
Given :&lt;br /&gt;
* the profile start date &amp;lt;code&amp;gt;origin&amp;lt;/code&amp;gt;,&lt;br /&gt;
* the frame of expression &amp;lt;code&amp;gt;frame&amp;lt;/code&amp;gt;,&lt;br /&gt;
* the Fourier series for each quaternion &amp;lt;code&amp;gt;q0&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;q1&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;q2&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;q3&amp;lt;/code&amp;gt;,&lt;br /&gt;
* the profile time boundaries &amp;lt;code&amp;gt;timeInterval&amp;lt;/code&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
one can build an angular velocities guidance profile using the code snippet below :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
profile = new QuaternionHarmonicProfile(origin, frame, q0, q1, q2, q3, timeInterval);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AttitudeProfile&#039;&#039;&#039;&lt;br /&gt;
|Interface for all attitude profiles.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/profiles/AttitudeProfile.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;QuaternionHarmonicProfile&#039;&#039;&#039;&lt;br /&gt;
|Object representing a quaternion guidance profile, calculated with Fourier series.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/guidance/QuaternionHarmonicProfile.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;QuaternionPolynomialProfile&#039;&#039;&#039;&lt;br /&gt;
|Object representing a quaternion guidance profile, calculated with polynomials by means of QuaternionPolynomialSegment.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/guidance/QuaternionPolynomialProfile.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;QuaternionDatePolynomialProfile&#039;&#039;&#039;&lt;br /&gt;
|Object representing a quaternion guidance profile, calculated with polynomials by means of QuaternionDatePolynomialSegment.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/guidance/QuaternionDatePolynomialProfile.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;QuaternionPolynomialSegment&#039;&#039;&#039;&lt;br /&gt;
|Object representing a quaternion polynomial guidance profile on a segment by means of UnivariateFunction.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/guidance/QuaternionPolynomialSegment.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;QuaternionDatePolynomialSegment&#039;&#039;&#039;&lt;br /&gt;
|Object representing a quaternion polynomial guidance profile on a segment by means of DatePolynomialFunctionInterface.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/guidance/QuaternionDatePolynomialSegment.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AngularVelocitiesHarmonicProfile&#039;&#039;&#039;&lt;br /&gt;
|Represents an angular velocities guidance profile, calculated with Fourier series.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/guidance/AngularVelocitiesHarmonicProfile.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AngularVelocitiesPolynomialProfile&#039;&#039;&#039;&lt;br /&gt;
|Represents an angular velocities guidance profile, calculated with polynomial functions.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/guidance/AngularVelocitiesPolynomialProfile.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AngularVelocitiesPolynomialProfileLeg&#039;&#039;&#039;&lt;br /&gt;
|Object representing an angular velocity polynomial guidance profile on a segment.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/guidance/AngularVelocitiesPolynomialProfileLeg.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Attitude_leg&amp;diff=4153</id>
		<title>User Manual 4.18 Attitude leg</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Attitude_leg&amp;diff=4153"/>
		<updated>2026-06-10T08:59:20Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === The purpose of this chapter is to describe the current Patrius attitude legs.  An attitude leg is a time-bounded attitude law. Generalities on attitude laws can be found [ATT_ALW_Home here].  === Javadoc === {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=&amp;quot;col&amp;quot;| Javadoc |- |Patrius |[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/package-summary.html Package fr.cnes.sirius.patrius.attitudes] |- |Patrius |[{{Jav... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The purpose of this chapter is to describe the current Patrius attitude legs.&lt;br /&gt;
&lt;br /&gt;
An attitude leg is a time-bounded attitude law. Generalities on attitude laws can be found [ATT_ALW_Home here].&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/package-summary.html Package fr.cnes.sirius.patrius.attitudes]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/package-summary.html Package fr.cnes.sirius.patrius.attitudes]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
&lt;br /&gt;
Orekit attitudes : [https://www.orekit.org/static/architecture/attitudes.html Orekit Attitudes architecture description ]&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The attitude leg &amp;lt;code&amp;gt;AttitudeLeg&amp;lt;/code&amp;gt; interface inherits the &amp;lt;code&amp;gt;AttitudeProvider&amp;lt;/code&amp;gt; interface.&lt;br /&gt;
Its place in the global Attitude design can be found [ATT_ALW_PkgOverview here].&lt;br /&gt;
It also inherits the general &amp;lt;code&amp;gt;Leg&amp;lt;/code&amp;gt; interface presented below.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
&lt;br /&gt;
=== Generalities: the Leg and the LegsSequence interfaces ===&lt;br /&gt;
Attitude legs inherit the interface &amp;lt;code&amp;gt;AttitudeLeg&amp;lt;/code&amp;gt;.&lt;br /&gt;
In addition to &amp;lt;code&amp;gt;AttitudeProvider&amp;lt;/code&amp;gt; services, they inherit the methods of the &amp;lt;code&amp;gt;Leg&amp;lt;/code&amp;gt; interface which means they are time-bounded attitude providers.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;Leg&amp;lt;/code&amp;gt; interface is a generic interface for time-bounded timestamped data. It has only one method &amp;lt;code&amp;gt;getTimeInterval()&amp;lt;/code&amp;gt; (as well as method allowing to retrieve start and end of interval). This &amp;lt;code&amp;gt;Leg&amp;lt;/code&amp;gt; interface allows to define an &amp;lt;code&amp;gt;AttitudeLeg&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
In order to define an attitude sequence &amp;lt;code&amp;gt;StrictAttitudeLegsSequence&amp;lt;/code&amp;gt;, another generic interface is available: the &amp;lt;code&amp;gt;LegsSequence&amp;lt;/code&amp;gt; interface. This interface defines a sequence of &amp;lt;code&amp;gt;Leg&amp;lt;/code&amp;gt; and provides methods to manipulate a collection of timestamped legs similarly to the &amp;lt;code&amp;gt;Collection&amp;lt;/code&amp;gt; interface (methods &amp;lt;code&amp;gt;first()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;next()&amp;lt;/code&amp;gt;, etc.).&lt;br /&gt;
A implementation of &amp;lt;code&amp;gt;LegsSequence&amp;lt;/code&amp;gt; is available: &amp;lt;code&amp;gt;StrictLegsSequence&amp;lt;/code&amp;gt;. This class handles a sequence of legs which are strictly ordered (not overlapping is allowed), legs are ordered by their starting date.&lt;br /&gt;
The sequence of attitude legs &amp;lt;code&amp;gt;StrictAttitudeLegsSequence&amp;lt;/code&amp;gt; inherits the &amp;lt;code&amp;gt;StrictLegsSequence&amp;lt;/code&amp;gt; by considering legs as &amp;lt;code&amp;gt;AttitudeLegs&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; the &amp;lt;code&amp;gt;Leg&amp;lt;/code&amp;gt;and &amp;lt;code&amp;gt;LegsSequence&amp;lt;/code&amp;gt;interfaces are purely generic and therefore can be used for any other time-bounded data.&lt;br /&gt;
&lt;br /&gt;
=== Available attitude leg ===&lt;br /&gt;
==== Attitude legs sequence ====&lt;br /&gt;
An attitude legs sequence is a container for several attitude legs, contiguous for their time intervals, in such a way that the attitude legs sequence can be processed like a single attitude leg by the propagator.&lt;br /&gt;
&lt;br /&gt;
The attitude legs sequence is the equivalent of the [ATT_ALW_Home#HAttitudessequence Attitudes sequence], using attitude legs (&amp;lt;code&amp;gt;AttitudeLeg&amp;lt;/code&amp;gt; instances) rather than attitude laws (&amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt; instances). &lt;br /&gt;
The switching from one attitude leg to another is based on the time interval of validity of the two legs.&lt;br /&gt;
&lt;br /&gt;
==== TabulatedAttitude ====&lt;br /&gt;
&amp;lt;code&amp;gt;TabulatedAttitude&amp;lt;/code&amp;gt; is an implementation of &amp;lt;code&amp;gt;AttitudeLeg&amp;lt;/code&amp;gt;. It represents a tabulated attitude leg.&lt;br /&gt;
&lt;br /&gt;
In order to interpolate the attitude at a date, the user must specify a list of &#039;&#039;&#039;ordered&#039;&#039;&#039; attitudes, and can specify a number of points used by Hermite interpolation.&lt;br /&gt;
If not specified, the number of points used by Hermite interpolation is set to a default number (currently 2).&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final List&amp;lt;Attitude&amp;gt; attList = new ArrayList&amp;lt;Attitude&amp;gt;();&lt;br /&gt;
attList.add(attitude0);&lt;br /&gt;
attList.add(attitude1);&lt;br /&gt;
final int nbrInterpPoints = 2;&lt;br /&gt;
final TabulatedAttitude attLeg = new TabulatedAttitude(attList, nbrInterpPoints);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is possible to get the non-interpolated ordered attitudes : &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final List&amp;lt;Attitude&amp;gt; attitudes = attLeg.getAttitudes();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the tabulated is defined, the computation can be performed on any orbital state using &amp;lt;code&amp;gt;getAttitude()&amp;lt;/code&amp;gt; method:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Attitude attitude = attLeg.getAttitude(orbit, date, FramesFactory.getEME2000());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== RelativeTabulatedAttitudeLeg ====&lt;br /&gt;
&amp;lt;code&amp;gt;RelativeTabulatedAttitudeLeg&amp;lt;/code&amp;gt; is an implementation of &amp;lt;code&amp;gt;AttitudeLeg&amp;lt;/code&amp;gt;. An instance of &amp;lt;code&amp;gt;RelativeTabulatedAttitudeLeg&amp;lt;/code&amp;gt; can be created with a &amp;lt;code&amp;gt;List&amp;lt;Pair&amp;lt;Double, Rotation&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; or with a &amp;lt;code&amp;gt;List&amp;lt;Pair&amp;lt;Double, AngularCoordinates&amp;gt;&amp;gt;&amp;lt;/code&amp;gt;. Each &amp;lt;code&amp;gt;Rotation&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;AngularCoordinates&amp;lt;/code&amp;gt;) is associated with a &amp;lt;code&amp;gt;double&amp;lt;/code&amp;gt; representing its time ellapsed in seconds since the reference date. Here is an example of a creation of an instance of &amp;lt;code&amp;gt;RelativeTabulatedAttitudeLeg&amp;lt;/code&amp;gt; : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// date and frame&lt;br /&gt;
AbsoluteDate refDate = new AbsoluteDate(2008, 1, 1, TimeScalesFactory.getTAI());&lt;br /&gt;
Frame frame = FramesFactory.getGCRF();&lt;br /&gt;
double timeEllapsedSinceRefDate = 1.0;&lt;br /&gt;
        &lt;br /&gt;
// List of AR&lt;br /&gt;
List&amp;lt;Pair&amp;lt;Double, AngularCoordinates&amp;gt;&amp;gt; listAr = new ArrayList&amp;lt;Pair&amp;lt;Double, AngularCoordinates&amp;gt;&amp;gt;();&lt;br /&gt;
final AngularCoordinates ar = new AngularCoordinates(&lt;br /&gt;
                new Rotation(false, 0.48, 0.64, 0.36, 0.48), Vector3D.PLUS_I, Vector3D.PLUS_J);&lt;br /&gt;
listAr.add(new Pair&amp;lt;Double, AngularCoordinates&amp;gt;(timeEllapsedSinceRefDate, ar));&lt;br /&gt;
&lt;br /&gt;
// create RelativeTabulatedAttitudeLeg&lt;br /&gt;
final RelativeTabulatedAttitudeLeg relativeTabulatedAttitudeLeg = &lt;br /&gt;
                new RelativeTabulatedAttitudeLeg(refDate, frame, listAr);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
=== Building an attitude legs sequence ===&lt;br /&gt;
&lt;br /&gt;
The attitude legs sequence was designed as a simple container, it performs only a few coherence checks on its inner attitude laws. Here&#039;s how an attitude sequence is built.&lt;br /&gt;
&lt;br /&gt;
* An attitude legs sequence is created empty, associated to a single &amp;lt;code&amp;gt;PVCoordinatesProvider&amp;lt;/code&amp;gt; instance.&lt;br /&gt;
&lt;br /&gt;
* The sequence is mutable, attitude laws can be added to it one by one.&lt;br /&gt;
&lt;br /&gt;
* Each attitude law is identified by a code.&lt;br /&gt;
&lt;br /&gt;
* The sequence has a validity time interval, which is the grouping of the validity time intervals of all contained laws.&lt;br /&gt;
&lt;br /&gt;
* The time interval of a newly added law must be contiguous to the grouped time interval of the already added laws. Otherwise an PatriusException is thrown.&lt;br /&gt;
&lt;br /&gt;
* As soon as the sequence contains at least one law, methods of the &amp;lt;code&amp;gt;AttitudeLeg&amp;lt;/code&amp;gt; interface can be called on the attitude sequence. The attitude sequence forwards the request to the appropriate attitude leg (according to the asking date), but replaces the &amp;lt;code&amp;gt;PVCoordinatesProvider&amp;lt;/code&amp;gt; attribute of the call with the inner &amp;lt;code&amp;gt;PVCoordinatesProvider&amp;lt;/code&amp;gt; instance.&lt;br /&gt;
&lt;br /&gt;
=== AttitudeLawLeg and AttitudeLegsSequence : Code sample ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final BodyCenterPointing earthCenterAttitudeLaw = new BodyCenterPointing(itrf);&lt;br /&gt;
final AttitudeLeg law1 = new AttitudeLawLeg(earthCenterAttitudeLaw, date1, date2);&lt;br /&gt;
final AttitudeLeg law2 = ... ;&lt;br /&gt;
final AttitudeLeg law3 = ... ;&lt;br /&gt;
&lt;br /&gt;
PVCoordinatesProvider pvProvider = new CartesianOrbit(pvCoordinates, gcrf, date1, mu);&lt;br /&gt;
final StrictAttitudeLegsSequence sequence = new StrictAttitudeLegsSequence(pvProvider);&lt;br /&gt;
sequence.add(law1);&lt;br /&gt;
sequence.add(law2);&lt;br /&gt;
sequence.add(law3);&lt;br /&gt;
&lt;br /&gt;
// Call to getAttitude on the sequence&lt;br /&gt;
final Attitude attitude = sequence.getAttitude(pvProvider, date, itrf);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Leg&#039;&#039;&#039;&lt;br /&gt;
|This interface is a generic interface for any king of time-bounded data.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/utils/legs/Leg.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LegsSequence&#039;&#039;&#039;&lt;br /&gt;
|This interface is a generic interface for any sequence of legs.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/utils/legs/LegsSequence.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AttitudeLeg&#039;&#039;&#039;&lt;br /&gt;
|This interface extends the AttitudeProvider interface and adds the time interval of validity notion to the attitude laws.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/AttitudeLeg.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;StrictLegsSequence&#039;&#039;&#039;&lt;br /&gt;
|This class is a generic class for handling any sequence of legs.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/utils/legs/StrictLegsSequence.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AttitudeLawLeg&#039;&#039;&#039;&lt;br /&gt;
|Object representing an attitude law for spacecraft attitude field purposes.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/AttitudeLawLeg.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TabulatedAttitude&#039;&#039;&#039;&lt;br /&gt;
|Object representing a tabulated attitude leg : the attitude at a date is interpolated from a list of known ones.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/TabulatedAttitude.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;StrictAttitudeLegsSequence&#039;&#039;&#039;&lt;br /&gt;
|Object representing a sequence of attitude legs.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/StrictAttitudeLegsSequence.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RelativeTabulatedAttitudeLeg&#039;&#039;&#039;&lt;br /&gt;
|This class implements a tabulated attitude leg with relative dates.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/RelativeTabulatedAttitudeLeg.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Attitude_law&amp;diff=4152</id>
		<title>User Manual 4.18 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Attitude_law&amp;diff=4152"/>
		<updated>2026-06-10T08:58:56Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === The purpose of this chapter is to describe the current Patrius attitude laws.  === Javadoc === The attitude objects are available in the package fr.cnes.sirius.patrius.attitudes.  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=&amp;quot;col&amp;quot;| Javadoc |- |Patrius |[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/package-summary.html Package fr.cnes.sirius.patrius.attitudes] |- |Patrius |[{{JavaDoc4.18}}/fr/cnes/sirius/pa... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The purpose of this chapter is to describe the current Patrius attitude laws.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The attitude objects are available in the package fr.cnes.sirius.patrius.attitudes.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/package-summary.html Package fr.cnes.sirius.patrius.attitudes]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/package-summary.html Package fr.cnes.sirius.patrius.attitudes]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
Orekit attitudes : [https://www.orekit.org/static/architecture/attitudes.html Orekit Attitudes architecture description ]&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Generalities ===&lt;br /&gt;
The Orekit class &amp;lt;code&amp;gt;AttitudeProvider&amp;lt;/code&amp;gt; represents a generic provider for an attitude law. Attitude from an attitude provider can be retrieved using the methods &amp;lt;code&amp;gt;getAttitude(...)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The new &amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt; interface, implementing &amp;lt;code&amp;gt;AttitudeProvider&amp;lt;/code&amp;gt; has been added to represent an attitude provider without a time interval of validity.&lt;br /&gt;
&lt;br /&gt;
Instead, to meet spacecraft attitude field needs, a wrapper object has been created. The idea is to provide objects more suited for spacecraft attitude field rather than orbit determination field, that means to associate a specific time interval of validity to the attitude laws. The new objects &amp;lt;code&amp;gt;AttitudeLeg&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;AttitudeLawLeg&amp;lt;/code&amp;gt; meet the requirements. &lt;br /&gt;
&amp;lt;code&amp;gt;AttitudeLawLeg&amp;lt;/code&amp;gt;  wraps an &amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt; object and defines a time interval of validity. This class implements the &amp;lt;code&amp;gt;AttitudeLeg&amp;lt;/code&amp;gt; interface which extends the &amp;lt;code&amp;gt;AttitudeProvider&amp;lt;/code&amp;gt; interface and adds the methods to get the time interval.&lt;br /&gt;
&lt;br /&gt;
In pratical terms, when it comes to create an attitude law for spacecraft attitude field purposes, the user has to create first an &amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt; which is then given to an &amp;lt;code&amp;gt;AttitudeLawLeg&amp;lt;/code&amp;gt; object, in addition to the initial and final date of the time interval of validity:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Attitude law leg provider       &lt;br /&gt;
&lt;br /&gt;
// Elliptic earth shape&lt;br /&gt;
final OneAxisEllipsoid earthShape = new OneAxisEllipsoid(6378136.460, 1 / 298.257222101, frameITRF);&lt;br /&gt;
&lt;br /&gt;
// Target pointing attitude provider over satellite nadir at date, without yaw compensation&lt;br /&gt;
final NadirPointing nadirLaw = new NadirPointing(earthShape);&lt;br /&gt;
&lt;br /&gt;
// First date&lt;br /&gt;
final AbsoluteDate date1 = new AbsoluteDate(new DateComponents(2012, 01, 01), &lt;br /&gt;
                           TimeComponents.H00, TimeScalesFactory.getUTC());&lt;br /&gt;
// Last date&lt;br /&gt;
final AbsoluteDate date2 = date1.shiftedBy(3600);&lt;br /&gt;
&lt;br /&gt;
// Attitude law leg&lt;br /&gt;
final AttitudeLawLeg myAttitudeLaw = new AttitudeLawLeg(nadirLaw, date1, date2);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Besides, compared to Orekit, the &amp;lt;code&amp;gt;Attitude&amp;lt;/code&amp;gt; object has been slightly modified. In addition to the rotation and the rotation rate it can also provide the rotation acceleration, and its computation can be activated (or not) by the user. Therefore, an additional &amp;lt;code&amp;gt;getAttitude()&amp;lt;/code&amp;gt; method and a &amp;lt;code&amp;gt;setSpinDerivativesComputation(final boolean setSpinDerivatives)&amp;lt;/code&amp;gt; method have been created to the &amp;lt;code&amp;gt;AttitudeProvider&amp;lt;/code&amp;gt; interface. This last method allows the user to activate the rotation acceleration computation. By default, only the rotation and the angular velocity is computed.&lt;br /&gt;
&lt;br /&gt;
=== Available attitude laws ===&lt;br /&gt;
&lt;br /&gt;
==== Ground pointing attitude laws ====&lt;br /&gt;
The satellite x axis is aligned to the satellite velocity vector, and the z axis points to the ground target:  &lt;br /&gt;
* &amp;lt;u&amp;gt;Body center ground pointing&amp;lt;/u&amp;gt;: the satellite z axis is pointing to the body frame center.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;u&amp;gt;Nadir pointing&amp;lt;/u&amp;gt;: the satellite z axis is pointing to the vertical of the ground point under satellite.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;u&amp;gt;Target ground pointing&amp;lt;/u&amp;gt;: the satellite z axis is pointing to a ground point target;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;u&amp;gt;LOF offset pointing&amp;lt;/u&amp;gt;: the attitude pointing law is defined by an attitude provider and the satellite axis vector chosen for pointing.&lt;br /&gt;
&lt;br /&gt;
These laws require a body shape and a frame.&lt;br /&gt;
&lt;br /&gt;
==== Body center attitude law ====&lt;br /&gt;
The satellite z axis points to a the body center; this law does not require a body shape.&lt;br /&gt;
&lt;br /&gt;
==== Target attitude law ====&lt;br /&gt;
The satellite z axis points to a target; this law does not require a body shape.&lt;br /&gt;
&lt;br /&gt;
==== Celestial body pointed attitude law ====&lt;br /&gt;
The celestial body pointed law is defined by two elements:&lt;br /&gt;
*   a celestial body towards which some satellite axis is exactly aimed&lt;br /&gt;
&lt;br /&gt;
*   a phasing reference defining the rotation around the pointing axis&lt;br /&gt;
&lt;br /&gt;
==== Fixed rate attitude law ====&lt;br /&gt;
The fixed rate attitude law handles a constant rate around a fixed axis.&lt;br /&gt;
This corresponding attitude provider performs a simple linear extrapolation from an initial orientation, a rotation axis and a rotation rate.&lt;br /&gt;
&lt;br /&gt;
==== Constant attitude law ====&lt;br /&gt;
The satellite frame has a constant orientation in a given reference frame. This orientation is defined by a rotation provided by the user.&lt;br /&gt;
&lt;br /&gt;
==== LOF offset attitude law ====&lt;br /&gt;
It is an attitude law defined by fixed Roll, Pitch and Yaw angles (in any order) with respect to a local orbital frame.&lt;br /&gt;
&lt;br /&gt;
==== Spin stabilized attitude law ====&lt;br /&gt;
Spin stabilized attitude provider. Spin stabilized laws are handled as wrappers for an underlying non-rotating law.&lt;br /&gt;
&lt;br /&gt;
==== Yaw compensation attitude law ====&lt;br /&gt;
Yaw compensation is mainly used for Earth observation satellites: as a satellite moves along its track, the image of ground points moves on the focal point of the optical sensor. This motion is a combination of the satellite motion, the Earth rotation and the current attitude (in particular if the pointing includes Roll or Pitch offset). &amp;lt;br&amp;gt;&lt;br /&gt;
In order to reduce geometrical distortion, the yaw angle is changed a little from the simple ground pointing attitude such that the apparent motion of ground points is along a prescribed axis (orthogonal to the optical sensor rows), taking into account all effects.&lt;br /&gt;
&lt;br /&gt;
==== Yaw steering attitude law ====&lt;br /&gt;
Yaw steering is mainly used for low Earth orbiting satellites with no missions-related constraints on yaw angle. It sets the yaw angle in such a way the solar arrays have maximal lightning without changing the roll and pitch.&lt;br /&gt;
&lt;br /&gt;
==== Two directions attitude law ====&lt;br /&gt;
The two directions provided by this attitude law are the following:&lt;br /&gt;
* the first direction is aligned with a given satellite axis;&lt;br /&gt;
&lt;br /&gt;
* the second direction is aligned at best with another given satellite axis.&lt;br /&gt;
&lt;br /&gt;
This attitude law can be used to represent the &#039;&#039;&#039;GAP&#039;&#039;&#039; (geocentric), and the &#039;&#039;&#039;SUP&#039;&#039;&#039; (heliocentric) pointing laws.&lt;br /&gt;
&lt;br /&gt;
==== RelativeTabulatedAttitudeLaw ====&lt;br /&gt;
&amp;lt;code&amp;gt;RelativeTabulatedAttitudeLaw&amp;lt;/code&amp;gt; is an implementation of &amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt;. It is composed of a &amp;lt;code&amp;gt;AttitudeLegLaw:attitudeLegLaw&amp;lt;/code&amp;gt; attribute defined by :&amp;lt;br&amp;gt;&lt;br /&gt;
- An instance of &amp;lt;code&amp;gt;RelativeTabulatedAttitudeLeg:leg&amp;lt;/code&amp;gt; built with an &amp;lt;code&amp;gt;List&amp;lt;Pair&amp;lt;Double, Rotation&amp;gt;&amp;gt;&amp;lt;/code&amp;gt; (or an &amp;lt;code&amp;gt;List&amp;lt;Pair&amp;lt;Double, AngularCoordinates&amp;gt;&amp;gt;)&amp;lt;/code&amp;gt; input.&amp;lt;br&amp;gt;&lt;br /&gt;
- Two instances of &amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt; to apply if the input date is inferior or superior to the interval of validity of &amp;lt;code&amp;gt;leg&amp;lt;/code&amp;gt;. These laws can be of two types : &amp;lt;code&amp;gt;ConstantAttitudeLaw&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;ExtrapolatedAttitudeLaw&amp;lt;/code&amp;gt; (local private class of &amp;lt;code&amp;gt;RelativeTabulatedAttitudeLaw&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ConstantAttitudeLaw&amp;lt;/code&amp;gt; is created with the input frame of &amp;lt;code&amp;gt;RelativeTabulatedAttitudeLaw&amp;lt;/code&amp;gt;, and the value of the rotation to the bound of the interval (minimum or maximum).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtrapolatedAttitudeLaw&amp;lt;/code&amp;gt; is a local private class. It is an implementation of &amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt;. It is created with an &amp;lt;code&amp;gt;AngularCoordinates&amp;lt;/code&amp;gt; and the expression frame of this attitude. Its method &amp;lt;code&amp;gt;getAttitude()&amp;lt;/code&amp;gt; returns &amp;lt;code&amp;gt;AngularCoordinates.shiftedBy(double)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtrapolatedAttitudeLaw&amp;lt;/code&amp;gt; is created with :&amp;lt;br&amp;gt;&lt;br /&gt;
- the input frame of &amp;lt;code&amp;gt;RelativeTabulatedAttitudeLaw&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
- the &amp;lt;code&amp;gt;AngularCoordinates&amp;lt;/code&amp;gt; to the bound of the interval (minimum or maximum).&amp;lt;br&amp;gt;&lt;br /&gt;
Here is an example of a creation of an instance of &amp;lt;code&amp;gt;RelativeTabulatedAttitudeLaw&amp;lt;/code&amp;gt; : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// build law before as a ConstantAttitudeLaw&lt;br /&gt;
final RelativeTabulatedAttitudeLaw.AroundAttitudetype lawBefore = &lt;br /&gt;
     RelativeTabulatedAttitudeLaw.AroundAttitudetype.CONSTANT_ATT;&lt;br /&gt;
&lt;br /&gt;
// build law after as a ExtrapolatedAttitudeLaw&lt;br /&gt;
final RelativeTabulatedAttitudeLaw.AroundAttitudetype lawAfter = &lt;br /&gt;
     RelativeTabulatedAttitudeLaw.AroundAttitudetype.EXTRAPOLATED_ATT;&lt;br /&gt;
&lt;br /&gt;
// build RelativeTabulatedAttitudeLaw&lt;br /&gt;
final RelativeTabulatedAttitudeLaw relativeTabulatedAttitudeLaw = &lt;br /&gt;
      new RelativeTabulatedAttitudeLaw(refDate, listAr, frame, lawBefore, lawAfter);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== AeroAttitudeLaw ====&lt;br /&gt;
&amp;lt;code&amp;gt;AeroAttitudeLaw &amp;lt;/code&amp;gt; is a law that aligns platform frame (Ox, Oy, Oz) with a frame defined by 3 angles: angle of attack, sideslip and velocity roll.&lt;br /&gt;
With the following conventions:&amp;lt;br&amp;gt;&lt;br /&gt;
- Platform frame is (Ox, Oy, Oz) with Ox along main frame, Oz in the symmetry plane of the aircraft toward up direction.&amp;lt;br&amp;gt;&lt;br /&gt;
- Velocity frame is (Oxv, Oyv, Ozv) with Oxv being along velocity and Ozv in the symmetry plane of the aircraft toward up direction.&amp;lt;br&amp;gt;&lt;br /&gt;
The three angles are defined in the following way:&amp;lt;br&amp;gt;&lt;br /&gt;
- Angle of attack is angle between (Oxv, Oyv) plane and Ox vector.&amp;lt;br&amp;gt;&lt;br /&gt;
- Sideslip is angle between Oxv vector and (Ox, Oz) symmetry plane&amp;lt;br&amp;gt;&lt;br /&gt;
- Velocity roll is angle around velocity vector.&lt;br /&gt;
&lt;br /&gt;
==== AttitudeLegLaw ====&lt;br /&gt;
&amp;lt;code&amp;gt;AttitudeLegLaw&amp;lt;/code&amp;gt; is an implementation of &amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt;. It is composed of : an instance of &amp;lt;code&amp;gt;AttitudeLeg:leg&amp;lt;/code&amp;gt;, an instance of &amp;lt;code&amp;gt;AttitudeLaw:lawbefore&amp;lt;/code&amp;gt; and an other instance of &amp;lt;code&amp;gt;AttitudeLaw:lawAfter&amp;lt;/code&amp;gt;. Its method &amp;lt;code&amp;gt;getAttitude(pvProv, date, frame)&amp;lt;/code&amp;gt; returns : &amp;lt;br&amp;gt;&lt;br /&gt;
- &amp;lt;code&amp;gt;lawbefore.getAttitude(pvProv, date, frame)&amp;lt;/code&amp;gt; is the date is inferior to the interval of validity of leg&amp;lt;br&amp;gt;&lt;br /&gt;
- &amp;lt;code&amp;gt;leg.getAttitude(pvProv, date, frame)&amp;lt;/code&amp;gt; is the date is contained in the interval of validity of leg&amp;lt;br&amp;gt;&lt;br /&gt;
- &amp;lt;code&amp;gt;lawAfter.getAttitude(pvProv, date, frame)&amp;lt;/code&amp;gt; is the date is superior to the the interval of validity of leg&lt;br /&gt;
&lt;br /&gt;
=== Attitudes sequence ===&lt;br /&gt;
The attitudes sequence represents a sequence of several attitude laws (&amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt; instances).&lt;br /&gt;
&lt;br /&gt;
Unlike the &amp;lt;code&amp;gt;AttitudeLeg&amp;lt;/code&amp;gt; objects, the &amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt; instances do not have an interval of validity, therefore the switching from one law to another can not be based on time intervals.  &lt;br /&gt;
For a given date, only one attitude law in the sequence is in an &amp;quot;active&amp;quot; state, so that the attitude of the spacecraft is computed from that attitude law. The laws are activated in turn according to some switching events, which are added to the sequence before starting the propagation.&lt;br /&gt;
&lt;br /&gt;
Note that during the propagation, the previously used attitude legs are stored along with their validity intervals. Hence, the &amp;lt;code&amp;gt;AttitudesSequence&amp;lt;/code&amp;gt; object always returns a consistent attitude for any given date in the past. The current active attitude leg is valid only since the last switch (or forever in the past if it is the first leg).&lt;br /&gt;
&lt;br /&gt;
==== Building an attitudes sequence ====&lt;br /&gt;
&lt;br /&gt;
Here is how an attitudes sequence is built:&lt;br /&gt;
&lt;br /&gt;
* An empty attitudes sequence is created: &amp;lt;code&amp;gt;new AttitudesSequence()&amp;lt;/code&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
* The attitudes laws that will compose the sequence are instantiated;&lt;br /&gt;
&lt;br /&gt;
* The switching detectors are instantiated and set up using the &amp;lt;code&amp;gt;addSwitchingCondition(AttitudeLaw, EventDetector, boolean, boolean, AttitudeLaw)&amp;lt;/code&amp;gt; command; in addition to the event detector, the previous and the next attitude laws associated to the switching condition are specified; Warning: switching detectors should have &amp;lt;code&amp;gt;Action.RESET_STATE&amp;lt;/code&amp;gt; as action.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;registerSwitchEvents(Propagator)&amp;lt;/code&amp;gt; method is called once before propagation, after the switching conditions have been set, in order to wrap switch events to the propagator.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;plainlinks&amp;quot;&amp;gt;&lt;br /&gt;
    [https://github.com/{{{owner|CNES}}}/{{{repo|patrius-tutorials}}}/{{{action|blob}}}/{{{branch|main}}}/{{{file|{{{1|src/main/java/attitudes/LOFOffsetAttitudeLaw.java}}}}}}#L56 {{{text|{{{2|Tutorial: LOFOffsetAttitudeLaw.java}}}}}}]&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Code sample ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final Frame gcrf = FramesFactory.getGCRF();&lt;br /&gt;
&lt;br /&gt;
// Build the attitudes sequence:&lt;br /&gt;
final AttitudesSequence aseq = new AttitudesSequence();&lt;br /&gt;
&lt;br /&gt;
final EventDetector switcherToTwo = new DateDetector(date.shiftedBy(100)) {&lt;br /&gt;
    @Override&lt;br /&gt;
    public Action eventOccurred(final SpacecraftState s, final boolean increasing, final boolean forward) throws PatriusException {&lt;br /&gt;
            // Action.RESET_STATE is compulsory for the switch to be taken into account&lt;br /&gt;
            return Action.RESET_STATE;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
final EventDetector switcherToOne = new DateDetector(date.shiftedBy(200)) {&lt;br /&gt;
    @Override&lt;br /&gt;
    public Action eventOccurred(final SpacecraftState s, final boolean increasing, final boolean forward) throws PatriusException {&lt;br /&gt;
            // Action.RESET_STATE is compulsory for the switch to be taken into account&lt;br /&gt;
            return Action.RESET_STATE;&lt;br /&gt;
        }&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
// Instantiate the attitude laws:&lt;br /&gt;
final AttitudeLaw lawOne = new LofOffset(gcrf, LOFType.QSW);&lt;br /&gt;
final AttitudeLaw lawTwo = new LofOffset(gcrf, LOFType.TNW);&lt;br /&gt;
&lt;br /&gt;
// Add the switching detectors to the sequence:&lt;br /&gt;
aseq.addSwitchingCondition(lawTwo, switcherToOne, true, true, lawOne);&lt;br /&gt;
aseq.addSwitchingCondition(lawOne, switcherToTwo, true, true, lawTwo);&lt;br /&gt;
&lt;br /&gt;
aseq.resetActiveProvider(lawOne);&lt;br /&gt;
&lt;br /&gt;
// Properly register switching events to the propagator:&lt;br /&gt;
final Propagator propagator = new KeplerianPropagator(orbit, aseq);&lt;br /&gt;
aseq.registerSwitchEvents(propagator);&lt;br /&gt;
&lt;br /&gt;
// Propagation:&lt;br /&gt;
propagator.propagate(date.shiftedBy(150));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Attitude composition ===&lt;br /&gt;
The &amp;lt;code&amp;gt;ComposedAttitudeLaw&amp;lt;/code&amp;gt; class allows to compose a main attitude law (implementing the &amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt; interface) and one or several orientation laws (&amp;lt;code&amp;gt;IOrientationLaw&amp;lt;/code&amp;gt; interface) whose purpose is to modify this law in order to obtain the &amp;quot;composed&amp;quot; attitude law.&lt;br /&gt;
&lt;br /&gt;
It shall be created this way :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// attitude law creation&lt;br /&gt;
AttitudeLaw attitudeLaw = new MyAttitudeLaw(...);&lt;br /&gt;
&lt;br /&gt;
// orientation laws creation (modifiers)&lt;br /&gt;
IOrientationLaw orientationLaw1 = new AnyOrientationLaw(...);&lt;br /&gt;
IOrientationLaw orientationLaw2 = new AnyOtherOrientationLaw(...);&lt;br /&gt;
&lt;br /&gt;
// modifiers list creation&lt;br /&gt;
final LinkedList&amp;lt;IOrientationLaw&amp;gt; modifiers = new LinkedList&amp;lt;IOrientationLaw&amp;gt;();&lt;br /&gt;
&lt;br /&gt;
modifiers.add(orientationLaw1);&lt;br /&gt;
modifiers.add(orientationLaw2);&lt;br /&gt;
&lt;br /&gt;
// composed attitude creation&lt;br /&gt;
final ComposedAttitudeLaw composedAtt = new ComposedAttitudeLaw(attitudeLaw, modifiers);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ComposedAttitudeLaw&amp;lt;/code&amp;gt; class implements the &amp;lt;code&amp;gt;AttitudeLawModifier&amp;lt;/code&amp;gt; interface : it shall be used as any &amp;lt;code&amp;gt;AttitudeLaw&amp;lt;/code&amp;gt;, and can also provide its &amp;quot;underlying attitude law&amp;quot; (the main attitude law used to build it).&lt;br /&gt;
&lt;br /&gt;
Dedicated frames exist to describe those laws and are used to compute the composition :&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;AttitudeFrame&amp;lt;/code&amp;gt; is a frame defined by any attitude law (&amp;lt;code&amp;gt;AttitudeProvider&amp;lt;/code&amp;gt;) and position velocity coordinates (&amp;lt;code&amp;gt;PVCoordinatesProvider&amp;lt;/code&amp;gt;). At any date, its center is the position of the &amp;lt;code&amp;gt;PVCoordinatesProvider&amp;lt;/code&amp;gt;, and its rotation from a reference frame is given by the attitude law.&lt;br /&gt;
&lt;br /&gt;
* The &amp;lt;code&amp;gt;OrientationFrame&amp;lt;/code&amp;gt; is defined from another &amp;lt;code&amp;gt;OrientationFrame&amp;lt;/code&amp;gt; or from an &amp;lt;code&amp;gt;AttitudeFrame&amp;lt;/code&amp;gt; by the corrections (&amp;lt;code&amp;gt;IOrientationLaw&amp;lt;/code&amp;gt; objects) applied to them.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ComposedAttitudeLaw&amp;lt;/code&amp;gt; class can be used to represent a biased geocentric pointing law (&#039;&#039;&#039;biased GAP&#039;&#039;&#039;): a geocentric attitude law is associated to a &amp;quot;modifier&amp;quot; that represents a constant rotation. This specific pointing law is used for the thrust: the bias added to the main pointing direction is the direction of the thrust.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AttitudeProvider&#039;&#039;&#039;&lt;br /&gt;
|This interface is the main interface of the attitudes package, it is related to the orbit determination field.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/AttitudeProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AttitudeLaw&#039;&#039;&#039;&lt;br /&gt;
|This interface represents a generic attitude law provider, for which no interval of validity is specified.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/AttitudeLaw.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AttitudeLawModifier&#039;&#039;&#039;&lt;br /&gt;
|This interface represents an attitude law provider that modifies/wraps another underlying provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/AttitudeLawModifier.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IOrientationLaw&#039;&#039;&#039;&lt;br /&gt;
|Orientation law.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/IOrientationLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbstractAttitudeLaw&#039;&#039;&#039;&lt;br /&gt;
|Abstract class representing the basic implementation of an attitude law provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/AbstractAttitudeLaw.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Attitude&#039;&#039;&#039;&lt;br /&gt;
|Object representing the attitude of the spacecraft for a specific date and in a specific frame.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/Attitude.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AttitudesSequence&#039;&#039;&#039;&lt;br /&gt;
|This class represents a sequence of attitude laws that are activated in turn according to switching events..&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/AttitudesSequence.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TwoDirectionAttitudeLaw&#039;&#039;&#039;&lt;br /&gt;
|This class implements a generic two directions attitude law. The first direction is aligned with a given satellite axis, the second direction is aligned at best with another given satellite axis.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/TwoDirectionAttitudeLaw.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AttitudeFrame&#039;&#039;&#039;&lt;br /&gt;
|Spacecraft frame (dynamic frame whose orientation is defined by the attitude law).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/AttitudeFrame.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OrientationFrame&#039;&#039;&#039;&lt;br /&gt;
|Spacecraft orientation frame.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/OrientationFrame.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BodyCenterPointing&#039;&#039;&#039;&lt;br /&gt;
|This class implements a body center pointing attitude law: the satellite z axis is pointing to the body frame center.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/BodyCenterPointing.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BodyCenterGroundPointing&#039;&#039;&#039;&lt;br /&gt;
|This class implements a body center ground pointing attitude law: the satellite z axis is pointing to the ground pointing corresponding to the body frame center.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/BodyCenterGroundPointing.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBodyPointed&#039;&#039;&#039;&lt;br /&gt;
|This class handles a celestial body pointed attitude provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/CelestialBodyPointed.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FixedRate&#039;&#039;&#039;&lt;br /&gt;
|This class handles a simple attitude provider at constant rate around a fixed axis.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/FixedRate.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GroundPointing&#039;&#039;&#039;&lt;br /&gt;
|This class is a basic model for different kind of ground pointing attitude providers.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/GroundPointing.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GroundPointingWrapper&#039;&#039;&#039;&lt;br /&gt;
|This class leverages common parts for compensation modes around ground pointing attitudes.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/GroundPointingWrapper.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ConstantAttitudeLaw&#039;&#039;&#039;&lt;br /&gt;
|This class handles an constant attitude provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/ConstantAttitudeLaw.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LofOffset&#039;&#039;&#039;&lt;br /&gt;
|Attitude law defined by fixed Roll, Pitch and Yaw angles (in any order) with respect to a local orbital frame.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/LofOffset.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LofOffsetPointing&#039;&#039;&#039;&lt;br /&gt;
|This attitude pointing law is defined by an attitude provider and the satellite axis vector chosen for pointing.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/LofOffsetPointing.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NadirPointing&#039;&#039;&#039;&lt;br /&gt;
|This class handles nadir pointing attitude provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/NadirPointing.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SpinStabilized&#039;&#039;&#039;&lt;br /&gt;
|This class handles a spin stabilized attitude provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/SpinStabilized.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TargetPointing&#039;&#039;&#039;&lt;br /&gt;
|This class handles target pointing attitude provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/TargetPointing.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TargetGroundPointing&#039;&#039;&#039;&lt;br /&gt;
|This class handles target ground pointing attitude provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/TargetPointing.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;YawCompensation&#039;&#039;&#039;&lt;br /&gt;
|This class handles yaw compensation attitude provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/YawCompensation.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;YawSteering&#039;&#039;&#039;&lt;br /&gt;
|This class handles yaw steering attitude law.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/YawSteering.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ComposedAttitudeLaw&#039;&#039;&#039;&lt;br /&gt;
|Composed attitude law provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/ComposedAttitudeLaw.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DirectionTrackingOrientation&#039;&#039;&#039;&lt;br /&gt;
|One direction orientation law. This law has to be used within a composed attitude law as a law modifier.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/DirectionTrackingOrientation.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SunPointing&#039;&#039;&#039;&lt;br /&gt;
|This class implements a Sun pointing attitude law. The first direction is the satellite-sun direction, the second direction is either the sun poles axis or the normal to the satellite orbit plane.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/SunPointing.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IsisSunPointing&#039;&#039;&#039;&lt;br /&gt;
|This class implements a ISIS Sun pointing attitude law. The first direction is the satellite-sun direction (being the - Z_sun axis computed in GCRF frame), the second direction is the Y_sun axis computed in GCRF.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/IsisSunPointing.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AttitudeLegLaw&#039;&#039;&#039;&lt;br /&gt;
|This class implements an attitude leg, one attitude law before the leg and one attitude law after the leg.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/AttitudeLegLaw.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RelativeTabulatedAttitudeLaw&#039;&#039;&#039;&lt;br /&gt;
|This class implements a tabulated attitude leg with relative dates, with one attitude law before the leg and one attitude law after the leg.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/RelativeTabulatedAttitudeLaw.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AeroAttitudeLaw&#039;&#039;&#039;&lt;br /&gt;
|This class implements an aerodynamic attitude law defined by angle of attack, side slip and velocity roll.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.18_Flight_Dynamics&amp;diff=4151</id>
		<title>Catégorie:User Manual 4.18 Flight Dynamics</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.18_Flight_Dynamics&amp;diff=4151"/>
		<updated>2026-06-10T08:58:34Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec «  == Introduction == In order to determine the position and velocity of a spacecraft at a given time, a reference frame with respect to which position and velocity as well as appropriate systems of coordinates and time measurements are required. These elements underpin the physical model that describes the dynamic system. The fundamentals of orbital mechanics have evolved over centuries and require evermore improvements to the dynamical models and coordinate and t... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Introduction ==&lt;br /&gt;
In order to determine the position and velocity of a spacecraft at a given time, a reference frame with respect to which position and velocity as well as appropriate systems of coordinates and time measurements are required. These elements underpin the physical model that describes the dynamic system. The fundamentals of orbital mechanics have evolved over centuries and require evermore improvements to the dynamical models and coordinate and time systems.&lt;br /&gt;
&lt;br /&gt;
[[File:referenceframe.gif|center]]&lt;br /&gt;
&lt;br /&gt;
Time has evolved from using the motion of the Sun to describe the fundamental unit of time to the current use of atomic clocks to define the second.&lt;br /&gt;
&lt;br /&gt;
At first based on Solar motion, time representation and measurement systems have considerably changed and currently involve measuring seconds with atomic clocks.&lt;br /&gt;
&lt;br /&gt;
Definitions of reference frames and reference systems have also considerably changed with the IERS standards and are more and more accurate. As observational accuracy has increased, models have generally increased in complexity, taking into consideration more and more details.&lt;br /&gt;
&lt;br /&gt;
== Applicable and Reference Documents ==&lt;br /&gt;
&lt;br /&gt;
=== Applicable Documents ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[A1]&#039;&#039;&#039;      &#039;&#039;CDCF - Fonctions de Base du Patrimoine de Dynamique du Vol&#039;&#039;, V1.2, SIRIUS-CF-DV-0049-CN, 2011.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;[A2]&#039;&#039;&#039;      &#039;&#039;Dossier de réutilisation Orekit et Commons Math&#039;&#039;, V1.0, SIRIUS-DLR-DV-0080-CN, 2010.&lt;br /&gt;
&lt;br /&gt;
=== Reference Documents ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[R1]&#039;&#039;&#039;    &#039;&#039;IERS website [http://www.iers.org/nn_10968/IERS/EN/IERSHome/home.html?__nnn=true].&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;[R2]&#039;&#039;&#039;    &#039;&#039;Spaceflight Dynamics&#039;&#039;, Part I, Jean-Pierre Carrou, edition 1995, chapter 10.4.5.&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;[R3]&#039;&#039;&#039;    &#039;&#039;JPL FTP server: [ftp://ssd.jpl.nasa.gov/pub/eph/planets/]&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Glossary ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CIRF&#039;&#039;&#039;&lt;br /&gt;
|Celestial Intermediate Reference Frame&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DE&#039;&#039;&#039;&lt;br /&gt;
|Development Ephemerides&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ERA&#039;&#039;&#039;&lt;br /&gt;
|Earth Rotation Angle&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GCRF&#039;&#039;&#039;&lt;br /&gt;
|Geocentric Celestial Reference Frame&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IERS&#039;&#039;&#039;&lt;br /&gt;
|Development Ephemerides&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ITRF&#039;&#039;&#039;&lt;br /&gt;
|International Terrestrial Reference Frame&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;JPL&#039;&#039;&#039;&lt;br /&gt;
|Jet Propulsion Laboratory&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TIRF&#039;&#039;&#039;&lt;br /&gt;
|Terrestrial Intermediate Reference Frame&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UT1&#039;&#039;&#039;&lt;br /&gt;
|Universal Time&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UTC&#039;&#039;&#039;&lt;br /&gt;
|Coordinated Universal Time&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The flight dynamics basis of the PATRIUS library are mainly based on the packages bodies, frames, time and orbits of original OREKIT. Some evolutions have been brougth to meet the SIRIUS Scope Statement &#039;&#039;&#039;[A1]&#039;&#039;&#039;, for instance, the topocentric frame has been slightly modified and two objects have been created in order to represent a topocentric mounting and a Cardan mounting.&lt;br /&gt;
&lt;br /&gt;
Several themes are developped in this section : &lt;br /&gt;
&lt;br /&gt;
* IERS conventions : this chapter is dedicated to the use of the IERS frames in Orekit. Its purpose is to help the user avoid some traps and know what to numerical precision to expect from subsequent computations.&lt;br /&gt;
&lt;br /&gt;
* Topocentric frame : this chapter deals with the modifications brought to the TopocentricFrame object and how to use it.&lt;br /&gt;
&lt;br /&gt;
* Body shape : this chapter explains how a body model can be constructed. The one-axis ellipsoid model is available. In this chapter, the use of the transformation methods from Cartesian coordinates to geodetic coordinates and vice versa is explained, these methods are linked to the body model.&lt;br /&gt;
&lt;br /&gt;
* Ephemerides loader : this chapter explains how to use the JPLEphemeridesLoader to load bodies ephemerides. Only the DE 405 and DE 406 loaders are available.&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:User Manual 4.18]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Time&amp;diff=4150</id>
		<title>User Manual 4.18 Time</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Time&amp;diff=4150"/>
		<updated>2026-06-10T08:58:11Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === Despite its current use, time requires careful attention in the description of physical phenomena. Indeed the rate at which time passes has to be accurate in order to guarantee the best physical description of a phenomenon. To that purpose several time scales have been set up and with the introduction of atomic clocks, more accurate time scales have been defined.  === Javadoc === The object related with dates and time s... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
Despite its current use, time requires careful attention in the description of physical phenomena. Indeed the rate at which time passes has to be accurate in order to guarantee the best physical description of a phenomenon. To that purpose several time scales have been set up and with the introduction of atomic clocks, more accurate time scales have been defined.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The object related with dates and time scales are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.time&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/package-summary.html Package fr.cnes.sirius.patrius.time]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/utils/package-summary.html Package fr.cnes.sirius.patrius.utils]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
&#039;&#039;Time architecture description&#039;&#039;, [http://procyon.cst.cnes.fr/mvnsites/1_0_1/orekit/architecture/time.html Orekit site].&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
&lt;br /&gt;
Please note that not all implementations are present in the following diagram for the sake of clarity.&lt;br /&gt;
&lt;br /&gt;
[[File:timeOrekit.JPG]]&lt;br /&gt;
&lt;br /&gt;
This package overview is from the OREKIT website, under apache license.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Dates ===&lt;br /&gt;
In Patrius, the class &amp;lt;code&amp;gt;AbsoluteDate&amp;lt;/code&amp;gt; represents a specific instant in time. There are several ways to create a date :&lt;br /&gt;
&lt;br /&gt;
* for instance, one way is to give the date with a calendar form (year, month and day as 3 integers or as a &amp;lt;code&amp;gt;DateComponents&amp;lt;/code&amp;gt; object) and a time scale : &amp;lt;code&amp;gt;AbsoluteDate(int, int, int, TimeScale)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;AbsoluteDate(DateComponents, TimeScale)&amp;lt;/code&amp;gt;&lt;br /&gt;
* to be more precise the informations of the hour, the minute and the second can be added : &amp;lt;code&amp;gt;AbsoluteDate(int, int, int, int, int, double, TimeScale)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;AbsoluteDate(DateComponents, TimeComponents, TimeScale)&amp;lt;/code&amp;gt;&lt;br /&gt;
NB : a DateComponents object represents a date broken up as year, month and day ; a TimeComponents object represents a day broken up as hour, minute and second.&lt;br /&gt;
* another way is to give a predefined date and an elapsed duration from this date : &amp;lt;code&amp;gt;AbsoluteDate(AbsoluteDate, double)&amp;lt;/code&amp;gt;&lt;br /&gt;
* through a CNES Julian date and associated timescale: &amp;lt;code&amp;gt;AbsoluteDate(double, TimeScale)&amp;lt;/code&amp;gt;. Note that the reversed conversion (from AbsoluteDate to CNES JD is also available with method &amp;lt;code&amp;gt;toCNESJulianDate()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{warning|For advanced users only : a constructor &amp;lt;code&amp;gt;AbsoluteDate(long, double)&amp;lt;/code&amp;gt; is available. It uses as parameters an &amp;quot;epoch&amp;quot; and an &amp;quot;offset&amp;quot;, which are in fact the attributes of AbsoluteDate. These attributes have no meaning outside of AbsoluteDate, and are not meant to be exposed or manipulated directly by regular users. This constructor was added for the purpose of creating AbsoluteDate instances very quickly from a static storage (apart from serialization) and without loss of precision. Getters for &amp;quot;epoch&amp;quot; and &amp;quot;offset&amp;quot; are also available for this purpose.&#039;&#039;&#039;Use at your own risk!&#039;&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As for the time scale, Patrius contains 10 different time scales among which the TAI scale (International Atomic Time), the TT scale (Terrestrial Time), the UT1 scale (Universal Time), the UTC scale (Coordinated Universal Time)... The creation of a time scale is done through the &amp;lt;code&amp;gt;TimeScalesFactory&amp;lt;/code&amp;gt; as follows : &amp;lt;code&amp;gt;TimeScale scale = TimeScalesFactory.getTT();&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that for UTC scale, some data are required (the UTC-TAI shift).&lt;br /&gt;
This data can be handled through the &amp;lt;code&amp;gt;TimeScalesFactory&amp;lt;/code&amp;gt; class.&lt;br /&gt;
By default, some loaders are added to &amp;lt;code&amp;gt;TimeScalesFactory&amp;lt;/code&amp;gt; in the following order:&lt;br /&gt;
*&amp;lt;code&amp;gt;UTCTAIHistoryFilesLoader&amp;lt;/code&amp;gt;: UTC-TAI file in IERS format (file UTC-TAI.history)&lt;br /&gt;
There is no included data in PATRIUS by default&lt;br /&gt;
Once loaded, data are stored in static variables and are used for UTC time scale retrieval.&lt;br /&gt;
&lt;br /&gt;
Some reference epochs are directly available, for instance :&lt;br /&gt;
&lt;br /&gt;
* J2000 epoch (2000-01-01T12:00:00) in TT scale : &amp;lt;code&amp;gt;AbsoluteDate date = AbsoluteDate.J2000_EPOCH;&amp;lt;/code&amp;gt;&lt;br /&gt;
* julian epoch (-4712-01-01T12:00:00) in TT scale : &amp;lt;code&amp;gt;AbsoluteDate date = AbsoluteDate.JULIAN_EPOCH;&amp;lt;/code&amp;gt;&lt;br /&gt;
* fifties epoch (CNES julian dates origin, 1950-01-01T00:00:00) in TT scale : &amp;lt;code&amp;gt;AbsoluteDate date = AbsoluteDate.FIFTIES_EPOCH_TT;&amp;lt;/code&amp;gt;&lt;br /&gt;
* fifties epoch (CNES julian dates origin) in UTC scale : &amp;lt;code&amp;gt;AbsoluteDate date = AbsoluteDate.FIFTIES_EPOCH_UTC;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Java Reference epoch (1970-01-01T00:00:00) in UTC scale : &amp;lt;code&amp;gt;AbsoluteDate date = AbsoluteDate.JAVA_EPOCH;&amp;lt;/code&amp;gt;&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
=== Time Interval ===&lt;br /&gt;
This implementation for time intervals, &amp;lt;code&amp;gt;AbsoluteDateInterval&amp;lt;/code&amp;gt;, uses the &amp;lt;code&amp;gt;AbsoluteDate&amp;lt;/code&amp;gt; class as the endpoint value type.&lt;br /&gt;
&lt;br /&gt;
Infinite endpoints ( &amp;lt;code&amp;gt;AbsoluteDate.PAST_INFINITY&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;AbsoluteDate.FUTURE_INFINITY&amp;lt;/code&amp;gt; ) are supported, but as open endpoints only. Empty intervals are also forbidden.&lt;br /&gt;
&lt;br /&gt;
This implementation extends the class &amp;lt;code&amp;gt;ComparableInterval&amp;lt;/code&amp;gt;, inheriting the following operations: &lt;br /&gt;
&lt;br /&gt;
* check if two intervals are equal:&lt;br /&gt;
&amp;lt;code&amp;gt; boolean equal = interval.equals(Object) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* check if two intervals overlap:&lt;br /&gt;
&amp;lt;code&amp;gt; boolean overlaps = interval.overlaps(ComparableInterval&amp;lt;T&amp;gt;) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* check if the interval includes another interval:&lt;br /&gt;
&amp;lt;code&amp;gt; boolean includes = interval.includes(ComparableInterval&amp;lt;T&amp;gt;) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* check if the interval is connected to another interval (its lower point coincides with the upper point of the input interval, and one point is closed and the other open):&lt;br /&gt;
&amp;lt;code&amp;gt; boolean connected = interval.isConnectedTo(ComparableInterval&amp;lt;T&amp;gt;) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* compare the lower end point with the lower end point of another interval:&lt;br /&gt;
&amp;lt;code&amp;gt; int compare = interval.compareLowerEndTo(ComparableInterval&amp;lt;T&amp;gt;) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* compare the upper end point with the upper end point of another interval:&lt;br /&gt;
&amp;lt;code&amp;gt; int compare = interval.compareUpperEndTo(ComparableInterval&amp;lt;T&amp;gt;) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to inherited capabilities, the class can also:&lt;br /&gt;
&lt;br /&gt;
* compute the duration of the interval in seconds (as computed in a regular timescale- the duration has a physical meaning):&lt;br /&gt;
&amp;lt;code&amp;gt; double duration = interval.getDuration() &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* compute the duration between intervals in seconds (that is : the duration between the end of the earlier interval and the beginning of the later one):&lt;br /&gt;
&amp;lt;code&amp;gt;double duration = interval.durationFrom(AbsoluteDateInterval nextInterval) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* merge the interval with another interval if possible (the intervals must overlap or be connected to be merged):&lt;br /&gt;
&amp;lt;code&amp;gt;AbsoluteDateInterval mergedInterval = interval.mergeTo(AbsoluteDateInterval) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* get the intersection between two intervals when overlapping:&lt;br /&gt;
&amp;lt;code&amp;gt; AbsoluteDateInterval intersection = interval.getIntersectionWith(AbsoluteDateInterval) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* compare the duration of an interval with the duration of another interval:&lt;br /&gt;
&amp;lt;code&amp;gt; int compare = interval.compareDurationTo(AbsoluteDateInterval) &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* create a list of equally spaced dates within an interval:&lt;br /&gt;
** &amp;lt;code&amp;gt; List&amp;lt;AbsoluteDate&amp;gt; datesList = interval.getDateList(double) &amp;lt;/code&amp;gt; (if providing a step)&lt;br /&gt;
** &amp;lt;code&amp;gt; List&amp;lt;AbsoluteDate&amp;gt; datesList = interval.getDateList(int) &amp;lt;/code&amp;gt; (if providing a number of dates)&lt;br /&gt;
Boundaries type (open, closed) are taken into account (more information in the javadoc of these methods)&lt;br /&gt;
&lt;br /&gt;
==== List of time intervals ====&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;code&amp;gt;AbsoluteDateIntervalsList&amp;lt;/code&amp;gt; represents a list of time intervals (whose elements are &amp;lt;code&amp;gt;AbsoluteDateInterval&amp;lt;/code&amp;gt; instances).&lt;br /&gt;
As &amp;lt;code&amp;gt;AbsoluteDateInterval&amp;lt;/code&amp;gt; objects implement the &amp;lt;code&amp;gt;Comparable&amp;lt;/code&amp;gt; interface via the class &amp;lt;code&amp;gt;ComparableInterval&amp;lt;/code&amp;gt;, the time intervals in the list are automatically ordered by their lower/upper dates. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        final AbsoluteDateIntervalsList list = new AbsoluteDateIntervalsList();&lt;br /&gt;
        IntervalEndpointType open = IntervalEndpointType.OPEN;&lt;br /&gt;
        IntervalEndpointType closed = IntervalEndpointType.CLOSED;&lt;br /&gt;
        // set up the time intervals to add:&lt;br /&gt;
        final AbsoluteDateInterval i1 = new AbsoluteDateInterval(open, date1, date2, closed);&lt;br /&gt;
        final AbsoluteDateInterval i2 = new AbsoluteDateInterval(closed, date1, date3, open);      &lt;br /&gt;
        list.add(i1);&lt;br /&gt;
        list.add(i2);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the methods inherited from the &amp;lt;code&amp;gt;TreeSet&amp;lt;/code&amp;gt; class, &amp;lt;code&amp;gt;AbsoluteDateIntervalsList&amp;lt;/code&amp;gt; can also:&lt;br /&gt;
&lt;br /&gt;
* tell which time intervals in the list contain a predetermined date:&lt;br /&gt;
&amp;lt;code&amp;gt;AbsoluteDateIntervalsList  intervals = list.getIntervalsContainingDate(date)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* compute the shortest interval containing all the intervals belonging to the list:&lt;br /&gt;
&amp;lt;code&amp;gt;AbsoluteDateInterval inclusiveInterval = list.getInclusiveInterval(); &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* compute the list of complementary intervals of the given intervals list:&lt;br /&gt;
&amp;lt;code&amp;gt;AbsoluteDateIntervalsList complementaryList = list.getComplementaryIntervals();&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please see the Javadoc for more information.&lt;br /&gt;
&lt;br /&gt;
=== Local time and solar time ===&lt;br /&gt;
Local time is represented by the angle between the projections of the Earth-Sun vector and the Earth-Spacecraft vector in the equatorial plane. Local time is expressed in hours and its value is 12h when this angle is 0 rad. Beware, in PATRIUS, local time is always expressed as an angle in the range [-PI; PI[ and always represents the angle between the projections of the Earth-Sun vector and the Earth-Spacecraft vector in the equatorial plane. If one wants to retrieve local time (in hours) from the local time angle provided by PATRIUS, the following formula should be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;Local time = 12h + local time angle* 12 / Pi.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Local time increases for prograde orbits and decreases for retrograde orbits.&lt;br /&gt;
&lt;br /&gt;
Similarly, solar time is represented by the angle between the Earth-Sun projection in the orbital plane and the Earth-Spacecraft vector. Solar time is expressed in hours and its value is 12h when this angle is 0 rad. Beware, in PATRIUS, solar time is always expressed as an angle in the range [-PI; PI[ and always represents the angle between the Earth-Sun projection in the orbital plane and the Earth-Spacecraft vector. If one wants to retrieve solar time (in hours) from the solar time angle provided by PATRIUS, the following formula should be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;Solar time = 12h + solar time angle* 12 / Pi.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Solar time always increases with time. It is mesured around the orbit momentum.&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;code&amp;gt;LocalTimeAngle&amp;lt;/code&amp;gt; provides methods to compute:&lt;br /&gt;
* True local time angle using &amp;lt;code&amp;gt;computeTrueLocalTimeAngle()&amp;lt;/code&amp;gt;. Local time is always computed in TIRF frame. True local time is represented by the angle between projection of satellite position and Sun position over the equatorial plane in provided frame. Returned time is expressed in seconds in the range [-PI; PI[.&lt;br /&gt;
* Mean local time angle using &amp;lt;code&amp;gt;computeMeanLocalTimeAngle()&amp;lt;/code&amp;gt;. Local time angle is always computed in TIRF frame. Mean local time is the sum of true local time and equation of time (EOT):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;Mean local time = True local time + EOT&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Equation of time using &amp;lt;code&amp;gt;computeEquationOfTime()&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
Equation of time is true local time of GMST ([0; 0; 1] vector in TIRF frame) minus seconds in the date:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;EOT =-(Local time GMST - sec)&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Equation of time is periodic over one year in the range [-16min; +14min]:&lt;br /&gt;
&lt;br /&gt;
[[File:EquationOfTime.png|center]]&lt;br /&gt;
&lt;br /&gt;
* RAAN from local true/mean time with methods &amp;lt;code&amp;gt;computeRAANFromMeanLocalTime&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;computeRAANFromTrueLocalTime&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
==== AbsoluteDateInterval ====&lt;br /&gt;
&lt;br /&gt;
Here is given a code example on how to use the &amp;lt;code&amp;gt;AbsoluteDateInterval&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        final AbsoluteDate t1 = new AbsoluteDate(&amp;quot;1969-11-03&amp;quot;, TimeScalesFactory.getTT());&lt;br /&gt;
        final AbsoluteDate t2 = new AbsoluteDate(&amp;quot;1969-11-04&amp;quot;, TimeScalesFactory.getTT());&lt;br /&gt;
        final AbsoluteDate t3 = new AbsoluteDate(&amp;quot;1969-11-06&amp;quot;, TimeScalesFactory.getTT());&lt;br /&gt;
        final AbsoluteDate t4 = new AbsoluteDate(&amp;quot;1969-11-07&amp;quot;, TimeScalesFactory.getTT());&lt;br /&gt;
        final IntervalEndpointType open = IntervalEndpointType.OPEN;&lt;br /&gt;
        final double dayInSeconds = Constants.JULIAN_DAY;&lt;br /&gt;
        // Two separated intervals, two days of separation :&lt;br /&gt;
        // ..] t1 ; t2 [....] t3 ; t4 [..&lt;br /&gt;
        final AbsoluteDateInterval ad1A = new AbsoluteDateInterval(open, t1, t2, open);&lt;br /&gt;
        final AbsoluteDateInterval ad1B = new AbsoluteDateInterval(open, t3, t4, open);&lt;br /&gt;
        final double dur11 = ad1B.durationFrom(ad1A);&lt;br /&gt;
        final double dur12 = ad1A.durationFrom(ad1B);&lt;br /&gt;
        // ad1B begins 2 days after ad1A ends : duration from is + 2 days&lt;br /&gt;
        Assert.assertEquals(2.* dayInSeconds, dur11, 0.);&lt;br /&gt;
        // ad1A ends 2 days before ad1B begins : duration from is- 2 days&lt;br /&gt;
        Assert.assertEquals(-2.* dayInSeconds, dur12, 0.);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TimeScale&#039;&#039;&#039;&lt;br /&gt;
|Interface for time scales.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/TimeScale.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TimeStamped&#039;&#039;&#039;&lt;br /&gt;
|This interface represents objects that have a AbsoluteDate  date attached to them.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/TimeStamped.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbsoluteDate&#039;&#039;&#039;&lt;br /&gt;
|This class represents a specific instant in time.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/AbsoluteDate.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbsoluteDateInterval&#039;&#039;&#039;&lt;br /&gt;
|This class implements an interval based on the AbsoluteDate class.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/AbsoluteDateInterval.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbsoluteDateIntervalsList&#039;&#039;&#039;&lt;br /&gt;
|This class represents a list of AbsoluteDateInterval objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/AbsoluteDateIntervalsList.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ChronologicalComparator&#039;&#039;&#039;&lt;br /&gt;
|Comparator for TimeStamped instance.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/ChronologicalComparator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ComparableInterval&#039;&#039;&#039;&lt;br /&gt;
|Class describing an interval of Comparable data.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/interval/ComparableInterval.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DateComponents&#039;&#039;&#039;&lt;br /&gt;
|Class representing a date broken up as year, month and day components.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/DateComponents.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DateTimeComponents&#039;&#039;&#039;&lt;br /&gt;
|Holder for date and time components.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/DateTimeComponents.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GalileoScale&#039;&#039;&#039;&lt;br /&gt;
|Galileo system time scale.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/GalileoScale.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GenericInterval&#039;&#039;&#039;&lt;br /&gt;
|Generic class to describe an interval.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/utils/GenericInterval.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GMSTScale&#039;&#039;&#039;&lt;br /&gt;
|Greenwich Mean Sidereal Time.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/GMSTScale.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GPSScale&#039;&#039;&#039;&lt;br /&gt;
|GPS time scale.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/GPSScale.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TAIScale&#039;&#039;&#039;&lt;br /&gt;
|International Atomic Time.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/TAIScale.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TCBScale&#039;&#039;&#039;&lt;br /&gt;
|Barycentric Coordinate Time.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/TCBScale.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TCGScale&#039;&#039;&#039;&lt;br /&gt;
|Geocentric Coordinate Time.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/TCGScale.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TDBScale&#039;&#039;&#039;&lt;br /&gt;
|Barycentric Dynamic Time.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/TDBScale.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TimeComponents&#039;&#039;&#039;&lt;br /&gt;
|Class representing a time within the day broken up as hour, minute and second components.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/TimeComponents.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TimeScalesFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory for predefined time scales.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/TimeScalesFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TTScale&#039;&#039;&#039;&lt;br /&gt;
|Terrestrial Time as defined by IAU(1991) recommendation IV.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/TTScale.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UT1Scale&#039;&#039;&#039;&lt;br /&gt;
|Universal Time 1.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/UT1Scale.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UTCScale&#039;&#039;&#039;&lt;br /&gt;
|Coordinated Universal Time.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/UTCScale.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LocalTimeAngle&#039;&#039;&#039;&lt;br /&gt;
|Local time angle computation methods.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/time/LocalTimeAngle.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Tutorials ==&lt;br /&gt;
=== Tutorial 1 ===&lt;br /&gt;
[[DatesTutorials|Tutoriel sur les dates]]&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_SpacecraftState&amp;diff=4149</id>
		<title>User Manual 4.18 SpacecraftState</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_SpacecraftState&amp;diff=4149"/>
		<updated>2026-06-10T08:57:45Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === This section describes the SpacecraftState object.   === Javadoc === The object [{{JavaDoc4.18}}//fr/cnes/sirius/patrius/propagation/SpacecraftState.html SpacecraftState] is available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.propagation&amp;lt;/code&amp;gt;.   === Links === Here is only described the SpacecraftState structure.  Please refer to [ORB_PRO_Home propagation chapter].  === Useful Documents === None as of now.  === Overv... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes the SpacecraftState object. &lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The object [{{JavaDoc4.18}}//fr/cnes/sirius/patrius/propagation/SpacecraftState.html SpacecraftState] is available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.propagation&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
Here is only described the SpacecraftState structure. &lt;br /&gt;
Please refer to [ORB_PRO_Home propagation chapter].&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
The [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/propagation/SpacecraftState.html SpacecraftState] is composed of :&amp;lt;br&amp;gt;&lt;br /&gt;
- an [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/Orbit.html orbit]&amp;lt;br&amp;gt;&lt;br /&gt;
- an [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/Attitude.html attitude for forces computation] &amp;lt;br&amp;gt;&lt;br /&gt;
- an [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/Attitude.html attitude for events computation]&amp;lt;br&amp;gt;&lt;br /&gt;
- a map of additional states (including mass states added from [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/propagation/MassProvider.html MassProvider]).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Two attitudes are stored in order to apply (if needed) a different treatment to each attitude.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== One orbit ===&lt;br /&gt;
The [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/propagation/SpacecraftState.html SpacecraftState] is composed of one [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/Orbit.html Orbit].&lt;br /&gt;
It is possible to simply declare a SpacecraftState with an orbit :&lt;br /&gt;
&amp;lt;code&amp;gt;final SpacecraftState state = new SpacecraftState(orbit);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The orbit could be updated using the following method :&lt;br /&gt;
&amp;lt;code&amp;gt;final SpacecraftState newState = state.updateOrbit(newOrbit);&amp;lt;/code&amp;gt;&lt;br /&gt;
The attitude and additional states will remain the same and a new SpacecraftState will be created.&lt;br /&gt;
&lt;br /&gt;
=== Two attitudes ===&lt;br /&gt;
The user can use one single &lt;br /&gt;
&lt;br /&gt;
[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/Attitude.html Attitude] or two different [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/Attitude.html Attitude] objects : one for forces computation and one for events computation. The following constructor can be used :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;final SpacecraftState state = new SpacecraftState(orbit, attitudeForces, attitudeEvents);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is possible to get the attitude for forces or events computation using the following methods:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final Attitude attForces = state.getAttitudeForces();&lt;br /&gt;
final Attitude attEvents = state.getAttitudeEvents();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The user can deals with a single attitude in the SpacecraftState using the following constructor: &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final SpacecraftState state = new SpacecraftState(orbit, attitude);&lt;br /&gt;
final Attitude att = state.getAttitude();&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the following constructor is used, both attitudes are set to null value: &lt;br /&gt;
&amp;lt;code&amp;gt;final SpacecraftState state = new SpacecraftState(orbit);&amp;lt;/code&amp;gt;&lt;br /&gt;
Then calling &amp;lt;code&amp;gt;getAttitude&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;getAttitudeForces&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;getAttitudeEvents&amp;lt;/code&amp;gt; will return null attitude.&lt;br /&gt;
&lt;br /&gt;
=== Additional states ===&lt;br /&gt;
The additional states are stored in the SpacecraftState using a Map with the additional states names as keys. The additional states are in the type &amp;lt;code&amp;gt;double[]&amp;lt;/code&amp;gt;.&lt;br /&gt;
The additional states map could be given directly to the constructor as follow : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;Map&amp;lt;String, double[]&amp;gt; addStates = new HashMap&amp;lt;String, double[]&amp;gt;();&lt;br /&gt;
addStates.put(&amp;quot;name&amp;quot;, new double[]{1.0});&lt;br /&gt;
SpacecraftState state = new SpacecraftState(orbit, attitudeForces, attitudeEvents, addStates); &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is possible to add an additional state to a SpacecraftState using&#039;&#039;&#039;&#039;&#039;addAdditionalState&#039;&#039;&#039;&#039;&#039;: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;state2 = state.addAdditionalState(&amp;quot;name2&amp;quot;, new double[]{0.1, 0.1});&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note :&#039;&#039;&#039;&#039;&#039;addAdditionalState&#039;&#039;&#039;&#039;&#039; returns a new SpacecraftState with the added additional state. It is necessary to store the returned object. The additional state is not added to the current state.&lt;br /&gt;
&lt;br /&gt;
=== Mass ===&lt;br /&gt;
A [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/propagation/MassProvider.html MassProvider] can be provided to the SpacecraftState. In that case, the mass information are automaticaly stored as additional states. Be careful, the mass values can never be negative: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final SpacecraftState state = new SpacecraftState(orbit, massProvider);&lt;br /&gt;
final SpacecraftState state = new SpacecraftState(orbit, attitudeForces, attitudeEvents, massProvider, addStates); &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The mass provider can be added to the SpacecraftState after its initilisation with the method &amp;lt;code&amp;gt;addMassProvider&amp;lt;/code&amp;gt; :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final SpacecraftState state = new SpacecraftState(orbit);&lt;br /&gt;
final SpacecraftState newState = state.addMassProvider(massProvider);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The mass parts from MassProvider are added to additional states map with the key : &amp;quot;MASS_&amp;lt;partName&amp;gt;&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The total mass of the SpacecraftState could not be obtained. &lt;br /&gt;
&lt;br /&gt;
It is possible to obtain the mass of a given part :&lt;br /&gt;
&amp;lt;code&amp;gt;state.getMass(&amp;quot;part1&amp;quot;); &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and to update the mass of a given part :&lt;br /&gt;
&amp;lt;code&amp;gt;state.updateMass(&amp;quot;part1&amp;quot;, 1000.0); &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== State vector ===&lt;br /&gt;
The [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/propagation/SpacecraftState.html SpacecraftState] object could be created from a state vector :&lt;br /&gt;
&amp;lt;code&amp;gt;final SpacecraftState state = new SpacecraftState(stateVector, OrbitType.CARTESIAN, PositionAngle.MEAN, date, mu, frame, addStatesInfo, attProviderForces, attProviderEvents);&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To build the SpacecraftState, it is necessary to know the size and the index of all additional states in the state vector. This information could be obtained from an old state using the following method : &lt;br /&gt;
&amp;lt;code&amp;gt;final Map&amp;lt;String, AdditionalStateInfo&amp;gt; addStatesInfos = state.getAdditionalStatesInfos();&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The state vector could be obtained from a SpacecraftState :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final double[] stateVector = new double[]{};&lt;br /&gt;
state.mapStateToArray(OrbitType.CARTESIAN, PositionAngle.MEAN, stateVector); &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Transform ===&lt;br /&gt;
&lt;br /&gt;
The [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/propagation/SpacecraftState.html SpacecraftState] class contains methods to compute the following transformations :&lt;br /&gt;
- &amp;lt;code&amp;gt;toTransform()&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;toTransformForces()&amp;lt;/code&amp;gt; : Transform from orbit/attitude reference frame to spacecraft frame (attitude used for forces computation which is the default attitude).&amp;lt;br&amp;gt;&lt;br /&gt;
- &amp;lt;code&amp;gt;toTransformEvents()&amp;lt;/code&amp;gt; : Transform from orbit/attitude reference frame to spacecraft frame attitude used for events computation (same as toTransform if there is no specific attitude for Events).&lt;br /&gt;
- &amp;lt;code&amp;gt;toTransform(Frame)&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;toTransformForces(Frame)&amp;lt;/code&amp;gt; : Transform from specified [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/Frame.html Frame] to spacecraft frame (attitude used for forces computation which is the default attitude).&amp;lt;br&amp;gt;&lt;br /&gt;
- &amp;lt;code&amp;gt;toTransformEvents(Frame)&amp;lt;/code&amp;gt; : Transform from specified [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/Frame.html Frame] to spacecraft frame attitude used for events computation (same as toTransform(Frame) if there is no attitude specific for Events).&amp;lt;br&amp;gt;&lt;br /&gt;
- &amp;lt;code&amp;gt;toTransform(LOFType)&amp;lt;/code&amp;gt; : Transform from orbit/attitude reference frame to local orbital frame ([{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/LOFType.html LOFType]).&amp;lt;br&amp;gt;&lt;br /&gt;
- &amp;lt;code&amp;gt;toTransform(Frame, LOFType)&amp;lt;/code&amp;gt; : Transform from specified [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/Frame.html Frame] to local orbital frame ([{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/LOFType.html LOFType]).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Using Transform ===&lt;br /&gt;
&lt;br /&gt;
Here after is presented the computation of a station position in spacecraft frame:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Station position defined in GCRF&lt;br /&gt;
final Vector3D station_InGCRF = new Vector3D(Constants.EGM96_EARTH_EQUATORIAL_RADIUS, 0, 0);&lt;br /&gt;
final Frame gcrf = FramesFactory.getGCRF();&lt;br /&gt;
// Compute transform from GCRF to spacecraft frame&lt;br /&gt;
final Transform transform = state.toTransform(gcrf);&lt;br /&gt;
// Station position in spacecraft frame&lt;br /&gt;
final Vector3D station_InSpacecraftFrame = transform.transformVector(station_InGCRF);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here after is presented the computation of the Sun direction in spacecraft frame.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Compute transform from orbit/attitude reference frame to local orbital frame TNW&lt;br /&gt;
final Transform transform = state.toTransform(LOFType.TNW);&lt;br /&gt;
// Position of Sun in local orbital frame TNW&lt;br /&gt;
final Vector3D pos = transform.transformPosition(sun.getPVCoordinates().getPosition());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
If an [{{JavaDoc4.18}}//fr/cnes/sirius/patrius/assembly/Assembly.html Assembly] is used, this is not necessary to use these methods because the conversion methods are included in Assembly functionalities (see [SPC_VBU_Home dedicated User Manual]).&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MassProvider&#039;&#039;&#039;&lt;br /&gt;
|Interface providing the mass for spacecraft models.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/propagation/MassProvider.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SpacecraftState&#039;&#039;&#039;&lt;br /&gt;
|This class is the representation of a complete state holding orbit, attitude for forces and for events computation and additional states at a given date.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/propagation/SpacecraftState.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Attitude&#039;&#039;&#039;&lt;br /&gt;
|Object representing the attitude of the spacecraft for a specific date and in a specific frame.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/attitudes/Attitude.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Orbits&amp;diff=4148</id>
		<title>User Manual 4.18 Orbits</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Orbits&amp;diff=4148"/>
		<updated>2026-06-10T08:57:21Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__ == Introduction == === Scope === The &amp;quot;orbits&amp;quot; package contains classes to represent the orbital state of a spacecraft at a given time. Several types of orbits are available (cartesian, keplerian, equinoctial...). The jacobian matrix for each orbital parameter / cartesian parameter conversion are also available for their current value.  An &amp;quot;Orbit&amp;quot; (implementing &amp;quot;Orbit&amp;quot; class) object is not to be misunderstood with an &amp;quot;Orbital parameters&amp;quot; object (implemen... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The &amp;quot;orbits&amp;quot; package contains classes to represent the orbital state of a spacecraft at a given time. Several types of orbits are available (cartesian, keplerian, equinoctial...).&lt;br /&gt;
The jacobian matrix for each orbital parameter / cartesian parameter conversion are also available for their current value.&lt;br /&gt;
&lt;br /&gt;
An &amp;quot;Orbit&amp;quot; (implementing &amp;quot;Orbit&amp;quot; class) object is not to be misunderstood with an &amp;quot;Orbital parameters&amp;quot; object (implement &amp;quot;IOrbitalParameters&amp;quot; interface). An orbit uses as attributes:&lt;br /&gt;
* Orbital parameters&lt;br /&gt;
* A date&lt;br /&gt;
* A frame (not necessarily inertial or pseudo-inertial)&lt;br /&gt;
&lt;br /&gt;
For more information about orbital parameters, please refer to [FDY_PARAM_Home Orbital parameters].&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The classes for orbits description are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.orbits&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
| Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/package-summary.html Package fr.cnes.sirius.patrius.orbits]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
All different orbits types extend the abstract generic Orbit class (the following class package may not contain all classes extending Orbit class).&lt;br /&gt;
&lt;br /&gt;
[[File:orbits.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
The enum &amp;quot;PositionAngle&amp;quot; lists the three types of position angle (anomaly, alpha angle...) available : TRUE, MEAN, ECCENTRIC.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Available orbit types ===&lt;br /&gt;
The available orbit types are :&lt;br /&gt;
* Cartesian  : X, Y, Z, Vx, Vy, Vz (including also acceleration Ax, Ay, Az)&lt;br /&gt;
* Keplerian : a, e, i, perigee argument, right ascension of ascending node, anomaly (in each position angle types)&lt;br /&gt;
* Equinoctial : a, ex, ey (eccentricity vector), hx, hy (inclination vector), true longitude argument (in each position angle types)&lt;br /&gt;
* Alternate equinoctial : n (mean motion), ex, ey (eccentricity vector), hx, hy (inclination vector), longitude argument (in each position angle types, but stored in mean)&lt;br /&gt;
* Circular : a, ex, ey (eccentricity vector), i, right ascension of ascending node, true latitude argument (in each position angle types)&lt;br /&gt;
* Apsis : periapsis, apoapsis, i, perigee argument, right ascension of ascending node, anomaly (in each position angle types)&lt;br /&gt;
* Equatorial : a, e, longitude of the periapsis (ω + Ω), ix (first component of inclination vector), iy (second component of inclination vector), anomaly (in each position angle types)&lt;br /&gt;
&lt;br /&gt;
=== Jacobians ===&lt;br /&gt;
For each orbital parameter type (keplerian, equinoctial, circular, apsis, equatorial), the jacobian matrices &amp;quot;orbital parameters with respect to cartesian parameters&amp;quot; and &amp;quot;cartesian parameters with respect to orbital parameters&amp;quot; are available.&lt;br /&gt;
The jacobian matrix related to the conversion between an orbital parameter type A to an orbital parameter type B is also available (computed by getJacobian method) for each orbital parameter type.&lt;br /&gt;
&lt;br /&gt;
For all except the equinoctial and equatorial parameters, the &amp;quot;with respect to cartesian parameters&amp;quot; jacobian (getJacobianWrtCartesian method) is computed with direct analytic methods, and the &amp;quot;with respect to orbital parameters&amp;quot; (getJacobianWrtParameters method) obtained by computing the inverse of the previous one.&lt;br /&gt;
For the equinoctial and equatorial parameters, both computations are direct and analytic.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
Any orbit can be defined using the chosen constructor. Here is an to define a circular orbit:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final KeplerianParameters keplerianParameters = new KeplerianParameters(10000E3, 0.1, 0.2, 0.3, 0.4, 0.5, PositionAngle.TRUE, Constants.EGM96_EARTH_MU);&lt;br /&gt;
final CircularOrbit orbit = new CircularOrbit(keplerianParameters, FramesFactory.getEME2000(), date);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Internal parameters of circular orbits are circular parameters. They can be retrieved and converted using conversion routines provided by [[User_Manual_4.1_Orbital_parameters|Orbital parameters]] objects:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final CartesianParameters cartesianParameters = orbit.getParameters().getCartesianParameters();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Orbit&#039;&#039;&#039;&lt;br /&gt;
|Abstract class for all orbits.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/Orbit.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CartesianOrbit&#039;&#039;&#039;&lt;br /&gt;
|Instant orbit described by its cartesian parameters.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/CartesianOrbit.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;KeplerianOrbit&#039;&#039;&#039;&lt;br /&gt;
|Instant orbit described by its keplerian parameters.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/KeplerianOrbit.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CircularOrbit&#039;&#039;&#039;&lt;br /&gt;
|Instant orbit described by its circular parameters.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/CircularOrbit.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EquinoctialOrbit&#039;&#039;&#039;&lt;br /&gt;
|Instant orbit described by its equinoctial parameters.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/EquinoctialOrbit.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AlternateEquinoctialOrbit&#039;&#039;&#039;&lt;br /&gt;
|Instant orbit described by its equinoctial parameters.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/AlternateEquinoctialOrbit.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EquatorialOrbit&#039;&#039;&#039;&lt;br /&gt;
|Instant orbit described by its equatorial parameters.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/EquatorialOrbit.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ApsisOrbit&#039;&#039;&#039;&lt;br /&gt;
|Instant orbit described by its apsis parameters.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/ApsisOrbit.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Orbital_parameters&amp;diff=4147</id>
		<title>User Manual 4.18 Orbital parameters</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Orbital_parameters&amp;diff=4147"/>
		<updated>2026-06-10T08:56:55Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction ==  === Scope === The &amp;quot;Orbital parameters&amp;quot; package contains classes to represent the orbital state of a space object. Several types of parameters are available (cartesian, keplerian, equinoctial... with different position angle definitions : true, mean, eccentric). Orbital parameters do not define a date nor a frame. To fully define an orbit, including date and frame, please refer to [FDY_Orbits_Home Orbits].  === Javadoc === The classe... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The &amp;quot;Orbital parameters&amp;quot; package contains classes to represent the orbital state of a space object. Several types of parameters are available (cartesian, keplerian, equinoctial... with different position angle definitions : true, mean, eccentric).&lt;br /&gt;
Orbital parameters do not define a date nor a frame. To fully define an orbit, including date and frame, please refer to [FDY_Orbits_Home Orbits].&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The classes for orbital parameters description are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.orbits.orbitalparameters&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
| Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/orbitalparameters/package-summary.html Package fr.cnes.sirius.patrius.orbits.orbitalparameters]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
All different orbital parameters types extend the abstract class AbstractOrbitalParameters and implement the interface IOrbitalParameters (the following class package may not contain all classes extending AbstractOrbitalParameters class).&lt;br /&gt;
&lt;br /&gt;
[[File:orbitalparameters.png|center]]&lt;br /&gt;
&lt;br /&gt;
All conversions methods from one type to another are specifically handled by each type of orbital parameters, thus optimising conversions.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Available parameters ===&lt;br /&gt;
The available parameters types are :&lt;br /&gt;
* Cartesian  : X, Y, Z, Vx, Vy, Vz&lt;br /&gt;
* Keplerian : a, e, i, perigee argument, right ascension of ascending node, anomaly (in each position angle types)&lt;br /&gt;
* Equinoctial : a, ex, ey (eccentricity vector), hx, hy (inclination vector), longitude argument (in each position angle types)&lt;br /&gt;
* Alternate equinoctial : n (mean motion), ex, ey (eccentricity vector), hx, hy (inclination vector), longitude argument (in each position angle types but stored in mean)&lt;br /&gt;
* Stela Equinoctial : a, ex, ey (eccentricity vector), ix, iy (inclination vector), mean longitude argument&lt;br /&gt;
* Circular : a, ex, ey (eccentricity vector), i, right ascension of ascending node, latitude argument (in each position angle types)&lt;br /&gt;
* Apsis (using radius) : periapsis, apoapsis, i, perigee argument, right ascension of ascending node, anomaly (in each position angle types)&lt;br /&gt;
* Apsis (using altitude) : altitude of periapsis, altitude of apoapsis, i, perigee argument, right ascension of ascending node, anomaly (in each position angle types)&lt;br /&gt;
* Equatorial : a, e, longitude of the periapsis (ω + Ω), ix (first component of inclination vector), iy (second component of inclination vector), anomaly (in each position angle types)&lt;br /&gt;
* Reentry : altitude, latitude, longitude, velocity norm, slope of velocity, azimuth of velocity&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
Any orbital parameters can be defined using the chosen constructor. Here is an example using circular parameters and true anomaly:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final CircularParameters circularParameters = new CircularParameters(10000E3, 0.1, 0.2, 0.3, 0.4, 0.5, PositionAngle.TRUE, Constants.EGM96_EARTH_MU);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then conversions to any orbital parameters type can directly be obtained using the conversion routines. Here is an example of conversion to equinoctial parameters:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final EquinoctialParameters equinoctialParameters = circularParameters .getEquinoctialParameters();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CartesianParameters&#039;&#039;&#039;&lt;br /&gt;
|Cartesian parameters object.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/orbitalparameters/CartesianParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;KeplerianParameters&#039;&#039;&#039;&lt;br /&gt;
|Keplerian parameters object.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/orbitalparameters/KeplerianParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CircularParameters&#039;&#039;&#039;&lt;br /&gt;
|Circular parameters object.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/orbitalparameters/CircularParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EquinoctialParameters&#039;&#039;&#039;&lt;br /&gt;
|Equinoctial parameters object.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/orbitalparameters/EquinoctialParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AlternateEquinoctialParameters&#039;&#039;&#039;&lt;br /&gt;
|Alternate Equinoctial parameters object.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/orbitalparameters/AlternateEquinoctialParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;StelaEquinoctialParameters&#039;&#039;&#039;&lt;br /&gt;
|Stela equinoctial parameters object.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/orbitalparameters/StelaEquinoctialParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EquatorialParameters&#039;&#039;&#039;&lt;br /&gt;
|Equatorial parameters object.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/orbitalparameters/EquatorialParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ApsisRadiusParameters&#039;&#039;&#039;&lt;br /&gt;
|Apsis parameters object (using radius).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/orbitalparameters/ApsisRadiusParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ApsisAltitudeParameters&#039;&#039;&#039;&lt;br /&gt;
|Apsis parameters object (using altitude).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/orbitalparameters/ApsisAltitudeParameters.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ReentryParameters&#039;&#039;&#039;&lt;br /&gt;
|Reentry parameters object.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/orbits/orbitalparameters/ReentryParameters.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Frames_configuration&amp;diff=4146</id>
		<title>User Manual 4.18 Frames configuration</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Frames_configuration&amp;diff=4146"/>
		<updated>2026-06-10T08:56:37Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__ == Introduction == === Scope === Frames configuration defines the models and data to use for each frame transformation. Several frames configurations are already available in PATRIUS (IERS 2003, IERS 2010, STELA? etc.) but the user may define its own convention.  === Javadoc === {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=&amp;quot;col&amp;quot;| Javadoc |- |Patrius |[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/package-summary.html Package fr.c... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
Frames configuration defines the models and data to use for each frame transformation.&lt;br /&gt;
Several frames configurations are already available in PATRIUS (IERS 2003, IERS 2010, STELA? etc.) but the user may define its own convention.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/package-summary.html Package fr.cnes.sirius.patrius.frames.configuration]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/package-summary.html Package fr.cnes.sirius.patrius.frames.configuration.eop]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/tides/package-summary.html Package fr.cnes.sirius.patrius.frames.configuration.tides]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/libration/package-summary.html Package fr.cnes.sirius.patrius.frames.configuration.libration]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/precessionnutation/package-summary.html Package fr.cnes.sirius.patrius.frames.configuration.precessionnutation]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
* [http://www.iers.org/IERS/EN/Home/home_node.html IERS website]&lt;br /&gt;
* [http://www.iers.org/IERS/EN/Publications/TechnicalNotes/tn36.html IERS 2010 Conventions]&lt;br /&gt;
* [http://www.iers.org/IERS/EN/Publications/TechnicalNotes/tn32.html IERS 2003 Conventions]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
&lt;br /&gt;
=== The Frames Configuration ===&lt;br /&gt;
In PATRIUS, a Frames configuration is defined as a set of models that are used to compute transformations between different frames. As of now, these models define the transformations between the frames defined by the IERS (see [http://www.iers.org/IERS/EN/Publications/TechnicalNotes/tn36.html/ IERS TN36 Ch. 5]). Thus, the configuration holds all the models required to transform a position or a velocity from the International Terrestrial Reference System (ITRS) and the Geocentric Celestial Reference System (GCRS) and vice versa.&lt;br /&gt;
&lt;br /&gt;
When no configuration is created by the user, PATRIUS uses the IERS 2010 convention. Note that this convention requires to provide EOP data. The library also allows the user to create configurations by setting up the adequate models.&lt;br /&gt;
&lt;br /&gt;
The FramesConfigurationFactory contains public static instances of standard configurations, amongst which:&lt;br /&gt;
* the configuration following the IERS 2010 conventions.&lt;br /&gt;
* A simple configuration which can be retrieved by calling &amp;lt;code&amp;gt;FramesConfigurationFactory.getSimpleConfiguration(boolean)&amp;lt;/code&amp;gt;. This configuration is useful because it removes the need for EOP data. Depending on the value of the provided boolean, this configuration leads to the following equalities:&lt;br /&gt;
** Boolean = true (use of EOP models): GCRF != CIRF, TIRF = ITRF&lt;br /&gt;
** Boolean = false (no use of EOP models): GCRF == CIRF, TIRF = ITRF. Hence only Earth Rotation Angle is taken into account from GCRF to ITRF frame.&lt;br /&gt;
&lt;br /&gt;
==== The default configuration (IERS2010) ====&lt;br /&gt;
&lt;br /&gt;
The default configuration (IERS2010) is convenient for most applications. In this case, no operation pertaining to frames configurations needs to be undertaken. At the first call requiring frames, the [{{JavaDoc4.18}}/FramesFactory fr/cnes/sirius/patrius/frames/FramesFactory.html] FramesFactory will create the default configuration and use it accordingly.&lt;br /&gt;
&lt;br /&gt;
The code snippet below is valid as long as the user has NOT passed a custom configuration to the FramesFactory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
/* &lt;br /&gt;
/* Example of frame transformations using IERS2010 convention&lt;br /&gt;
/*/&lt;br /&gt;
// instance of ITRF with the default configuration (IERS2010)&lt;br /&gt;
final Frame itrf = FramesFactory.getITRF();&lt;br /&gt;
// instance of GCRF with the default configuration (IERS2010)&lt;br /&gt;
final Frame gcrf = FramesFactory.getGCRF();&lt;br /&gt;
// transformation relating ITRS to GCRS at currentDate (supposed as already defined)&lt;br /&gt;
final Transform itrfTransform = itrf.getTransformTo(gcrf, currentDate);&lt;br /&gt;
// transformed currentPV (supposed as already defined)&lt;br /&gt;
final PVCoordinates Vtransformed = itrfTransform.transformPVCoordinates(currentPV);&lt;br /&gt;
// ...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The default IERS 2010 configuration is as follows  :&lt;br /&gt;
&lt;br /&gt;
* IERS 2010 tidal correction model&lt;br /&gt;
* IERS 2010 libration correction model&lt;br /&gt;
* IERS 2010 S&#039; model&lt;br /&gt;
* account of EOP UT1-UTC and pole corrections&lt;br /&gt;
* IERS 2010 precession and nutation (interpolated computation) with nutation correction to &#039;&#039;X&#039;&#039; and &#039;&#039;Y&#039;&#039; and account of angular derivatives.&lt;br /&gt;
&lt;br /&gt;
==== Creating a customised configuration ====&lt;br /&gt;
&lt;br /&gt;
PATRIUS allows creating customized configurations to define the intermediate transformations relating ITRS to TIRS, TIRS to CIRS and CIRS to GCRS.&lt;br /&gt;
&lt;br /&gt;
===== Transformation relating ITRS to TIRS =====&lt;br /&gt;
&lt;br /&gt;
Based on polar motion, it can be expressed as:&lt;br /&gt;
&amp;lt;math&amp;gt;W(t)=R3(-s&#039;).R2(xp).R1(yp)&amp;lt;/math&amp;gt;,&lt;br /&gt;
where &#039;&#039;xp&#039;&#039; and &#039;&#039;yp&#039;&#039; are the polar coordinates of the Celestial Intermediate Pole (CIP) in the ITRS and &#039;&#039;s&#039;&#039;&#039; is called the &amp;quot;Terrestrial Intermediate Origin locator&amp;quot;. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The user can define the following parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* polar motion (yes/no),&lt;br /&gt;
* interpolation method  for &#039;&#039;xp&#039;&#039; and &#039;&#039;yp&#039;&#039; (linear or Lagrange 4),&lt;br /&gt;
* account of ocean tidal effect &#039;&#039;(dx,dy),,ocean tides,,&#039;&#039; in polar motion (IERS2010, IERS2003 or no effect),&lt;br /&gt;
* account of libration effect &#039;&#039;(dx,dy),,libration,,&#039;&#039; in polar motion (IERS2010 or no effect),&lt;br /&gt;
* account of the quantity &#039;&#039;s&#039;&#039;&#039; (IERS2010, IERS2003 or no effect). &lt;br /&gt;
&lt;br /&gt;
To create a polar motion model with chosen parameters, PATRIUS provides the constructor &#039;&#039;&#039;PolarMotion&#039;&#039;&#039; (see [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/PolarMotion.html PolarMotion javadoc] for the description of the above parameters).&lt;br /&gt;
&lt;br /&gt;
===== Transformation relating TIRS to CIRS =====&lt;br /&gt;
&lt;br /&gt;
Based on the rotation of the Earth around the axis of the CIP, it can be expressed as:&lt;br /&gt;
&amp;lt;math&amp;gt;R(t)=R3(-ERA)&amp;lt;/math&amp;gt;,&lt;br /&gt;
where &#039;&#039;ERA&#039;&#039; is the Earth Rotation Angle between the CIO and the TIO.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The user can define the following parameters:&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
* account of &#039;&#039;UT1-UTC&#039;&#039; (yes or no),&lt;br /&gt;
* interpolation method for &#039;&#039;UT1-UTC&#039;&#039; (linear or Lagrange 4),&lt;br /&gt;
* account of ocean tidal effect &#039;&#039;dUT1,,ocean tides,,&#039;&#039; in &#039;&#039;UT1&#039;&#039; (IERS2010, IERS2003 or no effect),&lt;br /&gt;
*account of libration effect &#039;&#039;dUT1,,libration,,&#039;&#039; in &#039;&#039;UT1&#039;&#039; (IERS2010 or no effect).&#039;&#039;&#039;Note that this effect is not yet implemented. It is negligible in current practical applications due to its very small size&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
To create a diurnal rotation model with chosen parameters, PATRIUS provides the constructor &#039;&#039;&#039;DiurnalRotation&#039;&#039;&#039; (see [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/DiurnalRotation.html DiurnalRotation javadoc] for the description of the above parameters).&lt;br /&gt;
&lt;br /&gt;
===== Transformation relating CIRS to GCRS =====&lt;br /&gt;
&lt;br /&gt;
Based on the celestial motion of the CIP, it can be expressed as:&lt;br /&gt;
&amp;lt;math&amp;gt;Q(t)=R3(-E).R2(-d).R3(E).R3(s)&amp;lt;/math&amp;gt;,&lt;br /&gt;
&#039;&#039;E&#039;&#039; and &#039;&#039;d&#039;&#039; being such that the coordinates of the CIP in the GCRS are:&lt;br /&gt;
&amp;amp; and &#039;&#039;&#039;IAU 2000A_R06 nutation&#039;&#039;&#039;. The IAU series are given in the &#039;&#039;tab5.2a&#039;&#039; file (X model), in the &#039;&#039;tab5.2b&#039;&#039; file (Y model) and in the &#039;&#039;tab5.2d&#039;&#039; file (s model).  &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The user can define the following parameters:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* account of precession and nutation model (IERS2010, IERS2003 or no effect),&lt;br /&gt;
* interpolation method for &#039;&#039;X&#039;&#039;, &#039;&#039;Y&#039;&#039; and &#039;&#039;s&#039;&#039; (Neville method or direct computation),&lt;br /&gt;
* nutation corrections to the &#039;&#039;X&#039;&#039; and &#039;&#039;Y&#039;&#039; coordinates reported by the IERS as &amp;quot;celestial pole offsets&amp;quot; (yes or no),&lt;br /&gt;
* interpolation method for the corrections (linear or Lagrange 4),&lt;br /&gt;
* account of non constant rotation (yes or no) to compute properly the velocity&lt;br /&gt;
&lt;br /&gt;
To create a precession nutation model with chosen parameters, PATRIUS provides the constructor &#039;&#039;&#039;PrecessionNutation&#039;&#039;&#039; (see [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/PrecessionNutation.html PrecessionNutation javadoc] for the description of the above parameters).&lt;br /&gt;
&lt;br /&gt;
===== Using specific EOP history files / data =====&lt;br /&gt;
&lt;br /&gt;
Earth Orientation Parameters (EOP) files provide angular corrections that account for short-period variations of Earths&#039; [http://www.iers.org/nn_10828/IERS/EN/Service/Glossary/cip.html Celestial Intermediate Pole]. The corresponding data is used to compute the transformation from the TIRF to the ITRF frame. The amplitudes of the corrections are given in [FDY_FRAME_Home#HPolarmotion Polar Motion]. IN PATRIUS, the [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOPHistory.html EOPHistory] interface represents EOP data. It has two implementations : [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOP1980History.html EOP1980History] and [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOP2000History.html EOP2000History]. These classes differ because the EOP definition and representation has changed, according to the IERS conventions. Both remain available in PATRIUS.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
EOP data can be retrieved in two ways in PATRIUS:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;By providing your own history:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For the 2000 EOP paradigm, the user may manually create an EOP history with EOP entries. In order to do so, the user must create an instance of EOPHistory and feed it with EOP entries :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // create EOP list- use a 1 day gap&lt;br /&gt;
        final List&amp;lt;EOP2000Entry&amp;gt; list = new ArrayList&amp;lt;EOP2000Entry&amp;gt;();&lt;br /&gt;
        list.add(entry1);&lt;br /&gt;
        list.add(entry2);&lt;br /&gt;
        list.add(entry3);&lt;br /&gt;
        ...&lt;br /&gt;
        list.add(entryN);&lt;br /&gt;
&lt;br /&gt;
        // Create EOP history object- make sure to have enough entries around the dates of interpolation&lt;br /&gt;
        final EOP2000History eop2000History = new EOP2000History(EOPInterpolators.LAGRANGE4);&lt;br /&gt;
&lt;br /&gt;
        // Fill history&lt;br /&gt;
        EOP2000History.fillHistory(list, eop2000History);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also, the user may create an empty EOPHistory object and populate it using a Java InputStream (usually, a file). with the adequate loader (see [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/package-summary.html eop package]) :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        final InputStream is = new FileInputStream(&amp;quot;eopdatafile&amp;quot;);&lt;br /&gt;
        // Empty EOP history object-  choice of interpolator&lt;br /&gt;
        final EOP2000History eop2000History = new EOP2000History(EOPInterpolators.LAGRANGE4);&lt;br /&gt;
        // EOPC04FilesLoader reads the input stream and fills the history object&lt;br /&gt;
        EOPC04FilesLoader.fillHistory(eop2000History, is);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, in this case, the file has to be in the proper format for the EOPC04FilesLoader (see its [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOPC04FilesLoader.html javadoc] for information).&lt;br /&gt;
&lt;br /&gt;
For the 1980 EOP paradigm, the user must proceed in a similar fashion by manually creating an [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOP1980HistoryLoader.html EOP1980HistoryLoader] instance and feeding it to the EOPHistoryFactory.&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;By automatically loading data using default EOP loaders:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final EOP2000History eop2000History = EOPHistoryFactory.getEOP2000History(EOPInterpolators.LAGRANGE4);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This previous line of code returns an EOP 2000 history filled up with found data. Found data includes (in order of data reading):&lt;br /&gt;
* IERS Rapid data and prediction files&lt;br /&gt;
* EOC04 files&lt;br /&gt;
* IERS bulletin B files&lt;br /&gt;
Warning: providing overlapping data may results in some erratic results since some dates will have several EOP data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Finally the EOP history is provided to the frame configuration builder:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        FramesConfigurationBuilder builder = new FramesConfigurationBuilder(config);&lt;br /&gt;
        builder.setEOPHistory(eop2000History);&lt;br /&gt;
        FramesFactory.setConfiguration(builder.getConfiguration());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 1&#039;&#039;&#039;: for the users and applications that do not require any EOP data, utility classes that return zero for all EOP corrections have been implemented. These classes possess validity intervals that span 100 years (1950 through 2050) for the EOP 1980 paradigm and infinity (-infinity through +infinity) for the EOP 2000 paradigm. This means that any application using these classes can request EOP data over these intervals.&lt;br /&gt;
&lt;br /&gt;
* For the 1980 EOP paradigm, a loader class has been implemented : [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/NoEOP1980HistoryLoader.html NoEOP1980HistoryLoader]. The user need only to create an instance of that class and feed it the [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOPHistoryFactory.html EOPHistoryFactory] in order for all transformations to use zero for EOP corrections (only 1980). This done thanks to the following instruction : &amp;lt;code&amp;gt;EOPHistoryFactory.addEOP1980HistoryLoader(new NoEOP1980HistoryLoader())&amp;lt;/code&amp;gt;. This loader then feeds an internal instance of EOP1980History, that the users does not manipulate directly.&lt;br /&gt;
&lt;br /&gt;
* For the 2000 EOP paradigm, a utility class, [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/NoEOP2000History.html NoEOP2000History], was created and represents an EOP history with no corrections (or more precisely 0.0). It has an infinite time interval of validity, from PAST_INFINITY to FUTURE_INFINITY.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note 2&#039;&#039;&#039;: Note that most EOP providers are valid on data-provided timespan. The class &amp;lt;code&amp;gt;EOP2000HistoryConstantOutsideInterval&amp;lt;/code&amp;gt; circumvents that limitation by returning boundaries values when requested date is out of data range. Warning: in this case, as the UT1-TAI remains constant the (UT1-UTC) absolute value returned may become higher than 0.9 second depending on leap seconds (for UTC time scale) existing outside this interval.&lt;br /&gt;
&lt;br /&gt;
===== Note on the internal representation of EOP Data =====&lt;br /&gt;
&lt;br /&gt;
As of 2.1, EOP data sets have been modified to store the value of UT1-TAI instead of UT1-UTC. Additionally, new constructors that allow creating EOPEntry instances from UT1-TAI data have been added. The frames tranformations have thus become independent of the UTC-TAI.history file, provided that the user provides a correctly calculated UT1-TAI. Please refer to the [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOPEntry.html javadoc] for more information.&lt;br /&gt;
&lt;br /&gt;
It should be noted that UT1 is defined with respect to UTC. Consequently, the only way to correctly compute UT1-TAI is per UT1-TAI = UT1-UTC + UTC-TAI.&lt;br /&gt;
&lt;br /&gt;
==== Available models ====&lt;br /&gt;
&lt;br /&gt;
As of now, available models include :&lt;br /&gt;
&lt;br /&gt;
* IERS 2003 and 2010 Precession Nutation models,&lt;br /&gt;
* IERS 2010 S&#039; Model,&lt;br /&gt;
* IERS 2003 and 2010 Tidal corrections models,&lt;br /&gt;
* IERS 2010 Libration correction model (without UT1-UTC correction).&lt;br /&gt;
&lt;br /&gt;
==== Amplitudes of different effects ====&lt;br /&gt;
&lt;br /&gt;
This section provides some useful information about the different effect of each transformation. The distances are given at one terrestrial radius. These data come from the document &amp;quot;&#039;&#039;DCT/SB/OR/2010-12497&amp;quot;, issue 1.3, 2010/11/23&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== Polar motion =====&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;(xp,yp),,IERS,,&#039;&#039; &amp;lt; 1&#039;&#039; (30m)&lt;br /&gt;
* &#039;&#039;(dx,dy),,ocean tides,,&#039;&#039; &amp;lt; 0.002&#039;&#039; (6cm)&lt;br /&gt;
* &#039;&#039;(dx,dy),,libration,,&#039;&#039; &amp;lt; 0.00003 &#039;&#039; (1mm)&lt;br /&gt;
* &#039;&#039;s&#039;&#039;&#039; &amp;lt; 0.00005 &#039;&#039; per century&lt;br /&gt;
&lt;br /&gt;
===== Diurnal rotation =====&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;UT1-UTC,,IERS,,&#039;&#039; &amp;lt; 1 sec. (460m)&lt;br /&gt;
* &#039;&#039;UT1-UTC,,ocean tides,,&#039;&#039; &amp;lt; 33E-6 sec. (1.5cm)&lt;br /&gt;
* &#039;&#039;UT1-UTC,,libration,,&#039;&#039; &amp;lt; 4E-6 sec. (2mm)&lt;br /&gt;
&lt;br /&gt;
===== Celestial motion of the CIP =====&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;(X,Y),,IAU2000/2006,,&#039;&#039; &amp;lt; 11&#039;&#039; (340m)&lt;br /&gt;
* &#039;&#039;(dX,dY),,IERS,,&#039;&#039; &amp;lt; 0.001&#039;&#039; (3cm)&lt;br /&gt;
&lt;br /&gt;
==== Validation of IERS2010 implementation ====&lt;br /&gt;
&lt;br /&gt;
PATRIUS implementation of IERS2010 convention has been validated with reference software routines from &#039;&#039;SOFA&#039;&#039;, &#039;&#039;ZOOM&#039;&#039;, and other routines available in IERS website (like &#039;&#039;interp.f&#039;&#039; routine for EOP data interpolation). &lt;br /&gt;
&lt;br /&gt;
The first level of validation allows to compare the values for each intermediate transformation:&lt;br /&gt;
&lt;br /&gt;
* comparison of &#039;&#039;xp&#039;&#039;, &#039;&#039;yp&#039;&#039; and &#039;&#039;s&#039;&#039;&#039; for the transformation relating ITRS to TIRS,&lt;br /&gt;
* comparison of &#039;&#039;UT1-UTC&#039;&#039; for the transformation relating TIRS to CIRS,&lt;br /&gt;
* comparison of &#039;&#039;X&#039;&#039;, &#039;&#039;Y&#039;&#039;, &#039;&#039;s&#039;&#039; and &#039;&#039;dX&#039;&#039;, &#039;&#039;dY&#039;&#039;, &#039;&#039;ds&#039;&#039; for the transformation relating CIRS to GCRS.&lt;br /&gt;
&lt;br /&gt;
The second level of validation allows to compare the rotation matrices (&#039;&#039;Q(t)&#039;&#039;, &#039;&#039;R(t)&#039;&#039;, &#039;&#039;W(t)&#039;&#039;) by computing angular deviations with the reference.&lt;br /&gt;
&lt;br /&gt;
Several configurations are used to take into account the different effects. Tests have been done for short and long period.&lt;br /&gt;
&lt;br /&gt;
The following graphs represent angular deviations (in log scale) for the following transformations: ITRS to GCRS in dark green, ITRS to TIRS in red, TIRS to CIRS in blue-green and CIRS to GCRS in violet. The first one is related to a short period (10 days), the second one is related to a long period (40 years). The blue line is the validation threshold of&#039;&#039;&#039;0.1E-3 arcseconds&#039;&#039;&#039;. The deviations computed for all transformations are smaller than 0.1E-3 arcseconds.&lt;br /&gt;
&lt;br /&gt;
[[File:global.png|center]]&lt;br /&gt;
&lt;br /&gt;
[[File:globals.png|center]]&lt;br /&gt;
&lt;br /&gt;
As a consequence, some deviations are observed on position and velocity of points used in the context of this validation. The points are taken on LEO and GEO orbits, and also on the terrestrial crust. To give the user some indication, the magnitude of errors is between 1E-4 and 1E-5 m.&lt;br /&gt;
 &lt;br /&gt;
For more details, please refer to the validation report &amp;quot;&#039;&#039;SIRIUS-SVS-DV-10108-THA, issue 1.0, 2012/07/23&#039;&#039;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
=== Example of frame configuration ===&lt;br /&gt;
&lt;br /&gt;
The example describes how to create a frame configuration defined by the following parameters:&lt;br /&gt;
&lt;br /&gt;
* polar motion with IERS2003 corrections (ocean tidal effect, no libration effect and account of quantity &#039;&#039;s&#039;&#039;&#039;),&lt;br /&gt;
* account of &#039;&#039;UT1-UTC&#039;&#039; with IERS2003 corrections (ocean tidal effect),&lt;br /&gt;
* account of precession and nutation (direct or interpolated computation) with nutation correction to &#039;&#039;X&#039;&#039; and &#039;&#039;Y&#039;&#039; and account of angular derivatives.&lt;br /&gt;
&lt;br /&gt;
PATRIUS offers a configuration factory to make the creation easier. Several methods are available to set-up the configuration with the user parameters.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // Configurations builder&lt;br /&gt;
        final FramesConfigurationBuilder builder = new FramesConfigurationBuilder();&lt;br /&gt;
&lt;br /&gt;
        // Tides and libration&lt;br /&gt;
        final TidalCorrectionModel tides = TidalCorrectionModelFactory.TIDE_IERS2003_INTERPOLATED;&lt;br /&gt;
        final LibrationCorrectionModel lib = LibrationCorrectionModelFactory.NO_LIBRATION;&lt;br /&gt;
&lt;br /&gt;
        // Polar Motion&lt;br /&gt;
        final PolarMotion defaultPolarMotion = new PolarMotion(true, tides, lib, SPrimeModelFactory.SP_IERS2003);&lt;br /&gt;
&lt;br /&gt;
        // Diurnal rotation&lt;br /&gt;
        final DiurnalRotation defaultDiurnalRotation = new DiurnalRotation(tides, lib);&lt;br /&gt;
&lt;br /&gt;
        // Precession Nutation&lt;br /&gt;
        final PrecessionNutation precNut = new PrecessionNutation(true, PrecessionNutationModelFactory.PN_IERS2010_INTERPOLATED);&lt;br /&gt;
&lt;br /&gt;
        builder.setDiurnalRotation(defaultDiurnalRotation);&lt;br /&gt;
        builder.setPolarMotion(defaultPolarMotion);&lt;br /&gt;
        builder.setCIRFPrecessionNutation(precNut);&lt;br /&gt;
        builder.setEOPHistory(EOPHistoryFactory.getEOP2000History(EOPInterpolators.LAGRANGE4));&lt;br /&gt;
&lt;br /&gt;
        final FramesConfiguration config = builder.getConfiguration();&lt;br /&gt;
        // and pass it to the frames factory&lt;br /&gt;
        FramesFactory.setConfiguration(config);&lt;br /&gt;
 &lt;br /&gt;
        // Get the frames&lt;br /&gt;
        final Frame itrf = FramesFactory.getITRF();&lt;br /&gt;
        final Frame gcrf = FramesFactory.getGCRF();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
&#039;&#039;&#039;Interfaces used within the Frames configurations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FramesConfiguration&#039;&#039;&#039;&lt;br /&gt;
|Interface providing the basic services for frame configurations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/FramesConfiguration.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EOPHistory&#039;&#039;&#039;&lt;br /&gt;
|Interface for retrieving Earth Orientation Parameters history throughout a large time range.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOPHistory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LibrationCorrectionModel&#039;&#039;&#039;&lt;br /&gt;
|This interface provides the pole corrections as well as the ut1-utc corrections due to libration.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/libration/LibrationCorrectionModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PrecessionNutationModel&#039;&#039;&#039;&lt;br /&gt;
|This interface provides the Celestial Intermediate Pole motion (CIP) in the GCRS, those coordinates are used for the GCRF to CIRF transformation.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/precessionnutation/PrecessionNutationModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SPrimeModel&#039;&#039;&#039;&lt;br /&gt;
|This interface provides the s&#039; correction (used for the following transformation : TIRF -&amp;gt; ITRF).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/sp/SPrimeModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TidalCorrectionModel&#039;&#039;&#039;&lt;br /&gt;
|This interface provides the pole corrections as well as the ut1-utc corrections due to tidal effects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/tides/TidalCorrectionModel.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&lt;br /&gt;
The classes are mentioned according to their packages for better visibility. Note : The aforementioned EOP2000History class is to be used with the PATRIUS IERS Frames Configuration.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| General &lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FramesConfigurationBuilder&#039;&#039;&#039;&lt;br /&gt;
|Frame configuration builder utility, to assist the user in creating a FramesConfiguration.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/FramesConfigurationBuilder.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FramesConfigurationFactory&#039;&#039;&#039;&lt;br /&gt;
|Frames configuration factory. Contains useful configurations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/FramesConfigurationFactory.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Models container classes&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DiurnalRotation&#039;&#039;&#039;&lt;br /&gt;
|This class contains the different ut1-utc corrections (libration, tidal effects).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/DiurnalRotation.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PolarMotion&#039;&#039;&#039;&lt;br /&gt;
|This class contains the different polar motion corrections (libration, tidal effects, sp correction).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/PolarMotion.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PrecessionNutation&#039;&#039;&#039;&lt;br /&gt;
|This class contains the precession nutation model used within the FramesConfigurationImplementation class.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/PrecessionNutation.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Libration models classes&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IERS2010LibrationCorrection&#039;&#039;&#039;&lt;br /&gt;
|This class computes the diurnal lunisolar effect. It is a java translation of the fortran subroutine PM_GRAVI (provided by CNES and from IERS conventions, see chapter 5, tables 5.1a and 5.2a).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/libration/IERS2010LibrationCorrection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NoLibrationCorrection&#039;&#039;&#039;&lt;br /&gt;
|This class ignores the libration effects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/libration/NoLibrationCorrection.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Precession Nutation models classes&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PrecessionNutationConvention&#039;&#039;&#039;&lt;br /&gt;
|IERS Precession Nutation enumerate. Each enumerate provides data file locations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/precessionnutation/PrecessionNutationConvention.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IERS20032010PrecessionNutation&#039;&#039;&#039;&lt;br /&gt;
|Compute the precession nutation correction according to the new IAU-2000 model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/precessionnutation/IERS20032010PrecessionNutation.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| S&#039; models classes&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IERS2010SPCorrection&#039;&#039;&#039;&lt;br /&gt;
|Compute s&#039; correction (IERS 2010 model).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/sp/IERS2010SPCorrection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NoSpCorrection&#039;&#039;&#039;&lt;br /&gt;
|This class ignores the quantity s&#039;.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/sp/NoSpCorrection.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Tidal correction models classes&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IERS2010TidalCorrection&#039;&#039;&#039;&lt;br /&gt;
|Compute tidal correction of the pole motion.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/tides/IERS2010TidalCorrection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IERS2003TidalCorrection&#039;&#039;&#039;&lt;br /&gt;
|Compute tidal correction of the pole motion.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/tides/IERS2003TidalCorrection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NoTidalCorrection&#039;&#039;&#039;&lt;br /&gt;
|This class ignores the tidal effects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/tides/NoTidalCorrection.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| EOP classes&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EOP2000History&#039;&#039;&#039;&lt;br /&gt;
|	This class holds Earth Orientation Parameters (IAU2000) data throughout a large time range.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOP2000History.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EOP2000HistoryConstantOutsideInterval&#039;&#039;&#039;&lt;br /&gt;
|	This class extends the EOP2000History but returns boundaries values when date is out of data range.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOP2000HistoryConstantOutsideInterval.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EOPC04FilesLoader&#039;&#039;&#039;&lt;br /&gt;
|	This class is a generic reader for EOPC04 files.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOPC04FilesLoader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Frames&amp;diff=4145</id>
		<title>User Manual 4.18 Frames</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Frames&amp;diff=4145"/>
		<updated>2026-06-10T08:56:16Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === In Patrius, a frame is represented by the class Frame. The different frames are organized as a tree whose root is the ICRF. A frame is defined by a transformation with respect to its parent. A frame factory enables us to build easily some current frames such as GCRF, EME2000, ITRF... Models and data defining transformations between frame is defined in [FDY_FRCON_Home Frames configuration]  === Javadoc === The frames are... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
In Patrius, a frame is represented by the class Frame. The different frames are organized as a tree whose root is the ICRF. A frame is defined by a transformation with respect to its parent. A frame factory enables us to build easily some current frames such as GCRF, EME2000, ITRF...&lt;br /&gt;
Models and data defining transformations between frame is defined in [FDY_FRCON_Home Frames configuration]&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The frames are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.frames&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/package-summary.html Package fr.cnes.sirius.patrius.frames]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/transformations/package-summary.html Package fr.cnes.sirius.patrius.frames.transformations]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
* [https://www.orekit.org/static/architecture/frames.html Frames architecture] (some of this information may be obsolete)&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
None.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
&lt;br /&gt;
=== Frames ===&lt;br /&gt;
The following frames are available in PATRIUS:&lt;br /&gt;
&lt;br /&gt;
* Reference frames :&lt;br /&gt;
** ICRF,&lt;br /&gt;
** ICRF translated on the Earth-Moon Barycenter (EMB),&lt;br /&gt;
** GCRF,&lt;br /&gt;
** CIRF,&lt;br /&gt;
** TIRF,&lt;br /&gt;
** ITRF,&lt;br /&gt;
** EME 2000,&lt;br /&gt;
** Ecliptic J2000,&lt;br /&gt;
** MOD with and without EOP corrections,&lt;br /&gt;
** TOD with and without EOP corrections,&lt;br /&gt;
** GTOD with and without EOP corrections,&lt;br /&gt;
** G50,&lt;br /&gt;
** VEIS 1950,&lt;br /&gt;
** and more ...&lt;br /&gt;
* Local orbital frames&lt;br /&gt;
* Vehicule frame (see AttitudeFrame in the [ATT_ALW_Home attitude laws] section)&lt;br /&gt;
* Topocentric frames&lt;br /&gt;
* CelestialBody frame (frame centerd on a celestial body)&lt;br /&gt;
&lt;br /&gt;
To use any of the reference frames, the user must use the FramesFactory like so :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Frame eme2000 = FramesFactory.getEME2000();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
PATRIUS implements a frame configuration mechanism. To use it, see the [FDY_FRAME_Home#HTheFramesConfiguration Frames Configuration] section in this page.&lt;br /&gt;
&lt;br /&gt;
See [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/FramesFactory.html FramesFactory javadoc] for a complete list of public methods.&lt;br /&gt;
&lt;br /&gt;
Note that, since PATRIUS 4.13, referential can be defined for any frame using the method &amp;lt;code&amp;gt;Frame.setReferential(Frame)&amp;lt;/code&amp;gt;. By default, the referential is the same as the frame. Changing the referential will only impact the projection of the velocities in the destination frame.&lt;br /&gt;
&lt;br /&gt;
==== Topocentric frame ====&lt;br /&gt;
A topocentric frame can be instantiated with the class TopocentricFrame. This class is based on the definition of a BodyPoint as origin of the frame.&lt;br /&gt;
&lt;br /&gt;
===== TopocentricFrame =====&lt;br /&gt;
&lt;br /&gt;
This class provides several constructors. The simplest one returns an East oriented topocentric frame. The second one, that works with an angle, returns a North oriented topocentric frame if the angle is 0, or an image of this frame through the rotation around the zenith direction of the given angle (counterclockwise).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Reference frame = ITRF&lt;br /&gt;
Frame frameITRF = FramesFactory.getITRF();&lt;br /&gt;
&lt;br /&gt;
// Elliptic earth shape&lt;br /&gt;
OneAxisEllipsoid earthSpheric = new OneAxisEllipsoid(6378136.460, 0., frameITRF);&lt;br /&gt;
&lt;br /&gt;
// Geodetic point at which to attach the frame&lt;br /&gt;
final EllipsoidPoint point = new EllipsoidPoint(earthSpheric , LLHCoordinatesSystem.ELLIPSODETIC, FastMath.toRadians(0.), FastMath.toRadians(30.), 0., &amp;quot;point &amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Build the east frame&lt;br /&gt;
TopocentricFrame topoEast = new TopocentricFrame(point, &amp;quot;lon 30 lat 0&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Build a frame rotated by 30° from the North frame&lt;br /&gt;
TopocentricFrame topo30 = new TopocentricFrame(point, FastMath.toRadians(30.), &amp;quot;lon 30 lat 0&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It can provide a number of directions, such as West, North or Nadir. It provides methods that compute elevation, azimuth and the range of a point located by a cartesian vector.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// get the zenith or the Nadir&lt;br /&gt;
Vector3D north = topoEast.getZenith();&lt;br /&gt;
Vector3D nadir = topoEast.getNadir();&lt;br /&gt;
&lt;br /&gt;
// compute the azimuth of a position&lt;br /&gt;
Vector3D position = new Vector3D(1.0, 2.0, 3.0);&lt;br /&gt;
double azimuth = topo30.getAzimuth(position, earthSpheric.getBodyFrame(), date);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, being a Frame, it can be used to automatically transform a position/velocity to any frame (the inverse is also possible).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
//get the transformation from the topocentric East to the ITRF&lt;br /&gt;
Transform eastTOitrf = topoEast.getTransformTo(frameITRF, AbsoluteDate.FIFTIES_EPOCH_UTC);&lt;br /&gt;
&lt;br /&gt;
//apply the transformation&lt;br /&gt;
PVCoordinates pointPVeast= new PVCoordinates(new Vector3D(0.,-1., 1), Vector3D.ZERO);&lt;br /&gt;
PVCoordinates pointPVitrf= eastTOitrf.transformPVCoordinates(pointPVeast);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We can instantiate a TopocentricFrame without GeodeticCoordinates using either cartesian coordinates and a zenith direction or cartesian coordinates associated with a Body shape. This allows to define accurate Topocentric Frame on bodies which are not ellipsoids (e.g. Phobos).&lt;br /&gt;
&lt;br /&gt;
===== TopocentricCoordinates =====&lt;br /&gt;
&lt;br /&gt;
The topocentric coordinates are defined by the elevation, the azimuth and the distance from the center of the local topocentric frame [R2].&lt;br /&gt;
&lt;br /&gt;
[[File:azimut.gif|center]]&lt;br /&gt;
&lt;br /&gt;
The azimuth is the angle between the local North and the projection of the line which joins the center of the topocentric frame and the satellite in the horizontal plane. This angle ranges from 0 to 2&amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. This angle is oriented by the axis opposite to the Zenith. On the figure, the angle g is called the bearing, it is linked to the azimuth by : g = 2&amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;- azimuth.&lt;br /&gt;
&lt;br /&gt;
The elevation is the angle between the line which joins the center of the topocentric frame and the satellite and the projection of this line in the horizontal plane. This angle ranges from-&amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;/2 to &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;/2. This angle is oriented by the image of the West axis by the rotation of angle azimuth and around Zenith axis. On the figure, s is the elevation angle.&lt;br /&gt;
&lt;br /&gt;
If the elevation equals &amp;lt;math&amp;gt;{\pi\over2}&amp;lt;/math&amp;gt; or &amp;lt;math&amp;gt;-{\pi\over2}&amp;lt;/math&amp;gt;, the azimuth is undefined.&lt;br /&gt;
&lt;br /&gt;
The object TopocentricCoordinates contains also the first derivatives of these elements (elevation rate, azimuth rate and range rate).&lt;br /&gt;
&lt;br /&gt;
We can transform the position of the satellite expressed in Cartesian coordinates into TopocentriCoordinates and vice versa.&lt;br /&gt;
&lt;br /&gt;
We can also transform PVCoordinates into TopocentricCoordinates and vice versa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// North topocentric frame&lt;br /&gt;
final EllipsoidPoint point = new EllipsoidPoint(earthSpheric , LLHCoordinatesSystem.ELLIPSODETIC, FastMath.toRadians(43.604482), FastMath.toRadians(1.443962), 0., &amp;quot;point &amp;quot;);&lt;br /&gt;
final TopocentricFrame topoNorth = new TopocentricFrame(point, 0., &amp;quot;north topocentric frame&amp;quot;);&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(new DateComponents(2008, 04, 07), TimeComponents.H00, TimeScalesFactory.getUTC());&lt;br /&gt;
// Topocentric coordinates&lt;br /&gt;
TopocentricPosition topoCoord = new TopocentricPosition(FastMath.acos(FastMath.sqrt(2. / 3.)), FastMath.toRadians(315), FastMath.sqrt(3));&lt;br /&gt;
// Cartesian coordinates (position only)&lt;br /&gt;
Vector3D position = topoNorth.transformFromTopocentricToPosition(topoCoord);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// North topocentric frame&lt;br /&gt;
final EllipsoidPoint point = new EllipsoidPoint(ellipsoid, LLHCoordinatesSystem.ELLIPSODETIC, FastMath.toRadians(43.604482), FastMath.toRadians(1.443962), 0., &amp;quot;point &amp;quot;);&lt;br /&gt;
final TopocentricFrame topoNorth = new TopocentricFrame(point, 0., &amp;quot;north topocentric frame&amp;quot;);&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(new DateComponents(2008, 04, 07), TimeComponents.H00, TimeScalesFactory.getUTC());&lt;br /&gt;
// Cartesian coordinates (position only)&lt;br /&gt;
Vector3D position = new Vector3D(1,1,1);&lt;br /&gt;
// Topocentric Coordinates&lt;br /&gt;
TopocentricPosition topoCoord = topoNorth.transformFromPositionToTopocentric(position, topoNorth, date);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== CardanMounting =====&lt;br /&gt;
&lt;br /&gt;
The Cardan mounting is defined by two angles (X and Y) and the distance from the center of the local topocentric frame [R2].&lt;br /&gt;
&lt;br /&gt;
[[File:cardan.gif|center]]&lt;br /&gt;
&lt;br /&gt;
The X angle is the angle between the Zenith and the projection of the line which joins the center of the topocentric frame and the satellite in the vertical plane (plane defined by the Zenith and the West axis). This angle ranges from-&amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;. This angle is oriented by the South axis. On the figure, x is the X angle.&lt;br /&gt;
&lt;br /&gt;
The Y angle is the angle between the line which joins the center of the topocentric frame and the satellite and the projection of this line in the vertical plane (plane defined by the Zenith and the West axis). This angle ranges from-&amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;/2 and &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;/2. It is oriented by the image of the West axis by the rotation of angle X and around North axis. On the figure, y is the Y angle.&lt;br /&gt;
&lt;br /&gt;
If the Y angle equals &amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;/2 or-&amp;lt;math&amp;gt;\pi&amp;lt;/math&amp;gt;/2, the X angle is undefined.&lt;br /&gt;
&lt;br /&gt;
The object CardanMounting contains also the first time derivatives of these elements (X angle rate, Y angle rate and range rate).&lt;br /&gt;
&lt;br /&gt;
We can transform the position of the satellite expressed in Cartesian coordinates into CardanMounting and vice versa.&lt;br /&gt;
&lt;br /&gt;
We can also transform PVCoordinates into cardanMounting and vice versa.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// North topocentric frame&lt;br /&gt;
final EllipsoidPoint point = new EllipsoidPoint(ellipsoid, LLHCoordinatesSystem.ELLIPSODETIC, FastMath.toRadians(43.604482), FastMath.toRadians(1.443962), 0., &amp;quot;point &amp;quot;);&lt;br /&gt;
final TopocentricFrame topoNorth = new TopocentricFrame(point, 0., &amp;quot;north topocentric frame&amp;quot;);&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(new DateComponents(2008, 04, 07), &lt;br /&gt;
TimeComponents.H00, &lt;br /&gt;
TimeScalesFactory.getUTC());&lt;br /&gt;
// Cardan mounting&lt;br /&gt;
CardanMountPosition cardanCoord = new CardanMountPosition(FastMath.toRadians(45), FastMath.acos(FastMath.sqrt(2. / 3.)), FastMath.sqrt(3));&lt;br /&gt;
// Cartesian coordinates (position only)&lt;br /&gt;
Vector3D position = topoNorth.transformFromCardanToPosition(cardanCoord);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// North topocentric frame&lt;br /&gt;
final EllipsoidPoint point = new EllipsoidPoint(ellipsoid, LLHCoordinatesSystem.ELLIPSODETIC, FastMath.toRadians(43.604482), FastMath.toRadians(1.443962), 0., &amp;quot;point &amp;quot;);&lt;br /&gt;
final TopocentricFrame topoNorth = new TopocentricFrame(point, 0., &amp;quot;north topocentric frame&amp;quot;);&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(new DateComponents(2008, 04, 07), TimeComponents.H00, TimeScalesFactory.getUTC());&lt;br /&gt;
// Cartesian coordinates (position only)&lt;br /&gt;
Vector3D position = new Vector3D(1,1,1);&lt;br /&gt;
// Cardan mounting&lt;br /&gt;
cardanCoord = topoNorth.transformFromPositionToCardan(position, topoNorth, date);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== CelestialBodyFrame ====&lt;br /&gt;
&lt;br /&gt;
This frame is a wrapper for frames centered on celestial bodies. All celestial bodies-centered frames are instances of CelestialBodyFrame (including geocentric frames).&lt;br /&gt;
&lt;br /&gt;
==== &amp;quot;H0- n&amp;quot; frame ====&lt;br /&gt;
The &amp;quot;H0- n&amp;quot; frame is a pseudo-inertial frame; its parent frame is the GCRF.&lt;br /&gt;
It uses the frozen transformation of the ITRF with respect to the GCRF frame at the date &amp;quot;H0- n&amp;quot;, combined with a rotation by a fixed angle around the Z axis of the ITRF frame.&lt;br /&gt;
&lt;br /&gt;
==== TwoDirectionFrame ====&lt;br /&gt;
The &amp;lt;code&amp;gt;TwoDirectionFrame&amp;lt;/code&amp;gt; is a generic reference frame that can be build starting from two directions and two axis given as input. The specific reference frame inherits from the generic &amp;lt;code&amp;gt;Frame&amp;lt;/code&amp;gt; and uses an internal implementation of a &amp;lt;code&amp;gt;TransformProvider&amp;lt;/code&amp;gt; in order to define a specific &amp;lt;code&amp;gt;Transform&amp;lt;/code&amp;gt; starting from a specific date. &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;Transform&amp;lt;/code&amp;gt; is obtained as follows :&lt;br /&gt;
* a translation obtained starting from the &amp;lt;code&amp;gt;PVCoordinatesProvider&amp;lt;/code&amp;gt; and the &amp;lt;code&amp;gt;Frame&amp;lt;/code&amp;gt; given as input to the constructor ;&lt;br /&gt;
* a rotation obtained starting from the directions defined towards the axis of the reference frame ;&lt;br /&gt;
* a rotation rate which is built a finite difference method with the method &amp;lt;code&amp;gt;AngularCoordinates.estimateRate(…)&amp;lt;/code&amp;gt; : the finite difference step for the computation can be configurable by the used when creating the reference frame.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PredefinedFrame&#039;&#039;&#039;&lt;br /&gt;
| Base class for the predefined frames that are managed by FramesFactory.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/PredefinedFrame.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBodyFrame&#039;&#039;&#039;&lt;br /&gt;
| Class for frames centered on celestial bodies.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/CelestialBodyFrame.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Frame&#039;&#039;&#039;&lt;br /&gt;
|Tridimensional references frames class.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/Frame.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FramesFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory for predefined reference frames.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/FramesFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;HelmertTransformation&#039;&#039;&#039;&lt;br /&gt;
|Transformation class for geodetic systems.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/transformations/HelmertTransformation.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LocalOrbitalFrame&#039;&#039;&#039;&lt;br /&gt;
|Class for frames moving with an orbiting satellite.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/LocalOrbitalFrame.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TopocentricFrame&#039;&#039;&#039;&lt;br /&gt;
|The topocentric frame.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/TopocentricFrame.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Transform&#039;&#039;&#039;&lt;br /&gt;
|Transformation class in three dimensional space.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/transformations/Transform.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;H0MinusNProvider&#039;&#039;&#039;&lt;br /&gt;
|Provider for the &amp;quot;H0-n&amp;quot; frame.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/transformations/H0MinusNProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;H0MinusNFrame&#039;&#039;&#039;&lt;br /&gt;
|&amp;quot;H0-n&amp;quot; frame.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/H0MinusNFrame.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TwoDirectionFrame&#039;&#039;&#039;&lt;br /&gt;
|A generic frame the can be built starting from two directions and two axes.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/TwoDirectionFrame.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FrameConvention&#039;&#039;&#039;&lt;br /&gt;
|Enumeration of all frame conventions used in Patrius.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/configuration/FrameConvention.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SynodicFrame&#039;&#039;&#039;&lt;br /&gt;
|Synodic frame: frame linked to the 3-body problem. In practise this frame generalizes the concept of synodic frame (not necessarily linked to the 3-body problem).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/SynodicFrame.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TranslatedFrame&#039;&#039;&#039;&lt;br /&gt;
|Frame realizing a translation from a parent frame (axis direction remains unchanged).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/TranslatedFrame.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GCRFProvider&#039;&#039;&#039;&lt;br /&gt;
|Provider for the &amp;quot;GCRF&amp;quot; frame (from its parent frame, the EMB frame).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/transformations/GCRFProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EMBProvider&#039;&#039;&#039;&lt;br /&gt;
|Provider for the &amp;quot;EMB&amp;quot; frame (from its parent frame, the ICRF frame).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/frames/transformations/EMBProvider.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== [[File:lightBulb.png]] Tips &amp;amp; Tricks ==&lt;br /&gt;
=== IERS frames transformations ===&lt;br /&gt;
&lt;br /&gt;
This chapter sums up the up and downsides of the use of the IERS frames. Its purpose is to help the user avoid some traps and know what to expect as to the numerical precision of the computations. Further explanations about the IERS frames can be found on the [http://www.iers.org/nn_10968/IERS/EN/IERSHome/home.html?__nnn=true IERS website]&#039;&#039;&#039;[R1]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Tips ====&lt;br /&gt;
&lt;br /&gt;
The ICRF frame is the frame colinear to GCRF frame and centered on solar system barycenter.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One can compute the transformations between two frames with a specific frames configuration passed as a parameter as opposed to the current frame configuration (that is obtained with the &amp;lt;code&amp;gt;FramesFactory.getConfiguration()&amp;lt;/code&amp;gt; method). Given a date and a user specific config, the method to call is :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
frame1.getTransformTo(frame2, date, config);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
One can also compute the jacobian matrix of the conversion between two frames. Given a date epoch, the jacobian matrix of the conversion from frame1 to frame2 is computed by the method &amp;lt;code&amp;gt;getTransformJacobian&amp;lt;/code&amp;gt; called by :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
frame1.getTransformJacobian(frame2, epoch);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Traps ====&lt;br /&gt;
&lt;br /&gt;
The first thing to check when working with IERS frames is the presence of the Earth Orientation Parameters bulletins it requires. Indeed, if the c04 bulletins of the correct year cannot be found in the data, Patrius will use the ones stored internally to compute the transformations. To be sure that Patrius will use the good files, the user has first to point out the directory which contains these files. The fact that it doesn&#039;t warn the user that it does not have the parameters for the time of the simulation may lead to error, and thus the deviation compared to a reference could be enormous without the user being aware. One more thing to know about these bulletins is that they have to be continuous, meaning that the transformation won&#039;t work (and will throw an exception) if there are missing years or month in the files.&lt;br /&gt;
&lt;br /&gt;
Make sure to use IAU 2000 EOP data, otherwise nutation corrections are null.&lt;br /&gt;
&lt;br /&gt;
==== Usage of Frames ====&lt;br /&gt;
&lt;br /&gt;
The methods to be used in order to instanciate the IERS Frames are :&lt;br /&gt;
&lt;br /&gt;
* FramesFactory.getGCRF()&lt;br /&gt;
* FramesFactory.getCIRF()&lt;br /&gt;
* FramesFactory.getTIRF()&lt;br /&gt;
* FramesFactory.getITRF()&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Celestial_bodies&amp;diff=4144</id>
		<title>User Manual 4.18 Celestial bodies</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Celestial_bodies&amp;diff=4144"/>
		<updated>2026-06-10T08:55:53Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === The celestial bodies are described by their main features : position and geometry. The positions are ephemeris that must be loaded from models, the geometries are created as one axis ellipsoids or facet bodies. The package provides a factory able to create any celestial body of the solar system.  === Javadoc === The classes for bodies description are available in the package &amp;lt;code&amp;gt;bodies&amp;lt;/code&amp;gt; of Patrius.  {| class=&amp;quot;wi... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The celestial bodies are described by their main features : position and geometry. The positions are ephemeris that must be loaded from models, the geometries are created as one axis ellipsoids or facet bodies.&lt;br /&gt;
The package provides a factory able to create any celestial body of the solar system.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The classes for bodies description are available in the package &amp;lt;code&amp;gt;bodies&amp;lt;/code&amp;gt; of Patrius.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Orekit&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/package-summary.html Package fr.cnes.sirius.patrius.bodies]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/package-summary.html Package fr.cnes.sirius.patrius.bodies]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
&lt;br /&gt;
Orekit bodies : [https://www.orekit.org/static/architecture/bodies.html Orekit Bodies architecture description ]&lt;br /&gt;
&lt;br /&gt;
IAU report : [https://astrogeology.usgs.gov/groups/iau-wgccre Report of the IAU Working Group on Cartographic Coordinates and Rotational Elements: 2009]&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
None.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Celestial bodies ===&lt;br /&gt;
The Moon, the Sun and planets of the solar system are all represented by the [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/CelestialBody.html CelestialBody] interface. This class associates a name (eg Sun) to :&lt;br /&gt;
* a gravitational coefficient GM &lt;br /&gt;
*a body centered ICRF frame (which can be retrieved with method &amp;lt;code&amp;gt;getICRF()&amp;lt;/code&amp;gt;).&lt;br /&gt;
*a body centered EME2000 frame (which can be retrieved with method &amp;lt;code&amp;gt;getEME2000()&amp;lt;/code&amp;gt;).&lt;br /&gt;
*a body centered inertial frame taking into account only the constant part (α, δ) of IAUPole (which can be retrieved with method &amp;lt;code&amp;gt;getInertialFrame(IAUPoleModelType.CONSTANT)&amp;lt;/code&amp;gt;).&lt;br /&gt;
*a body centered inertial frame taking into account only the constant and secular parts (α, δ) of IAUPole (which can be retrieved with method &amp;lt;code&amp;gt;getInertialFrame(IAUPoleModelType.MEAN)&amp;lt;/code&amp;gt;).&lt;br /&gt;
*a body centered inertial frame taking into account the constant secular and harmonics parts (α, δ) of IAUPole (which can be retrieved with method &amp;lt;code&amp;gt;getInertialFrame(IAUPoleModelType.TRUE)&amp;lt;/code&amp;gt;).&lt;br /&gt;
*a body centered rotating frame taking into account only the constant part w of IAUPole (which can be retrieved with method &amp;lt;code&amp;gt;getRotatingFrame(IAUPoleModelType.CONSTANT)&amp;lt;/code&amp;gt;). It&#039;s parent frame is the inertial equator frame.&lt;br /&gt;
*a body centered rotating frame taking into account only the constant and secular parts w of IAUPole (which can be retrieved with method &amp;lt;code&amp;gt;getRotatingFrame(IAUPoleModelType.MEAN)&amp;lt;/code&amp;gt;). It&#039;s parent frame is the mean equator frame.&lt;br /&gt;
*a body centered rotating frame taking into account the constant secular and harmonics parts w of IAUPole (which can be retrieved with method &amp;lt;code&amp;gt;getRotatingFrame(IAUPoleModelType.TRUE)&amp;lt;/code&amp;gt;). It&#039;s parent frame is the true equator frame.&lt;br /&gt;
&lt;br /&gt;
Inertially-oriented and body-oriented frames are defined in the following way:&lt;br /&gt;
* Body-centered inertial frame is centered on the celestial body centered and pole axis (Z axis) is shifted by right ascension α and declination δ.&lt;br /&gt;
* Body-centered rotating frame is linked to inertially-oriented frame by a rotation of angle W(t) (reference values for W(t) is provided by IAU).&lt;br /&gt;
&lt;br /&gt;
To build a celestial body, the user can:&lt;br /&gt;
* use the static methods of the &amp;lt;code&amp;gt;CelestialBodyFactory&amp;lt;/code&amp;gt; to create instances of the most common celestial bodies (Moon, Sun, Jupiter, etc.). JPL Ephemeris data are used. Warning: using the factory requires to load JPL Ephemeris data beforehand.&lt;br /&gt;
* use the simplified models (Meeus, etc.).&lt;br /&gt;
* creates its own celestial body using the class &amp;lt;code&amp;gt;UserCelestialBody&amp;lt;/code&amp;gt; as well as its own pole motion using the class &amp;lt;code&amp;gt;UserIAUPole&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For the two first case (JPL and Meeus), the pole data of the body are automatically retrieved using the IAU data through &amp;lt;code&amp;gt;IAUPoleFactory&amp;lt;/code&amp;gt; class (data is contained within PATRIUS).&lt;br /&gt;
By default, IAU pole data for planetary bodies (including Sun and moon) are available in PATRIUS through the use of the &amp;lt;code&amp;gt;IAUPoleFactory.getIAUPole()&amp;lt;/code&amp;gt;. Data come from the IAU 2009 working group Technical Note.&lt;br /&gt;
&lt;br /&gt;
These methods are detailed in the following sections.&lt;br /&gt;
&lt;br /&gt;
=== Ephemeris Loader ===&lt;br /&gt;
For any celestial body of the Solar System, the actual computation of its position and velocity relies on the JPL planetary ephemerides files. These files are binary files and loaded thanks to the JPLCelestialBodyLoader object.&lt;br /&gt;
&lt;br /&gt;
Note that celestial bodies and associated ephemeris loaders are distinct: a class loads the ephemeris returning a &amp;lt;code&amp;gt;CelestialBodyEphemeris&amp;lt;/code&amp;gt; while the other loads the whole &amp;lt;code&amp;gt;CelestialBody&amp;lt;/code&amp;gt;.&lt;br /&gt;
However, for sake of clarity, the main visible loaders are celestial body loaders.&lt;br /&gt;
&lt;br /&gt;
For the moment, this object is able to load JPL DE XXX files and IMCCE INPOP files which are the most commonly used data files (see below for an exact list of accepted files). For instance with the most common files, the JPL DE 405 covers the years 1600 to 2200 at maximum precision, the JPL DE 406 covers the years-3000 to +3000 at only slightly reduced precision. The DE 405 file is the basis for the Astronomical Almanac and leads to sufficiently accurate results and, for most purposes, even the accuracy of DE 406 is sufficient.&lt;br /&gt;
&lt;br /&gt;
==== JPLCelestialBodyLoader ====&lt;br /&gt;
&lt;br /&gt;
In order to generate the ephemerides of one celestial body of the Solar System, one has to use the JPLCelestialBodyLoader as follows :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;   &lt;br /&gt;
final JPLCelestialBodyLoader loaderEMB = new JPLCelestialBodyLoader(fileName, &lt;br /&gt;
                   EphemerisType.EARTH_MOON);&lt;br /&gt;
final JPLCelestialBodyLoader loaderSSB = new JPLCelestialBodyLoader(fileName, &lt;br /&gt;
                   EphemerisType.SOLAR_SYSTEM_BARYCENTER);&lt;br /&gt;
CelestialBodyFactory.addCelestialBodyLoader(CelestialBodyFactory.EARTH_MOON, loaderEMB);&lt;br /&gt;
CelestialBodyFactory.addCelestialBodyLoader(CelestialBodyFactory.SOLAR_SYSTEM_BARYCENTER, loaderSSB);&lt;br /&gt;
&lt;br /&gt;
// Reference frame&lt;br /&gt;
Frame icrf = FramesFactory.getICRF();&lt;br /&gt;
&lt;br /&gt;
// Ephemeris of the Sun&lt;br /&gt;
JPLCelestialBodyLoaderloader = new JPLCelestialBodyLoader(&amp;quot;unxp2000.405&amp;quot;, &lt;br /&gt;
                EphemerisType.SUN);&lt;br /&gt;
&lt;br /&gt;
// Creation of the Sun&lt;br /&gt;
CelestialBody sun = loader.loadCelestialBody(CelestialBodyFactory.SUN);&lt;br /&gt;
&lt;br /&gt;
// Coordinates of the Sun given a date and a reference frame&lt;br /&gt;
PVCoordinates pvSun = sun.getPVCoordinates(date, icrf);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When the user wants to create a JPLCelestialBodyLoader, first of all, he must supply the folder where the DE XXX files are stored. Then he has to give the name of the file which contains the data (DE XXX), the type of celestial body and a date (desired central date) as entries of the JPLCelestialBodyLoader.&lt;br /&gt;
&lt;br /&gt;
The first argument (name of the data file) may be &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;. In this case, Patrius takes the first compatible file found. If one wants only files from the DE 405 ephemerides, for instance, he has to give the String &amp;lt;code&amp;gt; &amp;quot;^unx[mp](\\d\\d\\d\\d)\\.(?:405)$&amp;quot;&amp;lt;/code&amp;gt;. The last argument can also be &amp;lt;code&amp;gt;null&amp;lt;/code&amp;gt;. If the central date is not mentionned an arbitrary 100 days range will be loaded whereas if it is mentionned all data within a +/-50 days range around this date will be loaded.&lt;br /&gt;
&lt;br /&gt;
Once the data is loaded, thanks to the JPLCelestialBodyLoader, the user can create the celestial body with the method loadCelestialBody() of the JPLCelestialBodyLoaderclass. To do so, the user has to be sure that all required data is loaded. Indeed, apart from the Moon, the Earth and the Earth-Moon barycenter, the creation of a celestial body requires some data on the Earth Moon barycenter and the Solar System barycenter in order to instanciate the frame in which the ephemerides of the celestial body will be defined. Therefore, the user has to create a JPLCelestialBodyLoaderfor the Earth-Moon barycenter and the Solar System barycenter prior to creating the celestial body, otherwise Patrius will arbitrarily load a DE file to generate the corresponding ephemerides that are used afterwards for the generation of the frame. Then the user has to complete the list of the loaders of the CelestialBodyFactory with these two loaders before calling the method loadCelestialBody().&lt;br /&gt;
&lt;br /&gt;
A static method &amp;lt;code&amp;gt;hasNoLoader()&amp;lt;/code&amp;gt; in the class &amp;lt;code&amp;gt;CelestialBodyFactory&amp;lt;/code&amp;gt; allows for a given celestial body to verify if a default loader exists. The user can verify if a specific loader exists for the body before using the default one this way.&lt;br /&gt;
&lt;br /&gt;
NB : The user has to clean the CelestialBodyFactory memory if he does not want to work with the previously defined celestial bodies.&lt;br /&gt;
&lt;br /&gt;
==== JPL ephemerides ====&lt;br /&gt;
&lt;br /&gt;
The JPL ephemerides data is available on the [ftp://ssd.jpl.nasa.gov/pub/eph/planets/ JPL FTP server] [R3].&lt;br /&gt;
&lt;br /&gt;
Available ephemerides :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Development Ephemerides&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Created in...&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Description&lt;br /&gt;
|-&lt;br /&gt;
|DE200&lt;br /&gt;
|September 1981&lt;br /&gt;
|includes nutations but not librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the dynamical equator and equinox of 2000.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2305424.13 (1599 DEC 09)  to  JED 2513360.5 (2169 MAR 31).&lt;br /&gt;
&lt;br /&gt;
This ephemeris was used for  the Astronomical Almanac from 1984 to 2003. (See Standish, 1982 and Standish, 1990).&lt;br /&gt;
|-&lt;br /&gt;
|DE202&lt;br /&gt;
|October 1987&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the dynamical equator and equinox of 2000.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2414992.5 (1899 DEC 04) to  JED 2469808.5 (2050 JAN 02).&lt;br /&gt;
|-&lt;br /&gt;
|DE403&lt;br /&gt;
|May 1993&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2305200.5 (1599 APR 29) to  JED 2524400.5 (2199 JUN 22).&lt;br /&gt;
&lt;br /&gt;
Fit to planetary and lunar laser ranging data.(See Folkner et al. 1994).&lt;br /&gt;
|-&lt;br /&gt;
|DE405, DE406&lt;br /&gt;
|May 1997&lt;br /&gt;
|For the DE405:&lt;br /&gt;
&lt;br /&gt;
includes both nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2305424.130  (1599 DEC 09)  to  JED 2525008.50  (2201 FEB 20)&lt;br /&gt;
&lt;br /&gt;
For the DE406 :&lt;br /&gt;
&lt;br /&gt;
the same as the DE405 except the time span : Spans JED 0624976.50 (-3001 FEB 04) to 2816912.50 (+3000 MAY 06)&lt;br /&gt;
&lt;br /&gt;
This is the same integration as DE405, with the accuracy of the interpolating polynomials has been lessened to reduce file size for the longer time span covered by the file.&lt;br /&gt;
|-&lt;br /&gt;
|DE410&lt;br /&gt;
|April 2003&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2415056.5 (1900 FEB 06) to JED 2458832.5 (2019 DEC 15).&lt;br /&gt;
&lt;br /&gt;
Ephemeris used for Mars Exploration Rover navigation.&lt;br /&gt;
|-&lt;br /&gt;
|DE413&lt;br /&gt;
|November 2004&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2414992.5, (1899 DEC 04) to JED 2469872.5 (2050 MAR 07).&lt;br /&gt;
&lt;br /&gt;
Created to update the orbit of Pluto to aid in planning for an occultation of a relatively bright star by Charon on 11 July 2005.&lt;br /&gt;
|-&lt;br /&gt;
|DE414&lt;br /&gt;
|May 2005&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2414992.5, (1899 DEC 04) to JED 2469872.5 (2050 MAR 07).&lt;br /&gt;
&lt;br /&gt;
Fit to ranging data from MGS and Odyssey through 2003. (See Konopliv et al., 2006.)&lt;br /&gt;
|-&lt;br /&gt;
|DE418&lt;br /&gt;
|August 2007&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2414864.13 (1899 JUL 29) to JED 2470192.5 (2051 JAN 21)&lt;br /&gt;
|-&lt;br /&gt;
|DE421&lt;br /&gt;
|February 2008&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2414864.13 (1899 JUL 29) to JED 2471184.13 (2053 OCT 09)&lt;br /&gt;
&lt;br /&gt;
Fit to planetary and lunar laser ranging data. (See Folkner et al., 2009)&lt;br /&gt;
|-&lt;br /&gt;
|DE422&lt;br /&gt;
|September 2009&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 625648.5, (-3000 DEC 07) to JED 2816816.5, (3000 JAN 30).&lt;br /&gt;
&lt;br /&gt;
Intended for the MESSENGER mission to Mercury.&amp;lt;br&amp;gt;&lt;br /&gt;
Extended integration time to serve as successor to DE406.&amp;lt;br&amp;gt;&lt;br /&gt;
Fit to ranging data from MGS and Odyssey through 2003. (See Konopliv et al., 2010.)&lt;br /&gt;
|-&lt;br /&gt;
|DE423&lt;br /&gt;
|February 2010&lt;br /&gt;
|includes nutations and librations.&amp;lt;br&amp;gt;&lt;br /&gt;
Referred to the International Celestial Reference Frame  version 2.0.&amp;lt;br&amp;gt;&lt;br /&gt;
Covers JED 2378480.5, (1799 DEC 16) to JED  2524624.13, (2200 FEB 02).&lt;br /&gt;
&lt;br /&gt;
Intended for the MESSENGER mission to Mercury.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== IMCCE INPOP ephemerides ====&lt;br /&gt;
&lt;br /&gt;
The IMCCE INPOP ephemeris is available on IMCCE website.&lt;br /&gt;
&lt;br /&gt;
Available INPOP ephemerides :&lt;br /&gt;
* 06b&lt;br /&gt;
* 06c&lt;br /&gt;
* 08a&lt;br /&gt;
* 10a&lt;br /&gt;
* 10b&lt;br /&gt;
* 10e&lt;br /&gt;
* 13c&lt;br /&gt;
* 17a&lt;br /&gt;
* 19a&lt;br /&gt;
&lt;br /&gt;
=== Simplified analytical models ===&lt;br /&gt;
==== Meeus Model ====&lt;br /&gt;
&lt;br /&gt;
The Meeus Model is a simplified model which gives the position of the Sun and the Moon with respect to the time T expressed in centuries (TT time scale). This model is an analytical model less precise than the DE ephemerides given by JPL. It is adapted for onboard applications.&lt;br /&gt;
The class implementing the Meeus Model allows three different models computing the position of the Sun with appropriate equations : the standard model (provided by Jean Meeus), the Stela model and an onboard model. The main differences between these model is the computation of the obliquity of the ecliptic : indeed, its value is fixed to 0 for the standard model, given by an expression involving &amp;lt;math&amp;gt;T, T^{2}&amp;lt;/math&amp;gt;for Stela model and &amp;lt;math&amp;gt;T, T^{2}, T^{3}&amp;lt;/math&amp;gt; for the onboard model.&lt;br /&gt;
Moreover, the onboard model computed the position in J2000 frame, whereas standard and Stela models use respectively EOD and MOD frame.&lt;br /&gt;
&lt;br /&gt;
Regarding the precision, one has to expect a maximum difference of 25593km in position for the Sun and a maximum angular difference of 34.13&#039;&#039; (wrt DE405 ephemerides). For the Moon, one has to expect a maximum difference of 26 km in position and a maximum angular difference of 15.2&#039;&#039; (wrt DE405 ephemerides). As for the performances (in terms of execution time), the Meeus model for the Sun is faster than the DE405 ephemerides. However, we did not come to the same conclusion for the Moon even by decreasing the degree of precision (number of terms taken into account to compute the latitude, longitude and distance which are needed to compute in fine the position of the Moon).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Deviation in position wrt DE423&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Angular deviation wrt DE423&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sun&#039;&#039;&#039;&lt;br /&gt;
|12000 km&lt;br /&gt;
|34.13&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 62x66x46&#039;&#039;&#039;&lt;br /&gt;
|12.4 km&lt;br /&gt;
|15.2&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 26x13x13&#039;&#039;&#039;&lt;br /&gt;
|225 km&lt;br /&gt;
|122&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 9x4x3&#039;&#039;&#039;&lt;br /&gt;
|1591 km&lt;br /&gt;
|889&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Deviation in position wrt DE405&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Angular deviation wrt DE405&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sun&#039;&#039;&#039;&lt;br /&gt;
|25593km&lt;br /&gt;
|34.13&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 62x66x46&#039;&#039;&#039;&lt;br /&gt;
|26 km&lt;br /&gt;
|15.2&#039;&#039;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Number of elementary operations&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Number of trigonometric operations&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sun&#039;&#039;&#039;&lt;br /&gt;
|89&lt;br /&gt;
|10&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 62x66x46&#039;&#039;&#039;&lt;br /&gt;
|2671&lt;br /&gt;
|182&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 26x13x13&#039;&#039;&#039;&lt;br /&gt;
|917&lt;br /&gt;
|60&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 9x4x3&#039;&#039;&#039;&lt;br /&gt;
|401&lt;br /&gt;
|24&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
References for the tables : &lt;br /&gt;
* &amp;quot;Modèles d&#039;éphémérides luni-solaires&amp;quot;, CNES DCT/SB/MS, 03/14/2011&lt;br /&gt;
* &amp;quot;Modèle MEEUS pour éphémérides Lune-Soleil : Compléments sur le nombre d&#039;opérations&amp;quot;, CNES DCT/SB/MS&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| execution time - DE405&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| execution time- MEEUS&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sun&#039;&#039;&#039;&lt;br /&gt;
|59 s 548 ms&lt;br /&gt;
|19 s 938 ms&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 62x66x46&#039;&#039;&#039;&lt;br /&gt;
|11 s 625 ms&lt;br /&gt;
|3 mn 22 s 323 ms&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 26x13x13&#039;&#039;&#039;&lt;br /&gt;
|11 s 625 ms&lt;br /&gt;
|1 mn 17 s 74 ms&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Moon 9x4x3&#039;&#039;&#039;&lt;br /&gt;
|11 s 625 ms&lt;br /&gt;
|40 s 326 ms&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
In order to build such a Sun or Moon, one has to use the object MeeusSun or MeeusMoon which both extend AbstractCelestialBody. Note that it is not possible to build those celestial bodies from the CelestialBodyFactory, for the moment.&lt;br /&gt;
&lt;br /&gt;
==== Basic board Sun model ====&lt;br /&gt;
The basic board Sun  model is a simplified analytical model which gives the direction of the Sun (the normalized position) with respect to time. &lt;br /&gt;
This model is similar to the Meeus model (the constants of the model are different) and is adapted for onboard applications. &lt;br /&gt;
The reference inertial frame is the CIRF.&lt;br /&gt;
&lt;br /&gt;
=== User-defined celestial bodies ===&lt;br /&gt;
User can defined its own celestial body by using &amp;lt;code&amp;gt;UserCelestialBody&amp;lt;/code&amp;gt;.&lt;br /&gt;
This class requires to provide:&lt;br /&gt;
* Its name.&lt;br /&gt;
* Its position-velocity through time using a &amp;lt;code&amp;gt;PVCoordinateProvider&amp;lt;/code&amp;gt; implementation.&lt;br /&gt;
* Its gravitational constant.&lt;br /&gt;
* Its pole motion using &amp;lt;code&amp;gt;IAUPole&amp;lt;/code&amp;gt; implementation or directly the &amp;lt;code&amp;gt;UserIAUPole&amp;lt;/code&amp;gt; implementation.&lt;br /&gt;
The &amp;lt;code&amp;gt;UserIAUPole&amp;lt;/code&amp;gt; is a simple way to build standard pole motion from IAU note. It requires to provide for each component (α, δ and W) a list of functions of duration in days and duration in centuries (from a reference epoch) as defined in IAU note. This functions are &amp;lt;code&amp;gt;UnivariateDifferentiableFunction&amp;lt;/code&amp;gt;.&lt;br /&gt;
Available functions in PATRIUS include:&lt;br /&gt;
* &amp;lt;code&amp;gt;PolynomialFunction&amp;lt;/code&amp;gt;: polynomial function&lt;br /&gt;
* &amp;lt;code&amp;gt;SineFunction&amp;lt;/code&amp;gt;: function of the form k.sin(f) with f an &amp;lt;code&amp;gt;UnivariateDifferentiableFunction&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CosineFunction&amp;lt;/code&amp;gt;: function of the form k.cos(f) with f an &amp;lt;code&amp;gt;UnivariateDifferentiableFunction&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example: building Ceres&#039;&#039;&#039;.&lt;br /&gt;
According to the IAU report, Ceres has the following parameters:&lt;br /&gt;
* α = 291◦ ± 5◦&lt;br /&gt;
* δ = 59◦ ± 5◦&lt;br /&gt;
* W = 170.90◦ + 952.1532◦d&lt;br /&gt;
With &#039;&#039;d&#039;&#039; being the interval in days from the standard epoch (the standard epoch is JD 2451545.0, i.e. 2000 January 1 12 hours TDB)&lt;br /&gt;
&lt;br /&gt;
Ceres gravitational constant is 6.263E10 m^^3^^kg^^-1^^s^^-2^^.&lt;br /&gt;
&lt;br /&gt;
If one knows Ceres motion given for instance by a &amp;lt;code&amp;gt;PVCoordinatePropagator&amp;lt;/code&amp;gt; &#039;&#039;pv&#039;&#039;, then one can build Ceres with the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Gravitational parameter&lt;br /&gt;
final double gm = 6.263E10;&lt;br /&gt;
&lt;br /&gt;
// Pole motion - Method 1 - Implementation if IAUPole interface&lt;br /&gt;
final IAUPole pole = new IAUPole() {&lt;br /&gt;
    @Override&lt;br /&gt;
    public double getPrimeMeridianAngle(final AbsoluteDate date) {&lt;br /&gt;
        // W&lt;br /&gt;
        final double d = date.durationFrom(AbsoluteDate.J2000_EPOCH) / Constants.JULIAN_DAY;&lt;br /&gt;
        return FastMath.toRadians(170.90) + FastMath.toRadians(952.1532)* d;&lt;br /&gt;
    }&lt;br /&gt;
            &lt;br /&gt;
    @Override&lt;br /&gt;
    public Vector3D getPole(final AbsoluteDate date) {&lt;br /&gt;
        // Pole bias: alpha and delta&lt;br /&gt;
        return new Vector3D(FastMath.toRadians(291), FastMath.toRadians(59));&lt;br /&gt;
    }&lt;br /&gt;
    ...&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Pole motion - Method 2 - Use of UserIAUPole class&lt;br /&gt;
// Alpha 0 coefficients&lt;br /&gt;
final List&amp;lt;IAUPoleFunction&amp;gt; alpha0List = new ArrayList&amp;lt;IAUPoleFunction&amp;gt;();&lt;br /&gt;
alpha0List.add(new IAUPoleFunction(IAUPoleType.CONSTANT, new PolynomialFunction(new double[] { 291 }), IAUTimeDependency.DAYS);&lt;br /&gt;
final IAUPoleCoefficients1D alpha0Coeffs = new IAUPoleCoefficients1D(alpha0List);&lt;br /&gt;
// Delta 0 coefficients&lt;br /&gt;
final List&amp;lt;IAUPoleFunction&amp;gt; delta0List = new ArrayList&amp;lt;IAUPoleFunction&amp;gt;();&lt;br /&gt;
delta0List.add(new IAUPoleFunction(IAUPoleType.CONSTANT, new PolynomialFunction(new double[] { 59 }), IAUTimeDependency.DAYS);&lt;br /&gt;
final IAUPoleCoefficients1D delta0Coeffs = new IAUPoleCoefficients1D(delta0List );&lt;br /&gt;
// W coefficients&lt;br /&gt;
final List&amp;lt;IAUPoleFunction&amp;gt; w0List = new ArrayList&amp;lt;IAUPoleFunction&amp;gt;();&lt;br /&gt;
w0List.add(new IAUPoleFunction(IAUPoleType.CONSTANT, new PolynomialFunction(new double[] { 170.9 }), IAUTimeDependency.DAYS);&lt;br /&gt;
w0List.add(new IAUPoleFunction(IAUPoleType.SECULAR, new PolynomialFunction(new double[] { 0, 952.1532 }), IAUTimeDependency.DAYS);&lt;br /&gt;
final IAUPoleCoefficients1D wCoeffs = new IAUPoleCoefficients1D(w0List);&lt;br /&gt;
// Build pole&lt;br /&gt;
final IAUPole pole = new UserIAUPole(new IAUPoleCoefficients(alpha0Coeffs, delta0Coeffs, wCoeffs));&lt;br /&gt;
&lt;br /&gt;
// Build Ceres body&lt;br /&gt;
final CelestialBody ceres = new UserCelestialBody(&amp;quot;Ceres&amp;quot;, pv, gm, pole, FramesFactory.getICRF(), null);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then &amp;lt;code&amp;gt;ceres&amp;lt;/code&amp;gt; object possesses all features of:&lt;br /&gt;
* A &amp;lt;code&amp;gt;CelestialBody&amp;lt;/code&amp;gt;: retrieve body-centered inertial frames or body-centered rotating frames&lt;br /&gt;
* A &amp;lt;code&amp;gt;PVCoordinateProvider&amp;lt;/code&amp;gt;: retrieve position and velocity at any time&lt;br /&gt;
&lt;br /&gt;
==== BodyShape====&lt;br /&gt;
&lt;br /&gt;
The BodyShape interface carries servals features common to body shapes such as its name, frame, intersection point computation, distance to a line, closest point computation, body point transformation. &lt;br /&gt;
A couple of getter/setter allows to configure the LLHCoordinatesSystem associated to the shape, which can be ELLIPSODETIC, BODYCENTRIC_RADIAL or BODYCENTRIC_NORMAL. This coordinates system is used for instance by closest point computation or body point transformation. &lt;br /&gt;
The interface extends the PVCoordinatesProvider and ApparentRadiusProvider interfaces. The first carry the service to determine the PVCoordinates of the body at any date and the second describes two related features:&lt;br /&gt;
* Compute the apparent radius of the occulting body from the spacecraft (observer) position. Given a plane containing the spacecraft position, the center of the occulting body (the body shape) and the center of the occulted body, and given a line contained within this plane, passing by the spacecraft position and tangent to the mesh of the occulting body, the apparent radius corresponds to the length of the line starting from the center of the occulting body, perpendicular to the first given line and ending at the intersection of the two lines.&lt;br /&gt;
* Compute the apparent radius in a plane containing the spacecraft position, the center of the occulting body and a specified direction instead of the occulted body position. The rest of the behavior stays identical.&lt;br /&gt;
Note: The apparent radius is computed in one direction from the frame origin of the body to the perpendicular tangent line. In case of dissymmetric shape, this definition it might introduce some limitations as the radius computed in the other direction would be different.&lt;br /&gt;
&lt;br /&gt;
==== OneAxisEllipsoid ====&lt;br /&gt;
&lt;br /&gt;
This type is used to represent the shape of a planet. One very useful implementation represents an ellipsoid (OneAxisEllipsoid). It is constructed from an equatorial radius, a flattening coefficient, and a reference frame that will be used to localize Geodetic points on the shape.&lt;br /&gt;
&lt;br /&gt;
The one-axis ellipsoid is a good approximate model for most planet-size and larger natural bodies. It is the equilibrium shape reached by a fluid body under its own gravity field when it rotates. The symmetry axis is the rotation or polar axis.&lt;br /&gt;
&lt;br /&gt;
It could be interesting to obtain the intersection point of a line from the satellite to the surface of the body for a given altitude. To that purpose, one can use the method getIntersectionPoint(Line, Vector3D, Frame, AbsoluteDate, double) of the interface BodyShape.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
AbsoluteDate date = new AbsoluteDate(new DateComponents(2008, 03, 21),&lt;br /&gt;
                                             TimeComponents.H12,&lt;br /&gt;
                                             TimeScalesFactory.getUTC());       &lt;br /&gt;
CelestialBodyFrame frame = FramesFactory.getITRF();&lt;br /&gt;
// Body shape model&lt;br /&gt;
OneAxisEllipsoid earth = new OneAxisEllipsoid(6378136.460, 1 / 298.257222101, frame);&lt;br /&gt;
&lt;br /&gt;
// Satellite on any position&lt;br /&gt;
&lt;br /&gt;
circ = new CircularOrbit(7178000.0, 0.5e-4, 0., FastMath.toRadians(50.), FastMath.toRadians(0.),&lt;br /&gt;
                                   FastMath.toRadians(90.), PositionAngle.MEAN, &lt;br /&gt;
                                   FramesFactory.getEME2000(), date, mu);&lt;br /&gt;
        &lt;br /&gt;
// Transform satellite position to position/velocity parameters in EME2000 and ITRF200B&lt;br /&gt;
PVCoordinates pvSatEME2000 = circ.getPVCoordinates();&lt;br /&gt;
PVCoordinates pvSatItrf  = frame.getTransformTo(FramesFactory.getEME2000(), date).transformPVCoordinates(pvSatEME2000);&lt;br /&gt;
Vector3D pSatItrf  = pvSatItrf.getPosition();&lt;br /&gt;
        &lt;br /&gt;
// Nadir point of the satellite&lt;br /&gt;
Vector3D pointItrf     = new Vector3D.ZERO;&lt;br /&gt;
Vector3D direction = Vector3D(1., pSatItrf,-1., pointItrf);&lt;br /&gt;
Line line = new Line(pSatItrf, direction);&lt;br /&gt;
// intersection point between the ellipsoid and the line that joins the satellite and the center of the body&lt;br /&gt;
double altitude  = 0;&lt;br /&gt;
EllipsoidPoint nadir = earth.getIntersectionPoint(line, pSatItrf, frame, date, altitude);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The ThreeAxisEllipsoid class shares many features with the OneAxisEllipsoid and allows to define an ellipsoid fully defined by its three axis radius (along the directions (0, 0, 1) ; (0, 1, 0) ; (0, 0, 1)).&lt;br /&gt;
&lt;br /&gt;
OneAxisEllipsoid extends the AbstractEllipsoidBodyShape class (also extended by ThreeAxisEllipsoid) and AbstractEllipsoidBodyShape implements the EllipsoidBodyShape interface, which extends the StarConvexBodyShape interface, which, at its turn, extends the BodyShape interface (already introduced).&lt;br /&gt;
&lt;br /&gt;
==== Facet celestial body ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FacetBodyShape&amp;lt;/code&amp;gt; is a class used to define a celestial body as a mesh. This is particularly useful for small irregular bodies such as asteroids.&lt;br /&gt;
For example, Phobos contains here 100 000 vertices and 200 000 facets:&lt;br /&gt;
[[File:Phobos.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
This class:&lt;br /&gt;
* Inherits the &amp;lt;code&amp;gt;BodyShape&amp;lt;/code&amp;gt; interface and hence can be used together with &amp;lt;code&amp;gt;EclipseDetector&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;SensorModel&amp;lt;/code&amp;gt;.&lt;br /&gt;
* Provides some useful and optimised methods for small body handling. Facets are connected to each other allowing some methods to be writen in a recursive or iterative way and hence being very fast. If &amp;lt;i&amp;gt;n&amp;lt;/i&amp;gt; is the number of vertices of the body, fast recursive or iterative methods are in O(log(n)).&lt;br /&gt;
&lt;br /&gt;
For use as a &amp;lt;code&amp;gt;CelestialBody&amp;lt;/code&amp;gt;, this class must be linked to a &amp;lt;code&amp;gt;UserCelestialBody&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===== Mesh provider =====&lt;br /&gt;
&lt;br /&gt;
A mesh is described by a list of facets &amp;lt;code&amp;gt;Triangle&amp;lt;/code&amp;gt; and or vertices &amp;lt;code&amp;gt;Vertex&amp;lt;/code&amp;gt;. A &amp;lt;code&amp;gt;Triangle&amp;lt;/code&amp;gt; contains three vertices.&lt;br /&gt;
Mesh is provided by the generic interface &amp;lt;code&amp;gt;MeshProvider&amp;lt;/code&amp;gt;. This interface currently possesses two implementation:&lt;br /&gt;
* &amp;lt;code&amp;gt;ObjMeshLoader&amp;lt;/code&amp;gt;: in this case, the mesh is provided under official .obj file format. See [https://en.wikipedia.org/wiki/Wavefront_.obj_file This page] for more information on the format.&lt;br /&gt;
* &amp;lt;code&amp;gt;GeodeticMeshLoader&amp;lt;/code&amp;gt;: in this case, the mesh is provided in an ASCII column file listing each vertex in the format [Latitude Longitude Altitude].&lt;br /&gt;
&lt;br /&gt;
===== Available methods =====&lt;br /&gt;
&lt;br /&gt;
Note that most methods return &amp;lt;b&amp;gt;exact&amp;lt;/b&amp;gt; results. For example, &amp;lt;code&amp;gt;distanceTo&amp;lt;/code&amp;gt; methods returns exact distance to mesh body. Only &amp;lt;code&amp;gt;getEllipsoid(EllipsoidType)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;getApparentRadius&amp;lt;/code&amp;gt; methods return a simplified result.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;FacetBodyShape&amp;lt;/code&amp;gt; provides the following methods:&lt;br /&gt;
* &amp;lt;code&amp;gt;getIntersection(Line, Vector3D, Frame, AbsoluteDate)&amp;lt;/code&amp;gt; and similar which return an &amp;lt;code&amp;gt;Intersection&amp;lt;/code&amp;gt; object.This object contains the intersection point as well as the &amp;lt;code&amp;gt;Triangle&amp;lt;/code&amp;gt; containing the intersection point. This method is recursive and is in O(log(n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;buildPoint(LLHCoordinatesSystem, double, double, double, String)&amp;lt;/code&amp;gt; and similar which return the facet point associated to the specified corrinates in the given LLH coordinates system.&lt;br /&gt;
* &amp;lt;code&amp;gt;getApparentRadius&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;getApparentRadiusDirection&amp;lt;/code&amp;gt; methods which provides the local radius of the body shape seen by an observer in the direction of an occulted body or a specified direction using an approximate iterative algorithm. This method is used by EclipseDetector for instance.&lt;br /&gt;
* &amp;lt;code&amp;gt;resize(MarginType, double)&amp;lt;/code&amp;gt; method which returns a resized body shape.&lt;br /&gt;
* &amp;lt;code&amp;gt;closestPointTo&amp;lt;/code&amp;gt; methods which return the two closest points between the line given in input and the current facet body shape. One of the two points belongs to the line, the other to the facet body shape.&lt;br /&gt;
* &amp;lt;code&amp;gt;distanceTo()&amp;lt;/code&amp;gt; method which returns the distance to the body. This method is recursive and is hence in O(log(n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;getNeighbors()&amp;lt;/code&amp;gt; methods which returns the neighbors triangles to:&lt;br /&gt;
** A point or a triangle given a &amp;quot;neighborhood distance&amp;quot;&lt;br /&gt;
** A triangle given a &amp;quot;neighborhood order&amp;quot;. In this case, order 1 returns the immediate neighbors of the triangles, order 2 returns also the neighbors&#039; neighbors and so on.&lt;br /&gt;
This method is recursive and is hence in O(log(n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;getFieldData()&amp;lt;/code&amp;gt; which returns a container &amp;lt;code&amp;gt;FieldData&amp;lt;/code&amp;gt; containing data related to the field of view:&lt;br /&gt;
** Visible triangles from the satellite field of view &amp;lt;code&amp;gt;IFieldOfView&amp;lt;/code&amp;gt;. A visible triangle must be entirely in the field of view and not masked by any other triangle.&lt;br /&gt;
** Contour of the seen triangles. Contour is strictly contained in the field of view&lt;br /&gt;
If main direction of the field of view is provided, this method is recursive and is in O(log(n)). Otherwise, it is in O(n) and is much slower.&lt;br /&gt;
* &amp;lt;code&amp;gt;isInEclipse()&amp;lt;/code&amp;gt; method which returns true if the satellite is currently in eclipse, false otherwise. Penumbra is not taken into account. This method is in O(log(n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;getNeverVisibleTriangles()&amp;lt;/code&amp;gt; which returns a list of facets which are never visible from the provided ephemeris. Visibility criteria is the same as for &amp;lt;code&amp;gt;getFieldData()&amp;lt;/code&amp;gt; method. This method is in O((n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;getNeverEnlightenedTriangles()&amp;lt;/code&amp;gt; which returns a list of facets which are never enlightened by the Sun. Visibility criteria is the same as for &amp;lt;code&amp;gt;getFieldData()&amp;lt;/code&amp;gt; method. This method is in O((n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;getVisibleAndEnlightenedTriangles()&amp;lt;/code&amp;gt; which returns a list of facets which are visible and enlightened at the same time, at least once on the provided ephemeris. Visibility criteria is the same as for &amp;lt;code&amp;gt;getFieldData()&amp;lt;/code&amp;gt; method. This method is in O((n)).&lt;br /&gt;
* &amp;lt;code&amp;gt;getEllipsoidType()&amp;lt;/code&amp;gt; which returns the type of the ellipsoid.&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;code&amp;gt;BodyShapeFitter&amp;lt;/code&amp;gt; allows to build shapes fitted on the main Shape provided as input. Different criteria are available and the type of ellipsoid returned can be obtained by calling the method &amp;lt;code&amp;gt;getEllipsoid(EllipsoidType)&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== EllipsoidPoint====&lt;br /&gt;
&lt;br /&gt;
The ellipsoid point is defined by a latitude, a longitude and an altitude in the frame associated to the ellipsoid (EllipsoidBodyShape). It could be interesting to know the position of a satellite in terms of geodetic coordinates rather than Cartesian ones and vice versa (the corresponding methods in OneAxisEllipsoid).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// equatorial radius of the celestial body&lt;br /&gt;
double ae = 6378137.0;&lt;br /&gt;
// flatness of the celestial body&lt;br /&gt;
double f = 1.0 / 298.257222101;&lt;br /&gt;
// date        &lt;br /&gt;
AbsoluteDate date = AbsoluteDate.J2000_EPOCH;&lt;br /&gt;
// reference frame attached to the body        &lt;br /&gt;
CelestialBodyFrame frame = FramesFactory.getITRF();&lt;br /&gt;
// body shape model (ellipsoid)     &lt;br /&gt;
OneAxisEllipsoid model = new OneAxisEllipsoid(ae, f, frame);&lt;br /&gt;
&lt;br /&gt;
// transformation with jacobian matrix : cartesian to geodetic&lt;br /&gt;
&lt;br /&gt;
// initial cartesian point that will be transformed&lt;br /&gt;
Vector3D cp = new Vector3D(4637885.347, 121344.1308, 4362452.869);&lt;br /&gt;
// coresponding ellipsoid point        &lt;br /&gt;
EllipsoidPoint point = model.buildPoint(cp, frame, date, &amp;quot;point&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// transformation with jacobian matrix : geodetic to cartesian&lt;br /&gt;
&lt;br /&gt;
// coresponding Cartesian point        &lt;br /&gt;
Vector3D cp2 = model.computePositionFromEllipsodeticCoordinates(0.852479154923577, 0.0423149994747243, 111.6);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It could be also interesting to obtain the jacobian matrix of the transformation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// transformation : cartesian to geodetic&lt;br /&gt;
&lt;br /&gt;
final double[][] computedJacobian = LLHCoordinatesSystem.ELLIPSODETIC.jacobianFromCartesian(point);&lt;br /&gt;
&lt;br /&gt;
// transformation : geodetic to cartesian&lt;br /&gt;
&lt;br /&gt;
final double[][] computedJacobian2 = LLHCoordinatesSystem.ELLIPSODETIC.jacobianToCartesian(point);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The enumeration LLHCoordinatesSystem.ELLIPSODETIC allows the computation of the time derivatives of the LLH coordinates of a point. There are two algorithms implemented: &lt;br /&gt;
* Analytical calculation for OneAxisEllipsoid &lt;br /&gt;
* Finite-difference numerical calculation for all other types of ellipsoid, such as ThreeAxisEllipsoid&lt;br /&gt;
&lt;br /&gt;
The selection between the analytical and numerical method is automatic and the only function to call is the following:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double[] LLHCoordinatesSystem.ELLIPSODETIC.computeLLHRates(final BodyShape bodyShape, final PVCoordinates pv, final Frame frame, &lt;br /&gt;
final AbsoluteDate date) &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The longitude, latitude, and height rates are returned and expressed in rad/s, rad/s, et m/s respectively.&lt;br /&gt;
&lt;br /&gt;
Here is a full example of how to use this functionality:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Create Earth OneAxisEllipsoid&lt;br /&gt;
final double ae = 6378137.0;// GRS80 constant&lt;br /&gt;
final double flattening = 1.0 / 298.257222101;// GRS80 constant&lt;br /&gt;
final CelestialBodyFrame itrf = FramesFactory.getITRF();&lt;br /&gt;
final CelestialBodyFrame gcrf = FramesFactory.getGCRF();&lt;br /&gt;
final OneAxisEllipsoid earth = new OneAxisEllipsoid(ae, flattening, itrf);&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2010, 7, 9, 20, 30, 0);&lt;br /&gt;
&lt;br /&gt;
// Create orbit around the Earth in GCRF&lt;br /&gt;
final double mu = 3.986005e14;// GRS80 constant&lt;br /&gt;
final KeplerianOrbit orbit = KeplerianOrbit(ae + 700e3, 0.0, 0.5, 1.2, 1.1, 2.3, PositionAngle.TRUE, gcrf, date, mu);&lt;br /&gt;
&lt;br /&gt;
// Compute the rates using the analytical implementation&lt;br /&gt;
final double[] rates = LLHCoordinatesSystem.ELLIPSODETIC&lt;br /&gt;
                .computeLLHRates(earth, orbit.getPVCoordinates(), gcrf, date);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
TBD&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ApparentRadiusProvider&#039;&#039;&#039;&lt;br /&gt;
|Interface representing apparent radius providers.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/ApparentRadiusProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BodyShape&#039;&#039;&#039;&lt;br /&gt;
|Interface representing the rigid surface shape of a natural body.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/BodyShape.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBody&#039;&#039;&#039;&lt;br /&gt;
|Interface for celestial bodies like Sun, Moon or solar system planets.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/CelestialBody.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBodyEphemeris&#039;&#039;&#039;&lt;br /&gt;
|Interface for celestial body ephemeris like Sun, Moon or solar system planets.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/CelestialBodyEphemeris.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBodyLoader&#039;&#039;&#039;&lt;br /&gt;
|Interface for celestial body loaders.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/CelestialBodyLoader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBodyEphemerisLoader&#039;&#039;&#039;&lt;br /&gt;
|Interface for celestial body ephemeris loaders.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/CelestialBodyEphemerisLoader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MeshLoader&#039;&#039;&#039;&lt;br /&gt;
|Interface for FacetCelestialBody mesh provider.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/mesh/MeshProvider.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CelestialBodyFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory class for bodies of the solar system.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/CelestialBodyFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BodyPoint&#039;&#039;&#039;&lt;br /&gt;
|Point location relative to a 2D body surface.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/GeodeticPoint.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;JPLCelestialBodyLoader&#039;&#039;&#039;&lt;br /&gt;
|Loader for JPL ephemerides binary files (DE 405, DE 406, ...).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/JPLCelestialBodyLoader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OneAxisEllipsoid&#039;&#039;&#039;&lt;br /&gt;
|Modeling of a one-axis ellipsoid.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/OneAxisEllipsoid.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ThreeAxisEllipsoid&#039;&#039;&#039;&lt;br /&gt;
|Modeling of a tri-axis ellipsoid.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/ThreeAxisEllipsoid.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MeeusSun&#039;&#039;&#039;&lt;br /&gt;
|Position of the Sun according to Meeus model. Three models with there appropriate equations are avaible : the standard model (former MeeusSun), Stela model (former MeeuSunStela) and an on-board model&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/MeeusSun.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MeeusMoon&#039;&#039;&#039;&lt;br /&gt;
|Position of the Moon according to Meeus model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/MeeusMoon.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BasicBoardSun&#039;&#039;&#039;&lt;br /&gt;
|Direction of the Sun according to a basic board Sun model.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/BasicBoardSun.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UserCelestialBody&#039;&#039;&#039;&lt;br /&gt;
|User-defined celestial body&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/UserCelestialBody.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UserIAUPole&#039;&#039;&#039;&lt;br /&gt;
|User-defined IAU pole motion&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/UserIAUPole.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IAUPoleFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory for retrieval of solar system bodies IAU pole data&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/IAUPoleFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IAUPoleFunction&#039;&#039;&#039;&lt;br /&gt;
|Atomic IAU pole function. IAU pole data is the sum of atomic IAUPoleFunction.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/IAUPoleFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FacetBodyShape&#039;&#039;&#039;&lt;br /&gt;
|Celestial body defined by a mesh.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/mesh/FacetBodyShape.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BodyShapeFitter&#039;&#039;&#039;&lt;br /&gt;
|Fitter for a given body shape provided as input.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/mesh/BodyShapeFitter.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Triangle&#039;&#039;&#039;&lt;br /&gt;
|Unitary facet (triangle) for a FacetCelestialBody.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/mesh/Triangle.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ObjMeshLoader&#039;&#039;&#039;&lt;br /&gt;
|.obj 3D file mesh loader.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/mesh/ObjMeshLoader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeodeticMeshLoader&#039;&#039;&#039;&lt;br /&gt;
|Mesh loader for ASCII files describing the body with latitude/longitude/altitude components (1 per line).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/bodies/mesh/GeodeticMeshLoader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.18_Mathematics&amp;diff=4143</id>
		<title>Catégorie:User Manual 4.18 Mathematics</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.18_Mathematics&amp;diff=4143"/>
		<updated>2026-06-10T08:55:30Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec «  == Introduction == center  &amp;lt;center&amp;gt;&amp;lt;blockquote&amp;gt; Willingly would I burn to death like Phaeton,&amp;lt;br&amp;gt; were this the price for reaching the sun and&amp;lt;br&amp;gt; learning its shape, its size and its substance.&amp;lt;br&amp;gt; &amp;#039;&amp;#039;Eudoxus of Cnidus (408 - 355 B.C.)&amp;#039;&amp;#039;&amp;lt;/blockquote&amp;gt;&amp;lt;/center&amp;gt;  This section is a short presentation of the Math Library implemented in PATRIUS.  The Math library of PATRIUS is based on the Open-source Commons Math library.  Commons-Math has enti... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Introduction ==&lt;br /&gt;
[[File:eudoxus-1.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;blockquote&amp;gt;&lt;br /&gt;
Willingly would I burn to death like Phaeton,&amp;lt;br&amp;gt;&lt;br /&gt;
were this the price for reaching the sun and&amp;lt;br&amp;gt;&lt;br /&gt;
learning its shape, its size and its substance.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Eudoxus of Cnidus (408 - 355 B.C.)&#039;&#039;&amp;lt;/blockquote&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This section is a short presentation of the Math Library implemented in PATRIUS.&lt;br /&gt;
&lt;br /&gt;
The Math library of PATRIUS is based on the Open-source Commons Math library.&lt;br /&gt;
&lt;br /&gt;
Commons-Math has entirely been included in PATRIUS library. It is accessible through Patrius math package: fr.cnes.sirius.patrius.math package.&lt;br /&gt;
&lt;br /&gt;
Since V4.2, the user can choose and define its low-level math framework (cos, sin, exp, etc.).&lt;br /&gt;
&lt;br /&gt;
== Applicable and Reference Documents ==&lt;br /&gt;
=== Applicable Documents ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[A1]&#039;&#039;&#039;      &#039;&#039;CDCF - Fonctions de Base du Patrimoine de Dynamique du Vol&#039;&#039;, V1.2, SIRIUS-CF-DV-0049-CN, 2011.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;[A2]&#039;&#039;&#039;      &#039;&#039;Dossier de réutilisation Orekit et Commons Math&#039;&#039;, V1.0, SIRIUS-DLR-DV-0080-CN, 2010.&lt;br /&gt;
&lt;br /&gt;
=== Reference Documents ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[R1]&#039;&#039;&#039;      Nürnberg, R.; &#039;&#039;Distance from a Point to an Ellipse&#039;&#039;, Imperial College London, 2006, [http://www2.imperial.ac.uk/~~rn/distance2ellipse.pdf http://www2.imperial.ac.uk/~~rn/distance2ellipse.pdf].&lt;br /&gt;
&lt;br /&gt;
== Glossary ==&lt;br /&gt;
None Applicable.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The Math package of PATRIUS has been developed according to the SIRIUS Scope Statement &#039;&#039;&#039;[A1]&#039;&#039;&#039;. The themes developed are described hereafter:&lt;br /&gt;
&lt;br /&gt;
; Constants&lt;br /&gt;
: Implementation of mathematical and physical constants.&lt;br /&gt;
&lt;br /&gt;
; Comparisons of Numbers&lt;br /&gt;
: For this theme, classes and methods of comparison that allow a precise comparison of number representations have been developed.&lt;br /&gt;
&lt;br /&gt;
; Angles&lt;br /&gt;
: For this theme, angle utilities, such as intervals, have been implemented, and allow the user to perform multiple rigorous operations with modulus problems taken into account.&lt;br /&gt;
&lt;br /&gt;
; Low-level math frameworks&lt;br /&gt;
: A low-level math framework provides methods to compute simple math function such as sin, cos, exp, log, etc. For this theme, a generic interface for low-level math framework has been defined. Several implementations are available (FastMath and Jafama).&lt;br /&gt;
&lt;br /&gt;
; Dispersions&lt;br /&gt;
: Various algorithms have been developped to handle different kinds of random number generation.&lt;br /&gt;
&lt;br /&gt;
; Vectors&lt;br /&gt;
: Vector-specific operations, particularly in the case of 2D and 3D vectors, have been developed and implemented in classes such as Vector3D. It is understood that by vector, a real column vector is actually manipulated.&lt;br /&gt;
&lt;br /&gt;
; Matrices&lt;br /&gt;
: Matrix-specific operations, particularly in the case of 3x3 and 6x6 matrices, have been developed and implemented in classes such as Matrix3D.&lt;br /&gt;
&lt;br /&gt;
; Quaternions&lt;br /&gt;
: Quaternion-specific operations have been developed and implemented in classes such as Quaternion. It is understood that this class represents the mathematical object quaternion and, as such, is not necessarily a rotation quaternion.&lt;br /&gt;
&lt;br /&gt;
; Rotations&lt;br /&gt;
: Rotations implemented in PATRIUS are algebraic rotations that can be represented by normalized quaternions, rotation matrices or sequences of Euler angles. The prime objective of this design is to have all the rotation representations combined, 8making it easier for the user to manipulate such an object.&lt;br /&gt;
&lt;br /&gt;
; Geometry&lt;br /&gt;
: The geometry section presents the geometry classes developed and implemented in PATRIUS. It currently includes the following objects : lines, planes, plates, parallelepipeds, cylinders, cones, ellipsoids and spherical caps.&lt;br /&gt;
&lt;br /&gt;
; Interpolation methods&lt;br /&gt;
: Implementation of several methods : spline, bicubic, tricubic, Lagrange and Newton interpolation.&lt;br /&gt;
&lt;br /&gt;
; Root-Finding algorithm&lt;br /&gt;
: Implementation of several algorithms : Brent, Newton, Bisection and Müller.&lt;br /&gt;
&lt;br /&gt;
; Trigonometric polynomials&lt;br /&gt;
: Real trigonometric polynomials are implemented.&lt;br /&gt;
&lt;br /&gt;
; Numerical differentiation&lt;br /&gt;
: Implementation of two numerical differentiation methods: finite difference and Ridders.&lt;br /&gt;
&lt;br /&gt;
; Numerical integration&lt;br /&gt;
: Implementation of two numerical integration methods: Trapezoidal and Simpson.&lt;br /&gt;
&lt;br /&gt;
; Numerical ordinary differential equations&lt;br /&gt;
: It is the part of numerical analysis which studies the numerical solution of ordinary differential equations (ODEs). Please note: this may sometimes be called numerical integration, but we assume here that numerical integration only refers to the computation of integrals (see the corresponding theme).&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:User Manual 4.18]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Trigonometric_Polynomials_and_Fourier_Series&amp;diff=4142</id>
		<title>User Manual 4.18 Trigonometric Polynomials and Fourier Series</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Trigonometric_Polynomials_and_Fourier_Series&amp;diff=4142"/>
		<updated>2026-06-10T08:55:03Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__ == Introduction == === Scope === This section presents the Trigonometric Polynomials implemented in PATRIUS as well as Fourier Series.  === Javadoc === The trigonometric polynomial (and related) objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.analysis.polynomials&amp;lt;/code&amp;gt; and the FFT algorithms in &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.transform&amp;lt;/code&amp;gt;  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=&amp;quot;col&amp;quot;| Javadoc |- |Patrius |[{... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section presents the Trigonometric Polynomials implemented in PATRIUS as well as Fourier Series.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The trigonometric polynomial (and related) objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.analysis.polynomials&amp;lt;/code&amp;gt; and the FFT algorithms in &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.transform&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/polynomials/package-summary.html Package fr.cnes.sirius.patrius.math.geometry.analysis.polynomials]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/transform/package-summary.html Package fr.cnes.sirius.patrius.math.transform]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
Useful resources for this theme can be found here :&lt;br /&gt;
&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Trigonometric_polynomial Trigonometric Polynomials]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/List_of_trigonometric_identities List of trigonometric identities]&lt;br /&gt;
* [http://en.wikipedia.org/wiki/Fourier_series Fourier Series]&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
None.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Trigonometric Polynomials ===&lt;br /&gt;
The trigonometric polynomials are defined as :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\forall t \in \mathbb{R}, P(t) = a_0 + \sum_{k=0}^n \left( a_k \cos(kt) + b_k \sin(kt) \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the primitive of such a function is :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\forall t \in \mathbb{R}, P(t) = a_0 t + c^{te} + \sum_{k=0}^n \left( {-b_k \over k} \cos(kt) + {a_k \over k} \sin(kt) \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Classes that represent these functions are described in this section.&lt;br /&gt;
=== Fourier Series ===&lt;br /&gt;
Let &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; be a periodic, real variable, real function with period &amp;lt;math&amp;gt;T&amp;lt;/math&amp;gt;. The &#039;&#039;partial sums of the Fourier Series&#039;&#039; of &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; are given by&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
\forall N \in \mathbb{R}^{+*}, \, \left(S_Nf\right)(x) = a_0 + \sum_{n=1}^N\left(a_n\cos\left(n t {2\pi\over T}\right) + b_n\sin\left(n t {2\pi\over T}\right)\right)&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The Fourier coefficients (n &amp;gt; 0) of &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; are given by :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
a_0 = {1\over T}\int_{-T/2}^{T/2} \! f(t) \, \mathrm{d}t&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
a_n = {2\over T}\int_{-T/2}^{T/2} \! f(t) \cos\left(n t {2\pi\over T}\right) \, \mathrm{d}t&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;&lt;br /&gt;
b_n = {2\over T}\int_{-T/2}^{T/2} \! f(t) \sin\left(n t {2\pi\over T}\right) \, \mathrm{d}t &lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Classes that allow decomposing functions into finite Fourier series are described.&lt;br /&gt;
&lt;br /&gt;
=== Fast Fourier Transforms ===&lt;br /&gt;
A fast Fourier transform (FFT) is an algorithm to compute the discrete Fourier transform (DFT) and its inverse. Fourier analysis converts time (or space) to frequency and vice versa. An FFT rapidly computes such transformations by factorizing the DFT matrix into a product of sparse (mostly zero) factors.&amp;lt;br&amp;gt;&lt;br /&gt;
Let &amp;lt;math&amp;gt;( X_0, ..., X_{N-1})&amp;lt;/math&amp;gt;  be complex numbers. The DFT is defined by the formula&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;X_k = \sum^{N-1}_{n=0} x_n e^{-2i\pi k n/N}, \quad k=\left\{0, ..., N-1\right\}.&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;code&amp;gt;FastFourierTransformer.java&amp;lt;/code&amp;gt; owns two methods&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;transform(final double[] f, final TransformType type)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;transform(final Complex[] f, final TransformType type)&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
where &amp;lt;code&amp;gt;TransformType&amp;lt;/code&amp;gt; is an enumeration that defines the type of transform which is to be computed. It can be FORWARD or INVERSE.&lt;br /&gt;
&lt;br /&gt;
Depending on the size, this method will use a radix-2 algorithm if the size is a power-of-two, and the Bluestein algorithm otherwise. Both algorithms are explained above. &lt;br /&gt;
&lt;br /&gt;
==== The Cooley–Tukey &amp;amp;  radix-2 the algorithm ====&lt;br /&gt;
&lt;br /&gt;
By far the most commonly used FFT algorithm. This is a divide and conquer algorithm that recursively breaks down a DFT of any composite size &amp;lt;math&amp;gt;N = N_1N_2&amp;lt;/math&amp;gt; into many smaller DFTs of sizes &amp;lt;math&amp;gt;N_1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;N_2&amp;lt;/math&amp;gt;, along with &amp;lt;math&amp;gt;O(N)&amp;lt;/math&amp;gt; multiplications by complex roots of unity.&amp;lt;br&amp;gt;&lt;br /&gt;
The radix-2 algorithme is the most common use of FFT algorithm and is based on the Cooley–Tukey algorithm. It divides the transform into two pieces of size &amp;lt;math&amp;gt;N/2&amp;lt;/math&amp;gt; at each step, and is therefore limited to power-of-two sizes.&lt;br /&gt;
&lt;br /&gt;
==== The Bluestein algorithm ====&lt;br /&gt;
&lt;br /&gt;
It is commonly called the chirp z-transform algorithm. It computes the discrete Fourier transform (DFT) of arbitrary sizes (including prime sizes) by re-expressing the DFT as a convolution. For more information, see [http://en.wikipedia.org/wiki/Bluestein%27s_FFT_algorithm http://en.wikipedia.org/wiki/Bluestein%27s_FFT_algorithm]&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Usage of a trigonometric polynomial ===&lt;br /&gt;
* To create the polynomial &amp;lt;math&amp;gt;P(x) =-2 + \cos(x) + 2\sin(3x)&amp;lt;/math&amp;gt;, use the following code snippet :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double a0 =-2;&lt;br /&gt;
double[] a = new double[] {1, 0, 0};&lt;br /&gt;
double[] b = new double[] {0, 0, 2};&lt;br /&gt;
TrigonometricPolynomialFunction myPol2 = new TrigonometricPolynomialFunction(a0, a, b);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* To get the value of the second derivative at &amp;lt;math&amp;gt;x = 5&amp;lt;/math&amp;gt;, use the following snippet :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double result = myPol2.value(2,5);&lt;br /&gt;
// equivalent to&lt;br /&gt;
double result = myPol2.polynomialDerivative(2).value(5);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* To get the primitive :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// With an integration constant c = 1 :&lt;br /&gt;
TrigonometricPolynomialPrimitive result = myPol2.polynomialPrimitive(1.);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* To multiply two trigonometric polynomials &amp;lt;math&amp;gt;p1&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;p2&amp;lt;/math&amp;gt; :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
TrigonometricPolynomialFunction result = p1.multiply(p2);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Decomposing a UnivariateFunction into a Fourier Series ===&lt;br /&gt;
Given a user function with period T :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
UnivariateFunction f = new UnivariateFunction () {&lt;br /&gt;
    public double value(double x) {&lt;br /&gt;
         // ...&lt;br /&gt;
         return result;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The user must build an instance of the FourierDecompositionEngine (using an [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/integration/UnivariateIntegrator.html integrator]) :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
FourierDecompositionEngine engine = new FourierDecompositionEngine( integrator );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And pass the function, period and approximation order to it.&#039;&#039;&#039;NOTE :&#039;&#039;&#039; It is left up to the user to make sure that the specified period is coherent with the function as no internal check is conducted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
engine.setOrder(10);&lt;br /&gt;
engine.setFunction(f, T);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, the user can call the &amp;lt;code&amp;gt;decompose( )&amp;lt;/code&amp;gt; method :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
FourierSeriesApproximation approximation = engine.decompose();&lt;br /&gt;
FourierSeries fourier = approximation.getFourier();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;u&amp;gt;Example&amp;lt;/u&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to decompose a square function of period 2 to the 10th order :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// function definition&lt;br /&gt;
UnivariateFunction function = new UnivariateFunction() {&lt;br /&gt;
   public double value(final double x) {&lt;br /&gt;
   final double local = x- FastMath.floor(x / 2) * 2;&lt;br /&gt;
      if (local &amp;gt;= 1) {&lt;br /&gt;
         return-1;&lt;br /&gt;
      } else {&lt;br /&gt;
         return 1;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Engine parameters&lt;br /&gt;
UnivariateIntegrator integrator = new LegendreGaussIntegrator(5, 1e-14, 1e-14);&lt;br /&gt;
FourierDecompositionEngine engine = new FourierDecompositionEngine(integrator);&lt;br /&gt;
engine.setMaxEvals(Integer.MAX_VALUE);&lt;br /&gt;
&lt;br /&gt;
// decompose&lt;br /&gt;
double period = 2;&lt;br /&gt;
engine.setOrder(10);&lt;br /&gt;
engine.setFunction(function, period);&lt;br /&gt;
FourierSeriesApproximation result = engine.decompose();&lt;br /&gt;
FourierSeries fourier = result.getFourier();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function and its approximation are shown hereunder. The parasite undulations are known as the [http://en.wikipedia.org/wiki/Gibbs_phenomenon Gibbs Phenomenon] :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:square10.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UnivariateDifferentiableFunction&#039;&#039;&#039;&lt;br /&gt;
|Extension of UnivariateFunction representing a differentiable univariate function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis//differentiation/UnivariateDifferentiableFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IntegrableUnivariateFunction&#039;&#039;&#039;&lt;br /&gt;
|Extension of UnivariateRealFunction representing an integrable univariate function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/IntegrableUnivariateFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UnivariateFunction&#039;&#039;&#039;&lt;br /&gt;
|Interface representing an univariate function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/UnivariateFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IFastFourierTransformer&#039;&#039;&#039;&lt;br /&gt;
|Interface representing a FFT.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/transform/IFastFourierTransformer.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FourierDecompositionEngine&#039;&#039;&#039;&lt;br /&gt;
|Decompose a UnivariateFunction as a Fourier Series using TrigonometricPolynomialFunction representation.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/polynomials/FourierDecompositionEngine.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FourierSeries&#039;&#039;&#039;&lt;br /&gt;
|This class represents a finite Fourier Series.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/polynomials/FourierSeries.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FourierSeriesApproximation&#039;&#039;&#039;&lt;br /&gt;
|Holder for a UnivariateFunction and its FourierSeries approximation.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/polynomials/FourierSeriesApproximation.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TrigonometricPolynomialFunction&#039;&#039;&#039;&lt;br /&gt;
|This class is the Trigonometric Polynomial Function class.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/polynomials/TrigonometricPolynomialFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TrigonometricPolynomialPrimitive&#039;&#039;&#039;&lt;br /&gt;
|This class represents a Trigonometric Polynomial Primitive.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/polynomials/TrigonometricPolynomialPrimitive.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbstractFastFourierTransformer&#039;&#039;&#039;&lt;br /&gt;
| Abstract class representing a FFT.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/transform/AbstractFastFourierTransformer.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FastFourierTransformer&#039;&#039;&#039;&lt;br /&gt;
| Computes the FFT for real and complex arrays.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/transform/FastFourierTransformer.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Rotations_and_quaternions&amp;diff=4141</id>
		<title>User Manual 4.18 Rotations and quaternions</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Rotations_and_quaternions&amp;diff=4141"/>
		<updated>2026-06-10T08:54:35Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === This section describes rotation and quaternions.  === Javadoc === The relevant packages are documented here :  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=&amp;quot;col&amp;quot;| Javadoc |- | Patrius  |[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/package-summary.html Package fr.cnes.sirius.patrius.math.geometry.euclidean.threed] |- | Patrius |[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/complex/packa... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes rotation and quaternions.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The relevant packages are documented here :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
| Patrius &lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/package-summary.html Package fr.cnes.sirius.patrius.math.geometry.euclidean.threed]&lt;br /&gt;
|-&lt;br /&gt;
| Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/complex/package-summary.html Package fr.cnes.sirius.patrius.math.complex]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The relevant functionality can be found in the following packages :&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.complex&amp;lt;/code&amp;gt; for the Quaternion class.&lt;br /&gt;
* &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.cnesmerge.geometry.euclidean.threed&amp;lt;/code&amp;gt; for the Rotation class.&lt;br /&gt;
* &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.geometry.euclidean.threed&amp;lt;/code&amp;gt; for the RotationOrder class.&lt;br /&gt;
&lt;br /&gt;
[[File:PATRIMOINESIRIUSSUMDiagQuatRot.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Rotations ===&lt;br /&gt;
The Rotation is part of the math package fr.cnes.sirius.patrius.math.geometry.euclidean.threed.&lt;br /&gt;
&lt;br /&gt;
The Rotation is represented by a [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/complex/Quaternion.html quaternion]: it is a unit quaternion (a quaternion of norm one).&amp;lt;br&amp;gt;&lt;br /&gt;
The [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Rotation.html Rotation class] represents an algebraic rotation (i.e. a mathematical rotation).&lt;br /&gt;
&lt;br /&gt;
In a three dimensional space, a rotation &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; is a function that maps vectors to vectors &amp;lt;math&amp;gt;r: \vec{v} \mapsto \vec{w}&amp;lt;/math&amp;gt;. The rotation can be defined by one angle &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; and one axis &amp;lt;math&amp;gt;\vec{u}&amp;lt;/math&amp;gt;, transforming &amp;lt;math&amp;gt;\vec{v}&amp;lt;/math&amp;gt; into &amp;lt;math&amp;gt;\vec{w}&amp;lt;/math&amp;gt; as described in the following figure.&lt;br /&gt;
&lt;br /&gt;
[[File:Rotations.png|center]]&lt;br /&gt;
&lt;br /&gt;
There are several ways to represent rotations. Amongst the most used are quaternions and rotation matrices. The following paragraphs aim to discuss each of them.&lt;br /&gt;
&lt;br /&gt;
=== Quaternions ===&lt;br /&gt;
An advantageous way to deal with rotations is by using quaternions (class &amp;lt;code&amp;gt;Quaternion&amp;lt;/code&amp;gt;). The quaternion that represents the rotation &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; defined by an angle &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; and a &#039;&#039;&#039;normalized&#039;&#039;&#039; axis &amp;lt;math&amp;gt;\vec{u}&amp;lt;/math&amp;gt; is :&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;Q = \left( \begin{array}{ccc}&lt;br /&gt;
cos(\theta / 2) \\&lt;br /&gt;
  \vec{u}.sin(\theta / 2) \end{array} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With &amp;lt;math&amp;gt;\vec{u} = ( u_x, u_y, u_z )&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; can also be written as :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;Q = \left( \begin{array}{ccc}&lt;br /&gt;
cos(\theta / 2) \\&lt;br /&gt;
  u_x.sin(\theta / 2) \\&lt;br /&gt;
  u_y.sin(\theta / 2) \\&lt;br /&gt;
  u_z.sin(\theta / 2)\end{array} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Quaternions that represent rotations are normalized :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;||Q|| = q_0^2 + q_1^2 + q_2^2 + q_3^2 = 1&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For normalized quaternions, the inverse quaternion &amp;lt;math&amp;gt;Q^{-1}&amp;lt;/math&amp;gt; is the same as the conjugate &amp;lt;math&amp;gt;Q^*&amp;lt;/math&amp;gt;: &lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;Q^{-1} =Q^* = \left( \begin{array}{ccc} &lt;br /&gt;
cos(\theta / 2) \\ &lt;br /&gt;
-\vec{u}.sin(\theta / 2) \end{array} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The image &amp;lt;math&amp;gt;\vec{w}&amp;lt;/math&amp;gt; of a vector &amp;lt;math&amp;gt;\vec{v}&amp;lt;/math&amp;gt; transformed by the rotation represented by &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; is given by :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\vec{w} = Q.\vec{v}.Q^{*}&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Examples of rotations and associated quaternions====&lt;br /&gt;
The rotation defined by the angle &amp;lt;math&amp;gt;\theta = \pi/2&amp;lt;/math&amp;gt; and the axis &amp;lt;math&amp;gt;\vec{u} = \vec{z}&amp;lt;/math&amp;gt; is represented by the quaternion :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;Q = \left( \begin{array}{ccc}&lt;br /&gt;
cos(\pi / 4) \\&lt;br /&gt;
  0.sin(\pi / 4) \\&lt;br /&gt;
  0.sin(\pi / 4) \\&lt;br /&gt;
  1.sin(\pi / 4)\end{array} \right) = \left( \begin{array}{ccc}&lt;br /&gt;
\sqrt 2 / 2 \\&lt;br /&gt;
  0 \\&lt;br /&gt;
  0 \\&lt;br /&gt;
  \sqrt 2 / 2\end{array} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The rotation defined by the angle &amp;lt;math&amp;gt;\theta = 2\pi/3&amp;lt;/math&amp;gt; and the axis &amp;lt;math&amp;gt;\vec{u} = (1,1,1)&amp;lt;/math&amp;gt; (witch has to be normalized) is represented by the quaternion :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;Q = \left( \begin{array}{ccc}&lt;br /&gt;
cos(\pi / 3) \\&lt;br /&gt;
  1/\sqrt 3.sin(\pi / 3) \\&lt;br /&gt;
  1/\sqrt 3.sin(\pi / 3) \\&lt;br /&gt;
  1/\sqrt 3.sin(\pi / 3)\end{array} \right) = \left( \begin{array}{ccc}&lt;br /&gt;
1 / 2 \\&lt;br /&gt;
1 / 2 \\&lt;br /&gt;
1 / 2 \\&lt;br /&gt;
1 / 2\end{array} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Rotation composition with quaternions====&lt;br /&gt;
&amp;lt;math&amp;gt;r_1: \vec{w_1} \mapsto \vec{w_2}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;r_2: \vec{w_2} \mapsto \vec{w_3}&amp;lt;/math&amp;gt; being two known rotations, the rotation composition &amp;lt;math&amp;gt;r: \vec{w_1} \mapsto \vec{w_3}&amp;lt;/math&amp;gt; can be computed as well. The quaternion corresponding to that new rotation is: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;Q = Q{_2}.Q{_1}&amp;lt;/math&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be proven as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\vec{w_2} = Q{_1}.\vec{w_1} .Q_{1}^{-1}&amp;lt;/math&amp;gt; &lt;br /&gt;
&amp;lt;math&amp;gt;\vec{w_3} = Q{_2}.\vec{w_2} .Q_{2}^{-1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Substituting &amp;lt;math&amp;gt;\vec{w_2}&amp;lt;/math&amp;gt; in the expression of &amp;lt;math&amp;gt;\vec{w_3}&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;\vec{w_3} = Q{_2}.Q{_1}.\vec{w_1} .Q_{1}^{-1}.Q_{2}^{-1} = (Q{_2}.Q{_1}).\vec{w_1} .(Q_{2}.Q_{1})^{-1} = Q.\vec{w_1} .Q^{-1}&amp;lt;/math&amp;gt;.&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notice that in the expression of the quaternion &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt; the rightmost quaternion is the one corresponding to the first rotation to  be performed.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Rotation matrices ===&lt;br /&gt;
The matrix representation of a rotation is very intuitive altough more redundant compared to quaternions. A rotation matrix is a 3x3 (real) square matrix.&amp;lt;br&amp;gt;&lt;br /&gt;
If the rotation &amp;lt;math&amp;gt;r&amp;lt;/math&amp;gt; transforms an inital basis &amp;lt;math&amp;gt;(\vec{x}, \vec{y}, \vec{z})&amp;lt;/math&amp;gt; to a new one &amp;lt;math&amp;gt;(\vec{i}, \vec{j}, \vec{k})&amp;lt;/math&amp;gt; the columns of the rotation matrix are given by the components of the rotated basis vectors, expressed in the initial one. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&amp;lt;math&amp;gt;M = \left( \begin{array}{ccc}&lt;br /&gt;
i_x &amp;amp; j_x &amp;amp; k_x \\&lt;br /&gt;
i_y &amp;amp; j_y &amp;amp; k_y \\&lt;br /&gt;
i_z &amp;amp; j_z &amp;amp; k_z \end{array} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
The matrix &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; has the following properties:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; is orthogonal (each column has norm 1)&lt;br /&gt;
* &amp;lt;math&amp;gt;det(M) = 1&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;M^{-1} = M^{T}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Rotation matrix in term of quaternions====&lt;br /&gt;
Given a quaternion &amp;lt;math&amp;gt;Q = ( q_0, q_1, q_2, q_3 )&amp;lt;/math&amp;gt; the rotation matrix has the following expression in term of the components of &amp;lt;math&amp;gt;Q&amp;lt;/math&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;M = \left( \begin{array}{ccc}&lt;br /&gt;
q_0^2 + q_1^2-q_2^2  -q_3^2  &amp;amp; 2q_1q_2 + q_0q_3 &amp;amp; 2q_0q_2 + q_1q_3 \\&lt;br /&gt;
2q_0q_3 + q_1q_2 &amp;amp; q_0^2 + q_1^2-q_2^2  -q_3^2 &amp;amp; 2q_2q_3 + q_0q_1 \\&lt;br /&gt;
2q_1q_3 + q_0q_2 &amp;amp; 2q_0q_1 + q_2q_3 &amp;amp; q_0^2 + q_1^2-q_2^2  -q_3^2 \end{array} \right)&amp;lt;/math&amp;gt;&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Rotation interpolation ===&lt;br /&gt;
There are two implemented rotations interpolation methods :&lt;br /&gt;
&lt;br /&gt;
- LERP&amp;lt;br&amp;gt;&lt;br /&gt;
- SLERP&lt;br /&gt;
&lt;br /&gt;
=== LERP ===&lt;br /&gt;
&lt;br /&gt;
The LERP (linear interpolation method) is a method of curve fitting using linear polynomials. It is used for rotation interpolation goal in the PATRIUS library and relies on quaternion properties.&amp;lt;br&amp;gt;&lt;br /&gt;
Let &amp;lt;math&amp;gt;q_{0}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;q_{1}&amp;lt;/math&amp;gt; be two normed quaternions and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; an interpolation parameter in the [0;1] range. We can defined &amp;lt;math&amp;gt;q_{t}&amp;lt;/math&amp;gt; as the interpolated quaternion so as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{t}= q_{0} + t\times(q_{1}- q_{0})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SLERP ===&lt;br /&gt;
&lt;br /&gt;
The SLERP (spherical linear interpolation method) refers to constant-speed motion along a unit-radius great circle arc, given the ends and an interpolation parameter between 0 and 1.It is used for rotation interpolation goal in the PATRIUS library. It relies on quaternion capabilities.&lt;br /&gt;
Let &amp;lt;math&amp;gt;q_{0}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;q_{1}&amp;lt;/math&amp;gt; be two normed quaternions and &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; an interpolation parameter in the [0;1] range.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;First method:&amp;lt;/u&amp;gt;&lt;br /&gt;
We can defined &amp;lt;math&amp;gt;q_{t}&amp;lt;/math&amp;gt; as the interpolated quaternion so as :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{t} = q_{0} ( q_{0}^{-1} q_{1} )&#039;&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where-prime- operation is defined such as : &amp;lt;math&amp;gt;t, q(\theta, \vec{u}): q’ = q(t \times \theta, \vec{u})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Second method:&amp;lt;/u&amp;gt;&lt;br /&gt;
Another approch is to compute qt so as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;q_{t} = q_{0} \frac{\sin (1-t)\lambda}{\sin \lambda} + q_{1} \frac{\sin (t \lambda)}{\sin \lambda}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with lambda defined so as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\cos \lambda = q_{0} . q_{1}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This latest approach saves computing time when dealing with many SLERP computing.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Building Rotations ===&lt;br /&gt;
Rotations can be represented by several different mathematical entities (matrices, axis and angle, Cardan or Euler angles, quaternions). The user can build a rotation from any of these representations, and any of these representations can be retrieved from a [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Rotation.html Rotation instance].&lt;br /&gt;
In addition, a rotation can also be built implicitly from a set of vectors and their image or just a vector and its image.&lt;br /&gt;
&lt;br /&gt;
==== Rotation quaternion ====&lt;br /&gt;
&lt;br /&gt;
The rotation can be built from a rotation quaternion using one of the following constructors :&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;&#039;&#039;Rotation(boolean needsNormalization, double q0, double q1, double q2, double q3)&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*&#039;&#039;&#039;&#039;&#039;Rotation(boolean needsNormalization, final Quaternion quaternion)&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
*&#039;&#039;&#039;&#039;&#039;Rotation(boolean needsNormalization, final double[] q)&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
A rotation can be built from a normalized quaternion, i.e. a quaternion for which &amp;lt;math&amp;gt;q_0^2 + q_1^2 + q_2^2 + q_3^2 = 1&amp;lt;/math&amp;gt;. If the quaternion is not normalized, the constructor can normalize it in a preprocessing step. &lt;br /&gt;
&lt;br /&gt;
Note that some conventions put the scalar part of the quaternion as the fourth component and the vector part as the first three components. The scalar part is put as the first component.&lt;br /&gt;
&lt;br /&gt;
The rotation quaternion can be retrieve using &#039;&#039;&#039;&#039;&#039;getQuaternion()&#039;&#039;&#039;&#039;&#039; or &#039;&#039;&#039;&#039;&#039;getQi()&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Axis-angle representation ====&lt;br /&gt;
&lt;br /&gt;
The rotation can be built from an axis &amp;lt;math&amp;gt;(x, y, z)&amp;lt;/math&amp;gt; and an angle &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; with the following constructor : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// 90 deg rotation around z-axis&lt;br /&gt;
Vector3D axis = new Vector3D(0, 0, 1);&lt;br /&gt;
double angle = FastMath.PI / 2.;&lt;br /&gt;
Rotation r = new Rotation(axis, angle);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If necessary, the quaternion is normalized.&lt;br /&gt;
&lt;br /&gt;
The axis and the angle can be retrieved using &#039;&#039;&#039;&#039;&#039;getAxis()&#039;&#039;&#039;&#039;&#039; and &#039;&#039;&#039;&#039;&#039;getAngle()&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Matrix representation ====&lt;br /&gt;
The rotation can be built from a rotation matrix with the following constructor : &lt;br /&gt;
*&#039;&#039;&#039;&#039;&#039;Rotation(double[][] m, double threshold)&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The rotation matrix can be retrieved using &#039;&#039;&#039;&#039;&#039;getMatrix()&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Euler Angles ====&lt;br /&gt;
&lt;br /&gt;
===== The RotationOrder class =====&lt;br /&gt;
&lt;br /&gt;
The RotationOrder class contains static attributes, themselves being RotationOrder objects, describing every vector sequence that can be used to create a Rotation using Euler or Cardan angles.&lt;br /&gt;
&lt;br /&gt;
===== Using Euler angles in rotations =====&lt;br /&gt;
&lt;br /&gt;
A Rotation object can so be created using three angles and a RotationOrder describing the associated sequence of basis vectors.&lt;br /&gt;
The user can also get the Cardan or Euler angles by giving a sequence, using the getAngles(RotationOrder) method.&lt;br /&gt;
In some cases, there are singularities that make a rotation impossible to describe with a giver rotation order.&lt;br /&gt;
&lt;br /&gt;
Code example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Rotation rotation = new Rotation(RotationOrder.YZX, 0.12, 0.54, 0.45);&lt;br /&gt;
double[] angles = rotation.getAngles(RotationOrder.ZXY);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Others representations ====&lt;br /&gt;
See [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Rotation.html Rotation javadoc].&lt;br /&gt;
&lt;br /&gt;
=== Using Rotations ===&lt;br /&gt;
The Rotation is part of the package fr.cnes.sirius.patrius.math&lt;br /&gt;
.geometry.euclidean.threed.&lt;br /&gt;
&lt;br /&gt;
The Rotation is represented by a rotation quaternion : it is a unit quaternion (a quaternion of norm one).&amp;lt;br&amp;gt;&lt;br /&gt;
The [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Rotation.html Rotation class] represents an algebraic rotation (i.e. a mathematical rotation). &lt;br /&gt;
&lt;br /&gt;
==== Rotate a vector ====&lt;br /&gt;
&lt;br /&gt;
A rotation is an operator which basically rotates three dimensional [{{JavaDoc4.18}}//fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Vector3D.html vectors] into other three dimensional [{{JavaDoc4.18}}//fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Vector3D.html vectors] using &#039;&#039;&#039;&#039;&#039;applyTo()&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// vector A&lt;br /&gt;
Vector3D a = new Vector3D(1, 0, 0);&lt;br /&gt;
// build rotation r1&lt;br /&gt;
Vector3D u1 = new Vector3D(0, 0, 1);&lt;br /&gt;
double theta1 = FastMath.PI / 2. ;&lt;br /&gt;
Rotation r1 = new Rotation(u1, theta1);&lt;br /&gt;
// vector B, image of A by r1&lt;br /&gt;
Vector3D b = r1.applyTo(a);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Compose rotations ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Since a rotation is basically a vectorial operator, several rotations can be composed together and the composite operation r = r2 o r1 is also a rotation. r1 is applied before r2 and the operator &#039;&#039;&#039;&#039;&#039;applyTo()&#039;&#039;&#039;&#039;&#039; is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// build rotation r1&lt;br /&gt;
Vector3D u1 = new Vector3D(0, 0, 1);&lt;br /&gt;
double theta1 = FastMath.PI / 2. ;&lt;br /&gt;
Rotation r1 = new Rotation(u1, theta1);&lt;br /&gt;
// build rotation r2&lt;br /&gt;
Vector3D u2 = new Vector3D(1, 0, 0);&lt;br /&gt;
double theta2 = FastMath.PI / 2. ;&lt;br /&gt;
Rotation r2 = new Rotation(u2, theta2);&lt;br /&gt;
// build r2 o r1&lt;br /&gt;
Rotation r2_o_r1 = r2.applyTo(r1);&lt;br /&gt;
// vector D, image of A by r2 o r1&lt;br /&gt;
Vector3D d = r2_o_r1.applyTo(a);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Change the basis of a vector ====&lt;br /&gt;
&lt;br /&gt;
The rotation could be used to change the basis of a vector using &#039;&#039;&#039;&#039;&#039;applyInverseTo()&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Define frame R2 by building the rotation r12 in frame R1&lt;br /&gt;
Vector3D u12_R1 = new Vector3D(1, 1, 1);&lt;br /&gt;
double theta12 = FastMath.PI* 3. / 2.;&lt;br /&gt;
Rotation r12_R1 = new Rotation(u12_R1, theta12);&lt;br /&gt;
// vector A, expressed in R1&lt;br /&gt;
Vector3D a_R1 = new Vector3D(0.5, 0.5, 0);&lt;br /&gt;
// vector A, expressed in R2&lt;br /&gt;
Vector3D a_R2 = r12_R1.applyInverseTo(a_R1);&lt;br /&gt;
        &lt;br /&gt;
// Build rotation r, in R1 frame&lt;br /&gt;
Vector3D u_R1 = new Vector3D(0, 0, 1);&lt;br /&gt;
double theta = FastMath.PI;&lt;br /&gt;
Rotation r_R1 = new Rotation(u_R1, theta);&lt;br /&gt;
// Vector B, image of A by the rotation r, expressed in R1&lt;br /&gt;
Vector3D b_R1 = r_R1.applyTo(a_R1);&lt;br /&gt;
// Vector B, changed of basis, expressed in R2&lt;br /&gt;
Vector3D b_R2 = r12_R1.applyInverseTo(b_R1);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Change the basis of a rotation ====&lt;br /&gt;
&lt;br /&gt;
Let be r a rotation built from the coordinates of its rotation axis. This vector is expressed in a frame &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt; ; the rotation is supported only in this frame.&lt;br /&gt;
Let be &amp;lt;math&amp;gt;r_12&amp;lt;/math&amp;gt; the rotation from &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;R_2&amp;lt;/math&amp;gt;, i.e. the image of the axis &amp;lt;math&amp;gt;x_1&amp;lt;/math&amp;gt; expressed in &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt; using the rotation &amp;lt;math&amp;gt;r_12&amp;lt;/math&amp;gt; is the axis  &amp;lt;math&amp;gt;x_2&amp;lt;/math&amp;gt; expressed in &amp;lt;math&amp;gt;R_2&amp;lt;/math&amp;gt; : &amp;lt;math&amp;gt;r_12(x_1) = x_2&amp;lt;/math&amp;gt; with &amp;lt;math&amp;gt;x_1&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;x_2&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;r_12&amp;lt;/math&amp;gt; expressed in &amp;lt;math&amp;gt;R_1&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The rotation r, changed of basis to be expressed in &amp;lt;math&amp;gt;R_2&amp;lt;/math&amp;gt; is obtained by&#039;&#039;&#039;&#039;&#039;&amp;lt;math&amp;gt;r_12&amp;lt;/math&amp;gt;.applyTo(r.revert())&#039;&#039;&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Define frame R2 by building the rotation r12 in frame R1&lt;br /&gt;
Vector3D u12_R1 = new Vector3D(1, 1, 1);&lt;br /&gt;
double theta12 = FastMath.PI* 3. / 2.;&lt;br /&gt;
Rotation r12_R1 = new Rotation(u12_R1, theta12);&lt;br /&gt;
// Build rotation r, in R1 frame&lt;br /&gt;
Vector3D u_R1 = new Vector3D(0, 0, 1);&lt;br /&gt;
double theta = FastMath.PI;&lt;br /&gt;
Rotation r_R1 = new Rotation(u_R1, theta);&lt;br /&gt;
// Change the basis of r&lt;br /&gt;
Rotation r_R2 = r12_R1.applyTo(r_R1.revert());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using Quaternions ===&lt;br /&gt;
The &amp;lt;code&amp;gt;Quaternion&amp;lt;/code&amp;gt; class provides all elementary operations on quaternions: sum, product, inverse, conjugate, norm, dot product, etc.&lt;br /&gt;
Below are some examples of use:&lt;br /&gt;
&lt;br /&gt;
* Computing the product of two quaternions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Quaternion qA = new Quaternion(qA0,qA1,qA2,qA3);&lt;br /&gt;
Quaternion qB = new Quaternion(qB0,qB1,qB2,qB3);&lt;br /&gt;
Quaternion qProduct = Quaternion.multiply(qA,qB);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Getting the inverse of a quaternion :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Quaternion q = new Quaternion(0,5.1,4,8);&lt;br /&gt;
Quaternion qInverse = q.getInverse();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Using Rotations interpolation ===&lt;br /&gt;
&lt;br /&gt;
===== LERP Use case =====&lt;br /&gt;
&lt;br /&gt;
Here is an exemple on how one can compute LERP in Java language using PATRIUS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final Vector3D axis = new Vector3D(1,1,1);&lt;br /&gt;
final Rotation r1 = new Rotation(axis,FastMath.PI/6.);&lt;br /&gt;
final Rotation r2 = new Rotation(axis,FastMath.PI/3.);&lt;br /&gt;
&lt;br /&gt;
final Rotation r = Rotation.lerp(r1, r2, 0.5);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then one can retrieve corresponding rotation angle and axis:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final double rangle = r.getAngle();&lt;br /&gt;
final Vector3D raxis = r.getAxis();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Same example given in Scilab using Celestlab macros library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scilab&amp;quot;&amp;gt;&lt;br /&gt;
alpha1 = CL_deg2rad(30.);&lt;br /&gt;
q1 = CL_rot_axAng2quat([1;1;1],alpha1);&lt;br /&gt;
alpha2 = CL_deg2rad(60.);&lt;br /&gt;
q2 = CL_rot_axAng2quat([1;1;1],alpha2);&lt;br /&gt;
q = q1 + 0.5* (q2 - q1);&lt;br /&gt;
q = (1/norm(q))* q&lt;br /&gt;
[axis, angle] = CL_rot_quat2axAng(q)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== SLERP Use example ====&lt;br /&gt;
&lt;br /&gt;
Here is an exemple on how one can compute LERP in Java language using PATRIUS:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final Vector3D axis = new Vector3D(1,1,1);&lt;br /&gt;
final Rotation r1 = new Rotation(axis,FastMath.PI/6.);&lt;br /&gt;
final Rotation r2 = new Rotation(axis,FastMath.PI/3.);&lt;br /&gt;
&lt;br /&gt;
final Rotation r = Rotation.slerp(r1, r2, 0.5);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then one can retrieve corresponding rotation angle and axis:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final double rangle = r.getAngle();&lt;br /&gt;
final Vector3D raxis = r.getAxis();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Same example given in Scilab using Celestlab macros library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;scilab&amp;quot;&amp;gt;&lt;br /&gt;
alpha1 = CL_deg2rad(30.);&lt;br /&gt;
q1 = CL_rot_axAng2quat([1;1;1],alpha1);&lt;br /&gt;
alpha2 = CL_deg2rad(60.);&lt;br /&gt;
q2 = CL_rot_axAng2quat([1;1;1],alpha2);&lt;br /&gt;
q = CL_rot_quatSlerp(q1,q2,.5);&lt;br /&gt;
&lt;br /&gt;
[axis, angle] = CL_rot_quat2axAng(q)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
The relevant classes are :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Quaternion&#039;&#039;&#039;&lt;br /&gt;
|This class implements quaternions.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/complex/Quaternion.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Rotation&#039;&#039;&#039;&lt;br /&gt;
|This class implements rotations in a three-dimensional space.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Rotation.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RotationOrder&#039;&#039;&#039;&lt;br /&gt;
|This class is a utility representing a rotation order specification for Cardan or Euler angles specification.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/RotationOrder.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Root-Finding_Algorithms&amp;diff=4140</id>
		<title>User Manual 4.18 Root-Finding Algorithms</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Root-Finding_Algorithms&amp;diff=4140"/>
		<updated>2026-06-10T08:54:11Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === This section is about the root-finding algorithms for univariate real functions provided by the library. First we explain how to use the root-finding algorithms. Then a focus is made on the following root finding methods: Brent, Newton, Bisection and Müller.  === Javadoc === All solvers are in the following package : [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/solver/package-summary.html fr.cnes.sirius.patriu... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section is about the root-finding algorithms for univariate real functions provided by the library.&lt;br /&gt;
First we explain how to use the root-finding algorithms.&lt;br /&gt;
Then a focus is made on the following root finding methods: Brent, Newton, Bisection and Müller.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
All solvers are in the following package :&lt;br /&gt;
[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/solver/package-summary.html fr.cnes.sirius.patrius.math.analysis.solver]&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.analysis.solvers&amp;lt;/code&amp;gt; contains all the solvers described here.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
&lt;br /&gt;
=== About root finding ===&lt;br /&gt;
This library provides root-finding algorithms for real univariate functions.&lt;br /&gt;
The function for which a root is searched has to be provided as a [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/UnivariateFunction.html UnivariateFunction].&lt;br /&gt;
The root-finding algorithm is implemented through the [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/solver/UnivariateSolver.html UnivariateSolver] interface.&lt;br /&gt;
&lt;br /&gt;
A very generic example would be :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        UnivariateFunction f = &amp;lt;some function&amp;gt;;&lt;br /&gt;
        UnivariateSolver solver = &amp;lt;some solver&amp;gt;;&lt;br /&gt;
        int numberOfEvals = 100;    &lt;br /&gt;
        double startInterval = 5.;&lt;br /&gt;
        double endInterval = 10.;&lt;br /&gt;
&lt;br /&gt;
        double root = solver.solve(numberOfEvals , f, startInterval , endInterval);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means the solver with look for a root value of f in the interval [5. , 10.], and will have to do so in no more than 100 evaluation steps.&lt;br /&gt;
&lt;br /&gt;
==== Test functions ====&lt;br /&gt;
&lt;br /&gt;
We will demonstrate the use of root-finding algorithms with two test input functions : a periodic function and a linear function. These functions are defined as follows :&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;sinus function&#039;&#039;&#039;&#039;&#039; : SinFunction &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class SinFunction implements DifferentiableUnivariateFunction {&lt;br /&gt;
&lt;br /&gt;
    public double value(double x) {&lt;br /&gt;
        return FastMath.sin(x);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public UnivariateFunction derivative() {&lt;br /&gt;
        return new UnivariateFunction() {&lt;br /&gt;
            public double value(double x) {&lt;br /&gt;
                return FastMath.cos(x);&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;linear function&#039;&#039;&#039;&#039;&#039; : XMinus5Function &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
public class XMinus5Function implements DifferentiableUnivariateFunction {&lt;br /&gt;
&lt;br /&gt;
    public double value(double x) {&lt;br /&gt;
        return x- 5;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    public UnivariateFunction derivative() {&lt;br /&gt;
        return new UnivariateFunction() {&lt;br /&gt;
            public double value(double x) {&lt;br /&gt;
                return 1.0;&lt;br /&gt;
            }&lt;br /&gt;
        };&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Available solvers ====&lt;br /&gt;
&lt;br /&gt;
The library provides around ten solvers, but the following have been more thoroughly tested :&lt;br /&gt;
* BrentSolver&lt;br /&gt;
* NewtonSolver&lt;br /&gt;
* BisectionSolver&lt;br /&gt;
* MullerSolver&lt;br /&gt;
* LaguerreSolver&lt;br /&gt;
* PolynomialRootsFinder&lt;br /&gt;
&lt;br /&gt;
=== Brent method ===&lt;br /&gt;
The&#039;&#039;&#039;&#039;&#039;Brent&#039;s method&#039;&#039;&#039;&#039;&#039; is a root-finding algorithm combining the bisection method, the secant method and inverse quadratic interpolation. It has the reliability of bisection but it can be as quick as some of the less reliable methods. The idea is to use the secant method or inverse quadratic interpolation if possible, because they converge faster, but to fall back to the more robust bisection method if necessary.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        UnivariateFunction f = new SinFunction ();&lt;br /&gt;
        double r;&lt;br /&gt;
        UnivariateSolver solver = new BrentSolver();&lt;br /&gt;
&lt;br /&gt;
        r = solver.solve(100, f, 3, 4);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = PI&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        UnivariateFunction f = new XMinus5Function ();&lt;br /&gt;
        double r;&lt;br /&gt;
        UnivariateSolver solver = new BrentSolver();&lt;br /&gt;
&lt;br /&gt;
        r = solver.solve(100, f, 1, 2);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : NoBracketingException exception&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;&amp;lt;u&amp;gt;behavior deteriorated in case of several roots in the interval&amp;lt;/u&amp;gt;&#039;&#039;&#039;&#039;&#039;&amp;lt;u&amp;gt; :&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        UnivariateFunction f = new SinFunction ();&lt;br /&gt;
        double r;&lt;br /&gt;
        UnivariateSolver solver = new BrentSolver();&lt;br /&gt;
&lt;br /&gt;
        r = solver.solve(100, f, 1, 20);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = PI&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        UnivariateFunction f = new SinFunction ();&lt;br /&gt;
        double r;&lt;br /&gt;
        UnivariateSolver solver = new BrentSolver();&lt;br /&gt;
&lt;br /&gt;
        r = solver.solve(100, f, 2, 20);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = 3 PI&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        UnivariateFunction f = new SinFunction ();&lt;br /&gt;
        double r;&lt;br /&gt;
        UnivariateSolver solver = new BrentSolver();&lt;br /&gt;
&lt;br /&gt;
        r = solver.solve(100, f, 7, 20);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : NoBracketingException exception&lt;br /&gt;
&lt;br /&gt;
=== Newton method ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;Newton&#039;s method&#039;&#039;&#039;&#039;&#039; (also known as the Newton–Raphson method) is a method for finding successively better approximations to the roots of a real-valued function. The idea of the method is as follows: one starts with an initial guess which is reasonably close to the true root, then the function is approximated by its tangent line, and one computes the x-intercept of this tangent line. This x-intercept will typically be a better approximation to the function&#039;s root than the original guess, and the method can be iterated.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT : the Newton solver only works for differentiable functions, this is reflected in the interface and class inheritances.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        DifferentiableUnivariateFunction f = new XMinus5Function ();&lt;br /&gt;
        double r;&lt;br /&gt;
        DifferentiableUnivariateSolver solver = new NewtonSolver();&lt;br /&gt;
&lt;br /&gt;
        r = solver.solve(100, f, 1, 6);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = 5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;&amp;lt;u&amp;gt;aberrant behavior&amp;lt;/u&amp;gt;&#039;&#039;&#039;&#039;&#039;&amp;lt;u&amp;gt; :&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        DifferentiableUnivariateFunction f = new SinFunction();&lt;br /&gt;
        double r;&lt;br /&gt;
        DifferentiableUnivariateSolver solver = new NewtonSolver();&lt;br /&gt;
&lt;br /&gt;
        r = solver.solve(100, f, 1, 2);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r =- 4 PI&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        DifferentiableUnivariateFunction f = new SinFunction();&lt;br /&gt;
        double r;&lt;br /&gt;
        DifferentiableUnivariateSolver solver = new NewtonSolver();&lt;br /&gt;
&lt;br /&gt;
        r = solver.solve(100, f, 1, 3);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = PI&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        DifferentiableUnivariateFunction f = new XMinus5Function ();&lt;br /&gt;
        double r;&lt;br /&gt;
        DifferentiableUnivariateSolver solver = new NewtonSolver();&lt;br /&gt;
&lt;br /&gt;
        r = solver.solve(100, f, 5.1, 20);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = 5&lt;br /&gt;
&lt;br /&gt;
=== Bisection method ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;bisection method&#039;&#039;&#039;&#039;&#039; is a root-finding method which repeatedly bisects an interval and then selects a subinterval in which a root must lie for further processing. It is a very simple and robust method, but it is also relatively slow.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        UnivariateFunction f = new XMinus5Function ();&lt;br /&gt;
        double r;&lt;br /&gt;
        UnivariateSolver solver = new BisectionSolver();&lt;br /&gt;
&lt;br /&gt;
        r = solver.solve(100, f, 3, 4);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = PI&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;&amp;lt;u&amp;gt;behavior deteriorated&amp;lt;/u&amp;gt;&#039;&#039;&#039;&#039;&#039;&amp;lt;u&amp;gt; :&amp;lt;/u&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        UnivariateFunction f = new XMinus5Function ();&lt;br /&gt;
        double r;&lt;br /&gt;
        UnivariateSolver solver = new BisectionSolver();&lt;br /&gt;
&lt;br /&gt;
        r = solver.solve(100, f, 5.1, 20);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = 20 (the upper bound of the interval)&lt;br /&gt;
&lt;br /&gt;
=== Müller method ===&lt;br /&gt;
The&#039;&#039;&#039;&#039;&#039;Müller&#039;s method&#039;&#039;&#039;&#039;&#039; is based on the secant method, which constructs at every iteration a line through two points on the graph of f. Instead, Müller&#039;s method uses three points, constructs the parabola through these three points, and takes the intersection of the x-axis with the parabola to be the next approximation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        UnivariateFunction f = new XMinus5Function ();&lt;br /&gt;
        double r;&lt;br /&gt;
        UnivariateSolver solver = new MullerSolver();&lt;br /&gt;
&lt;br /&gt;
        r = solver.solve(100, f, 1, 6);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = 5&lt;br /&gt;
&lt;br /&gt;
=== Laguerre method ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;Laguerre method&#039;&#039;&#039;&#039;&#039; is based on root finding of real coefficient polynomials. For reference, see “A First Course in Numerical Analysis, ISBN 048641454X, chapter 8.” &lt;br /&gt;
In short, laguerre&#039;s method is global solver in the sense that it can start with any initial approximation and be able to solve all roots from that point. The algorithm requires a bracketing condition. &lt;br /&gt;
When creating an instance of this solver, the relative accuracy, absolute accuracy and function value accuracy needs to be provided. &lt;br /&gt;
With this instance, it is then possible to call the different “solveComplex” or “solveAllComplex” methods. The difference being that “solveComplex” methods find one complex root for the polynomial with the given coefficients, starting from the given initial value, while solveAllComplex methods return an array with all the complex roots of the polynomial. &lt;br /&gt;
The polynomial is to be provided to the methods as a list of coefficients, in descending degree order. So, if for example we want to find the roots for 3x^2 – 2x + 4 = 0, the coefficients array should be [3, -2, 4]. &lt;br /&gt;
It is also possible to configure the maximum number of iterations and the initial guess to start looking for solutions. Moreover, an array of initial guesses with their corresponding array of maximum iterations per guess can be given as well. If this is the case, the first initial point is checked. If no solution is found, the following initial points are checked. If after all the initial solution points the problem does not converge still, an error is raised. &lt;br /&gt;
Possible errors: &lt;br /&gt;
* NullArgumentException if the coefficients of the polynomial are null&lt;br /&gt;
* NoDataException if the coefficients array is empty&lt;br /&gt;
* TooManyEvaluationsException if after the max number of iterations, the problem does not converge. &lt;br /&gt;
An example of code can be found below. In this example we try to find the complex solutions of a certain polynomial. Its coefficients are expressed in the “coefs” array. First, we check that using 0.0 as initial guess, the problem does not converge after 100 iterations. Then, we try to solve the problem again giving “0.0” and “-1.0” as initial guesses. The code should return all the complex roots of the polynomial: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // Coefficients of the polynomial in descending degree order&lt;br /&gt;
        final double[] coefs = { -1277.3007688108385, -2784.4747201350438, -3484.5151185287687, -3025.129112243774, -1809.09448519026, -659.3527056579327, -192.0264504557372, -30.431131343092268, -4.143607944239528 };&lt;br /&gt;
        final LaguerreSolver laguerreSolver = new LaguerreSolver();&lt;br /&gt;
        &lt;br /&gt;
        // Check that with one initial point, no solution is obtained.&lt;br /&gt;
        try {&lt;br /&gt;
                final Complex[] rootsFail = laguerreSolver.solveAllComplex(coefs, 0.0, 100);&lt;br /&gt;
                // This part of the code should not be reached&lt;br /&gt;
        Assert.fail();&lt;br /&gt;
        } catch (TooManyEvaluationsException e) {&lt;br /&gt;
                // Check the message is the attended one.&lt;br /&gt;
                Assert.assertEquals(e.getMessage(), &amp;quot;illegal state: maximal count (100) exceeded: evaluations&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        // Reconfigure the solver with multiple initial guesses:&lt;br /&gt;
        final Complex[] roots =&lt;br /&gt;
        laguerreSolver.solveAllComplex(coefs, new double[] { 0.0, -1.0 }, new int[] { 100, 100 });&lt;br /&gt;
&lt;br /&gt;
        // Ref value of roots&lt;br /&gt;
        final Complex[] rootsRef = new Complex[] { new Complex(-1.0866082737090914, -0.5144910983744713),&lt;br /&gt;
        new Complex(-1.0866082737090914, 0.5144910983744713),&lt;br /&gt;
        new Complex(-0.19830816503367565, -1.1728862134932596),&lt;br /&gt;
        new Complex(-0.19830816503367568, 1.1728862134932596), new Complex(-1.3187864867933607, -3.034067652882213),&lt;br /&gt;
        new Complex(-1.3187864867933603, 3.034067652882214), new Complex(-1.0683543434675484, 3.553800385639665),&lt;br /&gt;
        new Complex(-1.068354343467548, -3.553800385639666) };&lt;br /&gt;
        &lt;br /&gt;
        // Verify value of roots&lt;br /&gt;
        for (int i = 0; i &amp;lt; roots.length; i++) {&lt;br /&gt;
                Assert.assertEquals(rootsRef[i].getReal(), roots[i].getReal(), Precision.DOUBLE_COMPARISON_EPSILON);&lt;br /&gt;
                Assert.assertEquals(rootsRef[i].getImaginary(), roots[i].getImaginary(), Precision.DOUBLE_COMPARISON_EPSILON);&lt;br /&gt;
        }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== PolynomialRootsFinder method ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;PolynomialRootsFinder method&#039;&#039;&#039;&#039;&#039; computes the roots of the polynomial p represented by an array of coefficients, starting with the coefficient of greater degree. A coefficient of 0 indicates that an intermediate power is not present in the equation. It can compute either just the real part of the roots, or the full complex solution.&lt;br /&gt;
&lt;br /&gt;
In this solver, the roots of the polynomial are calculated by computing the eigenvalues of the companion matrix A:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        A = diag(ones(n-1, 1), -1);&lt;br /&gt;
        A(1,:) = -p(2:n+1)./p(1);&lt;br /&gt;
        r = eig(A);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The results produced are the exact eigenvalues of a matrix within roundoff error of the companion matrix, A. However, this does not mean that they are the exact roots of a polynomial whose coefficients are within roundoff error of those in p.&lt;br /&gt;
The public method findRootsRealPolynomial() computes the real part of the roots of the polynomial, while findRootsComplexPolynomial() computes the full complex solution. To use either of these methods, it is only necessary to give as input the list of coefficients representing the polynomial (in decreasing degree order). So, if for example we want to find the roots for 3x^2 – 2x + 4 = 0, the coefficients array should be [3, -2, 4].&lt;br /&gt;
Possible errors: &lt;br /&gt;
* NullArgumentException if the coefficients of the polynomial are null&lt;br /&gt;
* NoDataException if the coefficients array is empty or the degree of the polynomial is lower than 1. &lt;br /&gt;
An example of code can be found below. In this example we try to find the complex solutions of a certain polynomial. Its coefficients are expressed in the “coefs” array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // Define coefficients&lt;br /&gt;
        final double[] coefficients = { 3, -2, 4 };&lt;br /&gt;
        &lt;br /&gt;
        // Compute roots&lt;br /&gt;
        double[] roots = PolynomialRootsFinder.findRootsRealPolynomial(coefficients);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
{{specialInclusion prefix=$theme_sub section=&amp;quot;GettingStarted&amp;quot;/}}&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
The library defines the following interfaces related to solvers:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UnivariateSolver&#039;&#039;&#039;&lt;br /&gt;
|Interface for a univariate solver&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/solver/UnivariateSolver.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UnivariateDifferentiableSolver&#039;&#039;&#039;&lt;br /&gt;
|Interface for a differentiable univariate real solver&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/solver/UnivariateDifferentiableSolver.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
This section is about the following classes related to solvers :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BrentSolver&#039;&#039;&#039;&lt;br /&gt;
|Brent solver implementation.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/solver/BrentSolver.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NewtonRaphsonSolver&#039;&#039;&#039;&lt;br /&gt;
|Newton-Raphson solver implementation.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/solver/NewtonRaphsonSolver.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BisectionSolver&#039;&#039;&#039;&lt;br /&gt;
|Bisection solver implementation.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/solver/BisectionSolver.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MullerSolver&#039;&#039;&#039;&lt;br /&gt;
|Müller solver implementation.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/solver/MullerSolver.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LaguerreSolver&#039;&#039;&#039;&lt;br /&gt;
|Laguerre solver implementation.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/solver/LaguerreSolver.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PolynomialRootsFinder&#039;&#039;&#039;&lt;br /&gt;
|PolynomialRootsFinder solver implementation.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/solver/PolynomialRootsFinder.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== [[File:lightBulb.png]] Tips &amp;amp; Tricks ==&lt;br /&gt;
Summing up : the solvers appear to behave in unexpected ways when the initial conditions are not &amp;quot;ideal&amp;quot;. Therefore It is advised, when using the solvers, to :&lt;br /&gt;
&lt;br /&gt;
* avoid non-ideal initial conditions,&lt;br /&gt;
* read the solvers&#039; javadoc carefully,&lt;br /&gt;
* always check if the solvers&#039; results are appropriate.&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Optimization&amp;diff=4139</id>
		<title>User Manual 4.18 Optimization</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Optimization&amp;diff=4139"/>
		<updated>2026-06-10T08:53:48Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__ == Introduction == === Scope === This section describes PATRIUS optimization features.   It will focus on the &amp;#039;&amp;#039;JOptimizer&amp;#039;&amp;#039; functionalities, which provides solvers for general convex optimization problems. In particular it provides the Following optimization solvers: * LP: Linear programming (linear criterion and constraints) * QP: Quadratic Programming (quadratic criterion and linear constraints) * QCQP: Qaudratically Constrained Quadratic Programming... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes PATRIUS optimization features.&lt;br /&gt;
 &lt;br /&gt;
It will focus on the &#039;&#039;JOptimizer&#039;&#039; functionalities, which provides solvers for general convex optimization problems. In particular it provides the Following optimization solvers:&lt;br /&gt;
* LP: Linear programming (linear criterion and constraints)&lt;br /&gt;
* QP: Quadratic Programming (quadratic criterion and linear constraints)&lt;br /&gt;
* QCQP: Qaudratically Constrained Quadratic Programming (quadratic criterion and constraints)&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The optimization classes are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.optim&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/package-summary.html Package fr.cnes.sirius.patrius.math.optim]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The optimization functionalities for joptimizer are organized in the following packages:&lt;br /&gt;
*&amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.optim.joptimizer.algebra&amp;lt;/code&amp;gt; compounds the classes with the algebra functionalities.&lt;br /&gt;
*&amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.optim.joptimizer.functions&amp;lt;/code&amp;gt; compounds the classes with the optimization functions.&lt;br /&gt;
*&amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.optim.joptimizer.optimizers&amp;lt;/code&amp;gt; compounds the classes with the optimizers.&lt;br /&gt;
*&amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.optim.joptimizer.solvers&amp;lt;/code&amp;gt; compounds the classes with the solvers.&lt;br /&gt;
*&amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.optim.joptimizer.util&amp;lt;/code&amp;gt; compounds the utility classes.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
Features descritpion for the joptimizer package.&lt;br /&gt;
=== Optimizers ===&lt;br /&gt;
The &amp;lt;code&amp;gt;JOptimizer&amp;lt;/code&amp;gt; class implements the convex optimizer (see &amp;quot;S.Boyd and L.Vandenberghe, Convex Optimization&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
The algorithm selection is implemented as a Chain of Responsibility pattern, and this class is the client of the chain.&lt;br /&gt;
&lt;br /&gt;
The different methods implemented to solve the convex optimization problem are:&lt;br /&gt;
* Interior point methods&lt;br /&gt;
**&amp;lt;code&amp;gt;PrimalDualMethod&amp;lt;/code&amp;gt; :  primal-dual interior-point method. &lt;br /&gt;
**&amp;lt;code&amp;gt;LPPrimalDualMethod&amp;lt;/code&amp;gt; : primal-dual interior-point method for linear problems. &lt;br /&gt;
**&amp;lt;code&amp;gt;BarrierMethod&amp;lt;/code&amp;gt;&lt;br /&gt;
*Quality constrained minimization &lt;br /&gt;
**&amp;lt;code&amp;gt;NewtonLEConstrainedFSP&amp;lt;/code&amp;gt; : linear equality constrained newton optimizer, with a feasible starting point.&lt;br /&gt;
**&amp;lt;code&amp;gt;NewtonLEConstrainedISP&amp;lt;/code&amp;gt; : linear equality constrained newton optimizer, with an infeasible starting point.&lt;br /&gt;
*Unconstrained minimization&lt;br /&gt;
**&amp;lt;code&amp;gt;NewtonUnconstrained&amp;lt;/code&amp;gt; : unconstrained newton optimizer.&lt;br /&gt;
 &lt;br /&gt;
==== Optimization problem ====&lt;br /&gt;
The &amp;lt;code&amp;gt;OptimizationRequest&amp;lt;/code&amp;gt; class has all the setting field&#039;s necessaires to define an optimization problem.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;LPOptimizationRequest&amp;lt;/code&amp;gt; is an extension of this class for linear optimization problems. &lt;br /&gt;
&lt;br /&gt;
The general form of a linear problem is (1):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
min(c) s.t.&lt;br /&gt;
A.x = b&lt;br /&gt;
lb &amp;lt;= x &amp;lt;= ub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;OptimizationResponse&amp;lt;/code&amp;gt; is the class with the getters and setters to set and get the response after the optimization.&lt;br /&gt;
The &amp;lt;code&amp;gt;LPOptimizationResponse&amp;lt;/code&amp;gt; is the extended class applied to linear problems.&lt;br /&gt;
&lt;br /&gt;
==== Standard converter ====&lt;br /&gt;
The &amp;lt;code&amp;gt;LPStandardConverter&amp;lt;/code&amp;gt; converts a general linear problem stated in the form (2):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
min(c) s.t. &lt;br /&gt;
G.x &amp;lt; h &lt;br /&gt;
A.x = b &lt;br /&gt;
lb &amp;lt;= x &amp;lt;= ub&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
to the (strictly)standard form:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
min(c) s.t. &lt;br /&gt;
A.x = b &lt;br /&gt;
x &amp;gt;= 0 &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
or to the (quasi)standard form (1).&lt;br /&gt;
&lt;br /&gt;
==== Presolver ====&lt;br /&gt;
The &amp;lt;code&amp;gt;LPPresolver&amp;lt;/code&amp;gt; implements a presolver for a linear problem in the form (1).&lt;br /&gt;
&lt;br /&gt;
It applies a set of techniques to the linear programming problem before a linear programming solver solves it. This set of techniques aims at reducing the size of the LP problem by eliminating redundant constraints and variables and identifying possible infeasibility and unboundedness of the problem.&lt;br /&gt;
&lt;br /&gt;
=== Solvers ===&lt;br /&gt;
The &amp;lt;code&amp;gt;AbstractKKTSolver&amp;lt;/code&amp;gt; implements a solver for the KKT system:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
H.v + [A]T.w = -g&lt;br /&gt;
A.v = -h&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where H is a square and symmetric matrix.&lt;br /&gt;
&lt;br /&gt;
The following classes are an extension of &amp;lt;code&amp;gt;AbstractKKTSolver&amp;lt;/code&amp;gt;:&lt;br /&gt;
*&amp;lt;code&amp;gt;AugmentedKKTSolver&amp;lt;/code&amp;gt; (for singular H)&lt;br /&gt;
*&amp;lt;code&amp;gt;BasicKKTSolver&amp;lt;/code&amp;gt;&lt;br /&gt;
*&amp;lt;code&amp;gt;UpperDiagonalHKKTSolver&amp;lt;/code&amp;gt; (for upper diagonal H)&lt;br /&gt;
&lt;br /&gt;
=== Functions ===&lt;br /&gt;
Different functions are implemented, all of them twice differentiable.&lt;br /&gt;
*Linear functions &lt;br /&gt;
The &amp;lt;code&amp;gt;LinearMultivariateRealFunction&amp;lt;/code&amp;gt; represents a function in the form of:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
f(x) = q.x + r&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
*Quadratic functions &lt;br /&gt;
The &amp;lt;code&amp;gt;QuadraticMultivariateRealFunction&amp;lt;/code&amp;gt; represents a function in the form of:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
f(x) := 1/2 x.P.x + q.x + r&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
where x, q ∈ R &amp;lt;sup&amp;gt;n&amp;lt;/sup&amp;gt;, P is a symmetric nXn matrix and r ∈ R.&lt;br /&gt;
&lt;br /&gt;
With the extended &amp;lt;code&amp;gt;PSDQuadraticMultivariateRealFunction&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PDQuadraticMultivariateRealFunction&amp;lt;/code&amp;gt; classes for P symmetric and positive semi-definite, and P symmetric and positive definite, respectively.&lt;br /&gt;
&lt;br /&gt;
*Barrier functions&lt;br /&gt;
The &amp;lt;code&amp;gt;LogarithmicBarrier&amp;lt;/code&amp;gt; is the default barrier function for the barrier method algorithm.&lt;br /&gt;
&lt;br /&gt;
If f&amp;lt;sub&amp;gt;i&amp;lt;/sub&amp;gt;(x) are the inequalities of the problem, then the function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Φ(x) = − ∑_i (log(−fi(x)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Algebra ===&lt;br /&gt;
==== Factorization ====&lt;br /&gt;
The &amp;lt;code&amp;gt;CholeskyFactorization&amp;lt;/code&amp;gt; implements the Cholesky L . L[T] factorization and inverse for symmetric and positive matrix:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Q = L.L[T]&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
with L lower-triangular.&lt;br /&gt;
&lt;br /&gt;
==== Rescaler ====&lt;br /&gt;
The &amp;lt;code&amp;gt;Matrix1NornRescaler&amp;lt;/code&amp;gt; calculates the matrix rescaling factors, so that the 1-norm of each row and each column of the scaled matrix asymptotically converges to one.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
=== Example 1 ===&lt;br /&gt;
Example of a linear problem optimized by the primal-dual interior-point method.&lt;br /&gt;
&lt;br /&gt;
The problem is:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
min(-100x + y) s.t.&lt;br /&gt;
x - y = 0&lt;br /&gt;
0 &amp;lt;= x &amp;lt;= 1&lt;br /&gt;
0 &amp;lt;= y &amp;lt;= 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First, the definition of the variables:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final double[] c = new double[] { -100, 1 }&lt;br /&gt;
final double[][] a = new double[][] { { 1, -1 } }&lt;br /&gt;
final double[] b = new double[] { 0 }&lt;br /&gt;
final double[] lb = new double[] { 0, 0 }&lt;br /&gt;
final double[] ub = new double[] { 1, 1 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Definition of the optimization problem by setting the variables:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final LPOptimizationRequest or = new LPOptimizationRequest()&lt;br /&gt;
or.setC(c)&lt;br /&gt;
or.setA(a)&lt;br /&gt;
or.setB(b)&lt;br /&gt;
or.setLb(lb)&lt;br /&gt;
or.setUb(ub)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Additional parameters (tolerance, check the solution accuracy, etc) can also be setted:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
or.setCheckKKTSolutionAccuracy(true)&lt;br /&gt;
or.setToleranceFeas(1.E-7)&lt;br /&gt;
or.setTolerance(1.E-7)&lt;br /&gt;
or.setDumpProblem(true)&lt;br /&gt;
or.setRescalingDisabled(true)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Definition of the optimizer and setting the optimization problem:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
LPPrimalDualMethod opt = new LPPrimalDualMethod()&lt;br /&gt;
opt.setLPOptimizationRequest(or)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Optimization and check that it has not failed:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final int returnCode = opt.optimize()&lt;br /&gt;
if (returnCode == OptimizationResponse.FAILED) {&lt;br /&gt;
    fail()&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Recuperate the response and the solution:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final LPOptimizationResponse response = opt.getLPOptimizationResponse()&lt;br /&gt;
final double[] sol = response.getSolution()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Validation:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final RealVector cVector = new ArrayRealVector(c)&lt;br /&gt;
final RealVector solVector = new ArrayRealVector(sol)&lt;br /&gt;
final double value = cVector.dotProduct(solVector)&lt;br /&gt;
assertEquals(2, sol.length)&lt;br /&gt;
assertEquals(1, sol[0], or.getTolerance())&lt;br /&gt;
assertEquals(1, sol[1], or.getTolerance())&lt;br /&gt;
assertEquals(-99, value, or.getTolerance())&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 2 ===&lt;br /&gt;
Example of the optimization of a linear objective function with quadratic constraints.&lt;br /&gt;
&lt;br /&gt;
The problem is:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
min(-e.x) s.t.&lt;br /&gt;
1/2 x.P.x &amp;lt; v&lt;br /&gt;
x + y + z = 1&lt;br /&gt;
x &amp;gt; 0&lt;br /&gt;
y &amp;gt; 0&lt;br /&gt;
z &amp;gt; 0&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Definition of the linear objective function:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final double[] e = { -0.018, -0.025, -0.01 }&lt;br /&gt;
final LinearMultivariateRealFunction objectiveFunction = new LinearMultivariateRealFunction(e, 0)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Definition of the quadratic and linear constraints:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final double[][] p = { { 1.68, 0.34, 0.38 }, { 0.34, 3.09, -1.59 }, { 0.38, -1.59, 1.54 } }&lt;br /&gt;
final double v = 0.3&lt;br /&gt;
final PDQuadraticMultivariateRealFunction qc0 = new PDQuadraticMultivariateRealFunction(p, null,-v)&lt;br /&gt;
final LinearMultivariateRealFunction lc0 = new LinearMultivariateRealFunction(new double[] { -1, 0, 0 }, 0)&lt;br /&gt;
final LinearMultivariateRealFunction lc1 = new LinearMultivariateRealFunction(new double[] { 0, -1, 0 }, 0)&lt;br /&gt;
final LinearMultivariateRealFunction lc2 = new LinearMultivariateRealFunction(new double[] { 0, 0, -1 }, 0)&lt;br /&gt;
final ConvexMultivariateRealFunction[] constraints = new ConvexMultivariateRealFunction[] { qc0, lc0, lc1, lc2 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Definition of the equality constraint:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final double[][] a = {{ 1, 1, 1 }}&lt;br /&gt;
final double[] b = { 1 }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Definition of the optimization problem and setting the parameters:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final OptimizationRequest or = new OptimizationRequest()&lt;br /&gt;
or.setF0(objectiveFunction)&lt;br /&gt;
or.setFi(constraints)&lt;br /&gt;
or.setA(a)&lt;br /&gt;
or.setB(b)&lt;br /&gt;
or.setToleranceFeas(1.e-6)  // additional parameter&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Definition of the optimizer and setting the optimization problem:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final JOptimizer opt = new JOptimizer()&lt;br /&gt;
opt.setLPOptimizationRequest(or)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Optimization and check that it has not failed:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final int returnCode = opt.optimize()&lt;br /&gt;
if (returnCode == OptimizationResponse.FAILED) {&lt;br /&gt;
    fail()&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Recuperate the response and the solution:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final LPOptimizationResponse response = opt.getLPOptimizationResponse()&lt;br /&gt;
final double[] sol = response.getSolution()&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Validation:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
assertEquals(1., sol[0] + sol[1] + sol[2], 1.e-6)&lt;br /&gt;
assertTrue(sol[0] &amp;gt; 0)&lt;br /&gt;
assertTrue(sol[1] &amp;gt; 0)&lt;br /&gt;
assertTrue(sol[2] &amp;gt; 0)&lt;br /&gt;
final RealVector xVector = MatrixUtils.createRealVector(sol)&lt;br /&gt;
final RealMatrix pMatrix = MatrixUtils.createRealMatrix(p)&lt;br /&gt;
final double xPx = xVector.dotProduct(pMatrix.operate(xVector))&lt;br /&gt;
assertTrue(0.5 * xPx &amp;lt; v)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
The interfaces related to the joptimizer are listed here : &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BarrierFunction&#039;&#039;&#039;&lt;br /&gt;
|Interface for the barrier function used by a given barrier optimization method.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/functions/BarrierFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ConvexMultivariateRealFunction&#039;&#039;&#039;&lt;br /&gt;
|Interface for convex multivariate real functions.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/functions/ConvexMultivariateRealFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MatrixRescaler&#039;&#039;&#039;&lt;br /&gt;
|An interface to classes that implement an algorithm to rescale matrices.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/algebra/MatrixRescaler.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;StrictlyConvexMultivariateRealFunction&#039;&#039;&#039;&lt;br /&gt;
|Interface for striclty convex multivariate real functions.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/functions/StrictlyConvexMultivariateRealFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TwiceDifferentiableMultivariateRealFunction&#039;&#039;&#039;&lt;br /&gt;
|Interface for twice-differentiable multivariate functions.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/functions/TwiceDifferentiableMultivariateRealFunction.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
The classes related to the joptimizer are listed here : &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AlgebraUtils&#039;&#039;&#039;&lt;br /&gt;
|Algebraic utility operations&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/algebra/AlgebraUtils.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CholeskyFactorization&#039;&#039;&#039;&lt;br /&gt;
|Implements the Cholesky L.L[T] factorization and inverse for symmetric and positive matrix.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/algebra/CholeskyFactorization.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Matrix1NornRescaler&#039;&#039;&#039;&lt;br /&gt;
|Calculates the matrix rescaling factors so that the 1-norm of each row and each column of the scaled matrix asymptotically converges to one.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/algebra/Matrix1NornRescaler.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FunctionsUtils&#039;&#039;&#039;&lt;br /&gt;
|Utility class for optimization function building.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/functions/FunctionsUtils.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LinearMultivariateRealFunction&#039;&#039;&#039;&lt;br /&gt;
|Represents a function f(x) = q.x + r.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/functions/LinearMultivariateRealFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LogarithmicBarrier&#039;&#039;&#039;&lt;br /&gt;
|Default barrier function for the barrier method algorithm.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/functions/LogarithmicBarrier.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PDQuadraticMultivariateRealFunction&#039;&#039;&#039;&lt;br /&gt;
|Extends the class QuadraticMultivariateRealFunction with P symmetric and positive definite.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/functions/PDQuadraticMultivariateRealFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PSDQuadraticMultivariateRealFunction&#039;&#039;&#039;&lt;br /&gt;
|Extends the class QuadraticMultivariateRealFunction with P symmetric and positive semi-definite.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/functions/PSDQuadraticMultivariateRealFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;QuadraticMultivariateRealFunction&#039;&#039;&#039;&lt;br /&gt;
|Represents a quadratic multivariate function in the form of f(x):= 1/2 x.P.x + q.x + r.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/functions/QuadraticMultivariateRealFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbstractLPOptimizationRequestHandler&#039;&#039;&#039;&lt;br /&gt;
|Abstract class for Linear Problem Optimization Request Handler.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/AbstractLPOptimizationRequestHandler.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BarrierMethod&#039;&#039;&#039;&lt;br /&gt;
|Implements the Barrier Method.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/BarrierMethod.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BasicPhaseIBM&#039;&#039;&#039;&lt;br /&gt;
|Implements the Basic Phase I Method as a Barried Method.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/BasicPhaseIBM.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BasicPhaseILPPDM&#039;&#039;&#039;&lt;br /&gt;
|Implements the Basic Phase I Method form LP problems as a Primal-Dual Method.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/BasicPhaseILPPDM.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BasicPhaseIPDM&#039;&#039;&#039;&lt;br /&gt;
|Implements the Basic Phase I Method as a Primal-Dual Method.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/BasicPhaseIPDM.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;JOptimizer&#039;&#039;&#039;&lt;br /&gt;
|Implements the convex optimizer.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/JOptimizer.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LPPresolver&#039;&#039;&#039;&lt;br /&gt;
|Presolver for a linear problem.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/LPPresolver.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LPPrimalDualMethod&#039;&#039;&#039;&lt;br /&gt;
|Implements the Primal-dual interior-point method for linear problems.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/LPPrimalDualMethod.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LPStandardConverter&#039;&#039;&#039;&lt;br /&gt;
|Converts a general LP problem into a strictly standard or quasi standard form.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/LPStandardConverter.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NewtonLEConstrainedFSP&#039;&#039;&#039;&lt;br /&gt;
|Linear equality constrained newton optimizer, with feasible starting point.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/NewtonLEConstrainedFSP.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NewtonLEConstrainedISP&#039;&#039;&#039;&lt;br /&gt;
|Linear equality constrained newton optimizer, with infeasible starting point.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/NewtonLEConstrainedISP.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NewtonUnconstrained&#039;&#039;&#039;&lt;br /&gt;
|Unconstrained newton optimizer.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/NewtonUnconstrained.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OptimizationRequest&#039;&#039;&#039;&lt;br /&gt;
|Implements an optimization problem.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/OptimizationRequest.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OptimizationRequestHandler&#039;&#039;&#039;&lt;br /&gt;
|Generic class for optimization process.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/OptimizationRequestHandler.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OptimizationResponse&#039;&#039;&#039;&lt;br /&gt;
|Optimization process output: stores the solution as well as an exit code.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/OptimizationResponse.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PrimalDualMethod&#039;&#039;&#039;&lt;br /&gt;
|Implements a primal-dual interior-point method.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/optimizers/PrimalDualMethod.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbstractKKTSolver&#039;&#039;&#039;&lt;br /&gt;
|Abstract class for solving KKT systems.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/solvers/AbstractKKTSolver.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AugmentedKKTSolver&#039;&#039;&#039;&lt;br /&gt;
|Extension of AbstractKKTSolver for singular matrix.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/solvers/AugmentedKKTSolver.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BasicKKTSolver&#039;&#039;&#039;&lt;br /&gt;
|Extension of AbstractKKTSolver for the basic solver.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/solvers/BasicKKTSolver.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UpperDiagonalHKKTSolver&#039;&#039;&#039;&lt;br /&gt;
|Extends the class AbstractKKTSolver for upper diagonal matrix.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/solvers/UpperDiagonalHKKTSolver.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ArrayUtils&#039;&#039;&#039;&lt;br /&gt;
|Class offering operations on arrays, primitive arrays (like int[]) and primitive wrapper arrays (like Integer[]).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/util/ArrayUtils.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MutableInt&#039;&#039;&#039;&lt;br /&gt;
|A mutable (int) wrapper.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/util/MutableInt.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Utils&#039;&#039;&#039;&lt;br /&gt;
|Utility class.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/optim/joptimizer/util/Utils.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Numerical_ordinary_differential_equations&amp;diff=4138</id>
		<title>User Manual 4.18 Numerical ordinary differential equations</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Numerical_ordinary_differential_equations&amp;diff=4138"/>
		<updated>2026-06-10T08:53:28Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__ == Introduction == === Scope === This library can compute solutions for ordinary differential equations, as numerical approximations. The problems are usually in the form of : Compute an estimate of y(t) from t=t0 to t=t1, knowing the derivative y&amp;#039;=f(t,y), and y(t0)=y0.  The library can also handle multiple discrete events detection based on the results of the ongoing estimation, which can be used to dynamically alter the conditions of the problem being... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This library can compute solutions for ordinary differential equations, as numerical approximations.&lt;br /&gt;
The problems are usually in the form of :&lt;br /&gt;
Compute an estimate of y(t) from t=t0 to t=t1, knowing the derivative y&#039;=f(t,y), and y(t0)=y0.&lt;br /&gt;
&lt;br /&gt;
The library can also handle multiple discrete events detection based on the results of the ongoing estimation, which can be used to dynamically alter the conditions of the problem being solved, or even stop the integration (for instance : when the function y reaches an expected value, the value of t at this point being the information needed, there is no need to go on).&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
==== Integrators ====&lt;br /&gt;
&lt;br /&gt;
The ODE integrators are provided in the following packages :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/package-summary.html Package fr.cnes.sirius.patrius.math.ode]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/nonstiff/package-summary.html Package fr.cnes.sirius.patrius.math.ode.nonstiff]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/sampling/package-summary.html Package fr.cnes.sirius.patrius.math.ode.sampling]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Event handling ====&lt;br /&gt;
&lt;br /&gt;
The events are managed in the following package :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/events/package-summary.html Package fr.cnes.sirius.patrius.math.ode.events]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
A general purpose explanation of this section can be found here :&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Numerical_ordinary_differential_equations http://en.wikipedia.org/wiki/Numerical_ordinary_differential_equations]&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
&lt;br /&gt;
Please note that not all implementations are present in the following diagram for the sake of clarity.&lt;br /&gt;
&lt;br /&gt;
Integrators :&lt;br /&gt;
&lt;br /&gt;
[[File:Integrators2.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
Events package :&lt;br /&gt;
&lt;br /&gt;
[[File:PATRIMOINESIRIUSSUMDiagEvents.png|center]]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Integrators ===&lt;br /&gt;
The provided integrators include :&lt;br /&gt;
* the Classical Runge Kutta integrator,&lt;br /&gt;
* the Dormand Prince 8(5, 3) integrator,&lt;br /&gt;
* the Gragg Bulirsch Stoer integrator,&lt;br /&gt;
* the 6th order Runge-Kutta integretor.&lt;br /&gt;
* the Stormer-Cowell integrator&lt;br /&gt;
&lt;br /&gt;
The ODE package documentation can be found [http://commons.apache.org/proper/commons-math/userguide/ode.html here ].&lt;br /&gt;
&lt;br /&gt;
=== Events ===&lt;br /&gt;
Event handling during an integrator run is a core functionality of the math package,&lt;br /&gt;
therefore this is already well-documented in the Javadoc (please see the relevant section).&lt;br /&gt;
This here is a short summary of how event handling works.&lt;br /&gt;
&lt;br /&gt;
==== How to monitor events ====&lt;br /&gt;
* &#039;&#039;&#039;create an EventHandler implementation&#039;&#039;&#039; &amp;lt;br&amp;gt; You need to create an EventHandler implementation for the event you want to trace.&amp;lt;br&amp;gt;The most important method here is the g() method :&amp;lt;br&amp;gt;&amp;lt;code&amp;gt;double g(double t, double[] y) throws EventException;&amp;lt;/code&amp;gt; &amp;lt;br&amp;gt;This method (which takes as input a solution of the integration problem at a given &amp;quot;time&amp;quot; t) should be designed so that &#039;&#039;&#039;when the event occurs, the sign of the method changes&#039;&#039;&#039;. It should also be continuous.&amp;lt;br&amp;gt;The other methods of the interface are : &lt;br /&gt;
** &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;int eventOccurred(double t, double[] y, boolean increasing, boolean forward) throws EventException&amp;lt;/syntaxhighlight&amp;gt; &amp;lt;br&amp;gt; This method is called when an event happens. It should return :&lt;br /&gt;
*** STOP if the integration computation should stop&lt;br /&gt;
*** RESET_STATE if the event handler wants to change the state vector before the integration resumes (the resetState method will be called)&lt;br /&gt;
*** RESET_DERIVATIVES if the state vector&#039;s derivatives need to be recomputed before the integration resumes&lt;br /&gt;
*** CONTINUE if the integration should continue as if nothing happened&lt;br /&gt;
** &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;void resetState(double t, double[] y) throws EventException&amp;lt;/syntaxhighlight&amp;gt; &amp;lt;br&amp;gt; This method is called when eventOccured has returned RESET_STATE. This method should modify the y array, which will change the way the integration performs.&lt;br /&gt;
* &#039;&#039;&#039;add the EventHandler to an appropriate integrator&#039;&#039;&#039; &amp;lt;br&amp;gt;Using an EventHandler on a given integration problem is simple : just add it to the integrator instance before computing the solution.&amp;lt;br&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;integrator.addEventHandler(eventHandler, maxCheckInterval, convergence, maxIterationCount);&amp;lt;/syntaxhighlight&amp;gt; &amp;lt;br&amp;gt;Aside from the EventHandler itself, the other parameters are :&amp;lt;br&amp;gt;&lt;br /&gt;
** maxCheckInterval : Maximal time interval between events handler checks.&lt;br /&gt;
** convergence : precision needed for the event &amp;quot;time&amp;quot; value.&lt;br /&gt;
** iterationCount : maximum number of iterations to find the event &amp;quot;time&amp;quot; value when an event has been identified. Reaching this number means there is a problem with finding the event quickly enough (so, this counter is a way to interrupt an event search that takes too long, since finding an event should be fast if the g() function is continuous).&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;run the integrator&#039;&#039;&#039;&lt;br /&gt;
Please see the relevant section.&lt;br /&gt;
&lt;br /&gt;
==== About the EventState class ====&lt;br /&gt;
The EventState class is a very important class for event detection (one EventState instance is needed for each EventHandler to work), but since the integrator instantiates EventStates when needed, a regular user never needs to interact directy with an EventState object. Therefore, describing the EventState class is out of the scope of this document; all relevant information can be found in the Javadoc if needed.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FirstOrderIntegrator&#039;&#039;&#039;&lt;br /&gt;
|This interface represents a first order integrator for differential equations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/FirstOrderIntegrator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ODEIntegrator&#039;&#039;&#039;&lt;br /&gt;
|This interface defines the common parts shared by integrators for first and second order differential equations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/ODEIntegrator.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EventHandler&#039;&#039;&#039;&lt;br /&gt;
|This interface represents a handler for discrete events triggered during ODE integration.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/events/EventHandler.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbstractIntegrator&#039;&#039;&#039;&lt;br /&gt;
|Base class managing common boilerplate for all integrators.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/AbstractIntegrator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AdaptiveStepsizeIntegrator&#039;&#039;&#039;&lt;br /&gt;
|This abstract class holds the common part of all adaptive stepsize integrators for Ordinary Differential Equations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/nonstiff/AdaptiveStepsizeIntegrator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ClassicalRungeKuttaIntegrator&#039;&#039;&#039;&lt;br /&gt;
|This class implements the classical fourth order Runge-Kutta integrator for Ordinary Differential Equations (it is the most often used Runge-Kutta method).&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/nonstiff/ClassicalRungeKuttaIntegrator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RungeKutta6Integrator&#039;&#039;&#039;&lt;br /&gt;
|This class implements the sixth order Runge-Kutta integrator for Ordinary Differential Equations (it is used as the default Stela Integrator). This integrator currently has an second order interpolator.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/nonstiff/RungeKutta6Integrator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DormandPrince54Integrator&#039;&#039;&#039;&lt;br /&gt;
|This class implements the 5(4) Dormand-Prince integrator for Ordinary Differential Equations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/nonstiff/DormandPrince54Integrator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DormandPrince853Integrator&#039;&#039;&#039;&lt;br /&gt;
|This class implements the 8(5,3) Dormand-Prince integrator for Ordinary Differential Equations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/nonstiff/DormandPrince853Integrator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GraggBulirschStoerIntegrator&#039;&#039;&#039;&lt;br /&gt;
|This class implements a Gragg-Bulirsch-Stoer integrator for Ordinary Differential Equations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/nonstiff/GraggBulirschStoerIntegrator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RungeKuttaIntegrator&#039;&#039;&#039;&lt;br /&gt;
|This class implements the common part of all fixed step Runge-Kutta integrators for Ordinary Differential Equations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/nonstiff/RungeKuttaIntegrator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CowellIntegrator&#039;&#039;&#039;&lt;br /&gt;
|This class implements the 2nd order Stormer-Cowell integrator for Ordinary Differential Equations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/nonstiff/cowell/CowellIntegrator.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EventState&#039;&#039;&#039;&lt;br /&gt;
|This class handles the state for one EventHandler during integration steps.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/ode/events/EventState.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Numerical_differentiation_and_integration&amp;diff=4137</id>
		<title>User Manual 4.18 Numerical differentiation and integration</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Numerical_differentiation_and_integration&amp;diff=4137"/>
		<updated>2026-06-10T08:53:06Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__ == Introduction == === Scope === This section détails numerical differentialtion and integration (not to be misunderstood with numerical integration of ODE). A focus is realised on: * differentiation methods of real univariate functions: Ridders and finite difference. * integration methods of real univariate functions : Trapezoidal and Simpson.  === Javadoc === The numerical differentiator objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patri... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section détails numerical differentialtion and integration (not to be misunderstood with numerical integration of ODE). A focus is realised on:&lt;br /&gt;
* differentiation methods of real univariate functions: Ridders and finite difference.&lt;br /&gt;
* integration methods of real univariate functions : Trapezoidal and Simpson.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The numerical differentiator objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.analysis.differentiation&amp;lt;/code&amp;gt;.&lt;br /&gt;
The numerical integrator objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.analysis.integration&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/differentiation/package-summary.html Package fr.cnes.sirius.patrius.math.analysis.differentiation]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/integration/package-summary.html Package fr.cnes.sirius.patrius.math.analysis.integration]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
Links to the implemented integration methods :&lt;br /&gt;
&lt;br /&gt;
http://mathworld.wolfram.com/TrapezoidalRule.html&lt;br /&gt;
&lt;br /&gt;
http://mathworld.wolfram.com/SimpsonsRule.html&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The numerical differentiation conception is described hereafter : &lt;br /&gt;
&lt;br /&gt;
[[File:differentiators.png|center]]&lt;br /&gt;
&lt;br /&gt;
Accuracy of integration method (all examples are based on sinus function):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Default setting&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Value&lt;br /&gt;
|-&lt;br /&gt;
|Maximum absolute error&lt;br /&gt;
|1.0e-15&lt;br /&gt;
|-&lt;br /&gt;
|Maximum relative error&lt;br /&gt;
|1.0e-6&lt;br /&gt;
|-&lt;br /&gt;
|Maximum number of iterations&lt;br /&gt;
|64&lt;br /&gt;
|-&lt;br /&gt;
|Minimum number of iterations&lt;br /&gt;
|3&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note : the accuracy of the results and the computing time are directly dependent on the value of maximum relative error.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
&lt;br /&gt;
=== Numerical differentiation ===&lt;br /&gt;
&lt;br /&gt;
==== Finite difference ====&lt;br /&gt;
Finite difference is the discrete analog of the derivative. The user can choose the number of points to use and the step size (the gap between each point).&lt;br /&gt;
&lt;br /&gt;
==== Ridders algorithm ====&lt;br /&gt;
The derivative of a function at a point x is computed using the Ridders method of polynomial extrapolation.&lt;br /&gt;
&lt;br /&gt;
=== Numerical Integration ===&lt;br /&gt;
=== Trapezoidal method ===&lt;br /&gt;
The trapezoidal rule works by approximating the region under the graph of the function as a trapezoid and calculating its area.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
UnivariateFunction f = new SinFunction();&lt;br /&gt;
UnivariateIntegrator integrator = new TrapezoidIntegrator();&lt;br /&gt;
double r = integrator.integrate(10000, f, 0, FastMath.PI);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = 1.9999996078171345 (exact result = 2)&lt;br /&gt;
&lt;br /&gt;
And :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
integrator = new TrapezoidIntegrator(1.e-12, 1.0e-15, 3, 64);&lt;br /&gt;
r = integrator.integrate(10000000, f, 0, FastMath.PI);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = 1.9999999999904077&lt;br /&gt;
&lt;br /&gt;
But :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;integrator = new TrapezoidIntegrator(1.e-13, 1.0e-15, 3, 64);&lt;br /&gt;
r = integrator.integrate(10000000, f, 0, FastMath.PI);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = no result (infinite time !)&lt;br /&gt;
&lt;br /&gt;
=== Simpson method ===&lt;br /&gt;
Simpson&#039;s rule is a Newton-Cotes formula for approximating the integral of a function using quadratic polynomials (i.e., parabolic arcs instead of the straight line segments used in the trapezoidal rule).&lt;br /&gt;
In general, this method has faster convergence than the trapezoidal rule for functions which are twice continuously differentiable, though not in all specific cases.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
UnivariateFunction f = new SinFunction();&lt;br /&gt;
UnivariateIntegrator integrator = new SimpsonIntegrator();&lt;br /&gt;
double r = integrator.integrate(10000, f, 0, FastMath.PI);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : r = 2.000000064530001 (exact result = 2)&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
{{specialInclusion prefix=$theme_sub section=&amp;quot;GettingStarted&amp;quot;/}}&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UnivariateFunctionDifferentiator&#039;&#039;&#039;&lt;br /&gt;
|This interface represents a generic numerical differentiator.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/differentiation/UnivariateFunctionDifferentiator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|UnivariateIntegrator&lt;br /&gt;
|Interface for univariate integration algorithms.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/integration/UnivariateIntegrator.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FiniteDifferencesDifferentiator&#039;&#039;&#039;&lt;br /&gt;
|Apply the finite difference method to differentiate a function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/differentiation/FiniteDifferencesDifferentiator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RiddersDifferentiator&#039;&#039;&#039;&lt;br /&gt;
|Apply the Ridders algorithm to differentiate a function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/differentiation/RiddersDifferentiator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|TrapezoidIntegrator&lt;br /&gt;
|The class implements the Trapezoidal rule&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/integration/TrapezoidIntegrator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|SimpsonIntegrator&lt;br /&gt;
|The class implements the Simpson rule&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/integration/SimpsonIntegrator.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Matrices&amp;diff=4136</id>
		<title>User Manual 4.18 Matrices</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Matrices&amp;diff=4136"/>
		<updated>2026-06-10T08:52:41Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === This section will focus on the following aspects :  * Matrix3D and Vector3D * Generic Matrices * UD Decomposition  === Javadoc === The relevant packages are documented here :  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=&amp;quot;col&amp;quot;| Javadoc |- | Patrius |[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/package-summary.html Package fr.cnes.sirius.patrius.math.linear] |- | Patrius |[{{JavaDoc4.18}}/fr/cnes/sirius/... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section will focus on the following aspects :&lt;br /&gt;
&lt;br /&gt;
* Matrix3D and Vector3D&lt;br /&gt;
* Generic Matrices&lt;br /&gt;
* UD Decomposition&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The relevant packages are documented here :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
| Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/package-summary.html Package fr.cnes.sirius.patrius.math.linear]&lt;br /&gt;
|-&lt;br /&gt;
| Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/package-summary.html Package fr.cnes.sirius.patrius.math.geometry.euclidean.threed]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Packages Overview ===&lt;br /&gt;
The matrices functionality can be found in the following packages :&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.geometry.euclidean.threed&amp;lt;/code&amp;gt; for Vector3D, Matrix3D&lt;br /&gt;
* &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.linear&amp;lt;/code&amp;gt; for RealMatrix, AbstractRealMatrix, Array2DRowRealMatrix, UDDecomposition, UDDecompositionImpl ...&lt;br /&gt;
&lt;br /&gt;
Please note that not all implementations are present in the following diagram for the sake of clarity.&lt;br /&gt;
&lt;br /&gt;
[[File:PATRIMOINESIRIUSDiagrammeMUmatricesgeneriques.png]]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== The Matrix3D class ===&lt;br /&gt;
The Matrix3D is a real matrix designed to be used in geometric calculations. The Matrix3D is compatible with the Vector3D type, unlike the matrices implemented in the package &amp;quot;linear&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The packages &amp;quot;linear&amp;quot; and &amp;quot;geometry&amp;quot; both contains classes to represent vectors and matrices, but without any compatibility (for example, the &amp;quot;multiply&amp;quot; methods availables in the generic real matrices only accept the objects from the &amp;quot;linear&amp;quot; package).&lt;br /&gt;
&lt;br /&gt;
To make possible the operations using both types of vectors and matrices, a constructor and a getter are added to the Vector3D and Matrix3D classes.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The constructor creates the object from a similar one (containing the same data) from the &amp;quot;linear&amp;quot; package.&lt;br /&gt;
&lt;br /&gt;
For vectors :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
ArrayRealVector realVector = new ArrayRealVector(data);&lt;br /&gt;
Vector3D vector3D = new Vector3D(realVector);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For matrices, the operation is described in the previous paragraph.&lt;br /&gt;
&lt;br /&gt;
This construction works only if the generic real vectors and matrices dimensions are right (3 for the vectors and 3x3 for the matrices).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The getters are : &amp;quot;getRealMatrix()&amp;quot; in the Matrix3D class and &amp;quot;getRealVector()&amp;quot; in the Vector3D class. They return the generic objects containing identical data.&lt;br /&gt;
&lt;br /&gt;
=== Generic real matrices ===&lt;br /&gt;
The library also provides generic representations of real matrices, of any size.&lt;br /&gt;
&lt;br /&gt;
The RealMatrix interface presents the following services :&lt;br /&gt;
&lt;br /&gt;
* usual operations (adding, multiplying)&lt;br /&gt;
* extraction of submatrices&lt;br /&gt;
* symmetry and antisymmetry tests&lt;br /&gt;
* orthogonality tests&lt;br /&gt;
* diagonality tests&lt;br /&gt;
* invertibility tests&lt;br /&gt;
&lt;br /&gt;
The Array2DRowRealMatrix is one available implementation for generic real matrices.&lt;br /&gt;
&lt;br /&gt;
=== Decompositions ===&lt;br /&gt;
&lt;br /&gt;
PATRIUS provides several ways for matrix decomposition. Interface for decomposition is &amp;lt;code&amp;gt;Decomposition&amp;lt;/code&amp;gt;.&lt;br /&gt;
A decomposition provides a way to:&lt;br /&gt;
* Inverse a matrix&lt;br /&gt;
* Separate a matrix into a product of specific matrices (orthogonal, upper triangular, etc.) depending on the solver type.&lt;br /&gt;
Standard decomposition in PATRIUS are:&lt;br /&gt;
* &amp;lt;code&amp;gt;QRDecomposition&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;LUDecomposition&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;CholeskyDecomposition&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;SingularValueDecomposition&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;UDDecompositionImpl&amp;lt;/code&amp;gt;&lt;br /&gt;
RealMatrix interface possesses a method to get its inverse. If not provided, by default a &amp;lt;code&amp;gt;LUDecomposition&amp;lt;/code&amp;gt;is used.&lt;br /&gt;
The QR decomposition method implements an optimisation option which is able to provide an improved process pour des matrices creuses (option &amp;quot;parallel&amp;quot; to be used for the related constructor).&lt;br /&gt;
&lt;br /&gt;
==== Exemple with UD decomposition ====&lt;br /&gt;
The library can compute the UD decomposition of a matrix.&lt;br /&gt;
&lt;br /&gt;
The UD-decomposition of the matrix A is a set of three matrices such that A = UxDxU^^t^^ with :&lt;br /&gt;
&lt;br /&gt;
* U is an upper triangular matrix,&lt;br /&gt;
* D is a diagonal matrix,&lt;br /&gt;
*  U^^t^^ is the transpose of U.&lt;br /&gt;
&lt;br /&gt;
=== Symmetric matrices ===&lt;br /&gt;
&lt;br /&gt;
Symmetric matrices are handled through the generic &amp;lt;code&amp;gt;SymmetricMatrix&amp;lt;/code&amp;gt; interface.&lt;br /&gt;
An implementation is provided: &amp;lt;code&amp;gt;ArrayRowSymmetricMatrix&amp;lt;/code&amp;gt;. This implementation optimally stores data in one single 1D-array.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Matrix3D and Vector3D ===&lt;br /&gt;
==== The Matrix3D class ====&lt;br /&gt;
&lt;br /&gt;
A Matrix3D instance be constructed from doubles :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double[][] data = { {1d,2d,3d}, {2d,5d,3d}, {1d,0d,8d} };&lt;br /&gt;
&lt;br /&gt;
Matrix3D matrix3d = new Matrix3D(data);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Or from a RealMatrix :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Array2DRowRealMatrix matrixCM = new Array2DRowRealMatrix(data);&lt;br /&gt;
&lt;br /&gt;
Matrix3D matrix3D = new Matrix3D(matrixCM);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the RealMatrix or data dimensions are not 3x3, a MathIllegalArgumentException is thrown.&lt;br /&gt;
&lt;br /&gt;
Some basic methods are available in it :&lt;br /&gt;
&lt;br /&gt;
* Matrix3D / Matrix3D addition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Matrix3D matrix3d_result = matrix3d_1.add(matrix3d_2);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Matrix3D / Matrix3D subtraction&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Matrix3D matrix3d_result = matrix3d_1.subtract(matrix3d_2);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Matrix3D / Matrix3D multiplication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Matrix3D matrix3d_result = matrix3d_1.multiply(matrix3d_2);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Matrix3D / Vector3D multiplication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Vector3D vector3d_result = matrix3d.multiply(vector3d);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Matrix3D / double multiplication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Matrix3D matrix3d_result = matrix3d.multiply(2.0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* transposition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Matrix3D transposed_matrix3d = matrix3d.transpose();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* minimum&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double min = matrix3d.getMin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* maximum&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double max = matrix3d.getMax();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* absolute values&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
RealMatrix abs_matrix3d = matrix3d.getAbs();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* transposition and Matrix3D / Vector3D multiplication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Vector3D vector3d_result = matrix3d.transposeAndMultiply(vector3d);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* test : orthogonal matrix ? Uses the same-named function in AbstractRealMatrix : same principle, same use.&lt;br /&gt;
&lt;br /&gt;
* getRealMatrix : returns an Array2dRowRealMatrix with the same data in it&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
RealMatrix realmatrix = matrix3d.getRealMatrix();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* toString : creates a string containing all the values.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; final Matrix3D matrix = new Matrix3D(testData);&amp;lt;/code&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
returns &amp;lt;code&amp;gt;&amp;quot;Matrix3D{{1.0,2.0,3.0},{2.0,5.0,3.0},{1.0,0.0,8.0}}&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Generic matrices ===&lt;br /&gt;
==== The AbstractRealMatrix class ====&lt;br /&gt;
&lt;br /&gt;
===== Symmetry and antisymmetry tests =====&lt;br /&gt;
&lt;br /&gt;
The RealMatrix interface and the AbstractRealMatrix abstract class contain the two methods isSymmetric and isAntisymmetric to test if a real matrix is symmetric or antisymmetric:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Array2DRowRealMatrix sym = new Array2DRowRealMatrix(symmetricData);&lt;br /&gt;
&lt;br /&gt;
boolean isSymmetric = sym.isSymmetric() ;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The returned boolean is TRUE if the matrix is symmetric. The equality test made on each value uses the MathUtils.equalsWithRelativeTolerance method, with an algorithm using a relative threshold  described in the “Doubles Values Comparisons” paragraph of the SUM.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
isAntisymmetric needs a threshold given by the user for the comparisons the zero of the diagonal values. This threshold can be taken as MathUtils.DOUBLES_COMPARISON_EPSILON for standard cases.&lt;br /&gt;
&lt;br /&gt;
But if the matrix contains values closer to zero than this epsilon (1.0e-14), the user shall define their own threshold.&lt;br /&gt;
&lt;br /&gt;
For the rest of the values tested (other than the diagonal), the same method as in isSymmetric is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Array2DRowRealMatrix antisym = new Array2DRowRealMatrix(antisymmetricData);&lt;br /&gt;
&lt;br /&gt;
boolean isAntisymmetric = antisym.isAntisymmetric(Precision.DOUBLE_COMPARISON_EPSILON) ;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The returned boolean is TRUE if the matrix is antisymmetric.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Orthogonal test =====&lt;br /&gt;
&lt;br /&gt;
In order to know if a real matrix is orthogonal, one can use the method isOrthogonal(), this method checks if the column vectors form an orthonormal set :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        double[][] orthogonalMatrix = {{ 8.0 / 9.0, 1.0 / 9.0,-4.0 / 9.0 },&lt;br /&gt;
                {-4.0 / 9.0, 4.0 / 9.0, -7.0 / 9.0 },&lt;br /&gt;
                { 1.0 / 9.0, 8.0 / 9.0, 4.0 / 9.0 }};&lt;br /&gt;
        RealMatrix matrix = new Array2DRowRealMatrix(orthogonalMatrix);&lt;br /&gt;
        matrix.isOrthogonal(Precision.EPSILON, Precision.EPSILON));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, because a matrix usually results from several operations which can introduce numerical errors, one has to give 2 thresholds under which the matrix is considered to be orthogonal. These thresholds concern the normality and the orthogonality of the column vectors of the matrix.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Diagonal test =====&lt;br /&gt;
&lt;br /&gt;
In order to know if a real matrix is diagonal, one can use the method isDiagonal() :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        double[][] diagonalMatrix = {{ 4.0, 0.0, 0.0, 0.0 },&lt;br /&gt;
                { 0.0,-1.0, 0.0, 0.0 },&lt;br /&gt;
                { 0.0, 0.0, 5.0, 0.0 },&lt;br /&gt;
                {0.0, 0.0, 0.0, 9.0 }};&lt;br /&gt;
        RealMatrix matrix = new Array2DRowRealMatrix(diagonalMatrix);&lt;br /&gt;
        matrix.isDiagonal(Precision.EPSILON);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, because a matrix usually results from several operations which can introduce numerical errors, one has to give a threshold under which the non diagonal elements are considered to be zero ie the matrix is considered to be diagonal.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Invertible test =====&lt;br /&gt;
&lt;br /&gt;
In order to know if a real matrix is invertible, one can use the method isInvertible(), this method checks if the n column vectors form a basis of Rn :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        double[][] nonSingularMatrix = {{ 4.0, 2.0,-1.5, 2.0 },&lt;br /&gt;
                { 6.0, 8.0, 2.1, 2.5 },&lt;br /&gt;
                { 2.0, 1.0,-0.75, 1.0 },&lt;br /&gt;
                {-1.0, 0.0, 0.0, -0.5 }};&lt;br /&gt;
        RealMatrix matrix = new Array2DRowRealMatrix(nonSingularMatrix);&lt;br /&gt;
        matrix.isInvertible(Precision.EPSILON);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Of course, because a matrix usually results from several operations which can introduce numerical errors, one has to give a threshold under which the column vectors are considered linearly dependant.&lt;br /&gt;
&lt;br /&gt;
=== UD decomposition ===&lt;br /&gt;
==== The UDDecompositionImpl class ====&lt;br /&gt;
&lt;br /&gt;
The UDDecompositionImpl class is the one performing the UD-decomposition of a matrix.&lt;br /&gt;
&lt;br /&gt;
If the RealMatrix A is not square, a NonSquareMatrixException is thrown.&lt;br /&gt;
If the RealMatrix A is not symmetric, a NonSymmetricMatrixException is thrown.&lt;br /&gt;
If the RealMatrix A is not positive definite, a NonPositiveDefiniteMatrixException is thrown.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two constructors are available :&lt;br /&gt;
&lt;br /&gt;
* default constructor :&lt;br /&gt;
&amp;lt;code&amp;gt;UDDecompositionImpl(matrix,relativeSymmetryThreshold,absolutePositivityThreshold)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;matrix&#039;&#039;&#039; = matrix to factorize,&lt;br /&gt;
** &#039;&#039;&#039;relativeSymmetryThreshold&#039;&#039;&#039; = threshold above which off-diagonal elements are considered too different and matrix not symmetric,&lt;br /&gt;
** &#039;&#039;&#039;absolutePositivityThreshold&#039;&#039;&#039; = threshold below which diagonal elements are considered null and matrix not positive definite&lt;br /&gt;
&lt;br /&gt;
* basic constructor :&lt;br /&gt;
&amp;lt;code&amp;gt;UDDecompositionImpl(matrix)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;matrix&#039;&#039;&#039; = matrix to factorize with relativeSymmetryThreshold = DEFAULT_RELATIVE_SYMMETRY_THRESHOLD (1.0e-15) and absolutePositivityThreshold = DEFAULT_ABSOLUTE_POSITIVITY_THRESHOLD (0.0)&lt;br /&gt;
&lt;br /&gt;
The following methods are available in it :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final UDDecomposition udut = new UDDecompositionImpl(matrix);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get the U matrix&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
RealMatrix Umatrix = udut.getU();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get the D matrix&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
RealMatrix Dmatrix = udut.getD();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get the U^^t^^ matrix&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
RealMatrix UTmatrix = udut.getUT();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get the determinant&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double d = udut.getDeterminant();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* get the solver based on the UD decomposition&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
DecompositionSolver s = udut.getSolver();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
The most relevant interfaces related to matrices are listed here :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Vector&amp;lt;S extends Space&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
|This interface represents a generic vector in a vectorial space or a point in an affine space.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/Vector.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RealMatrix&#039;&#039;&#039;&lt;br /&gt;
|Interface defining a real-valued matrix with basic algebraic operations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/RealMatrix.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SymmetricMatrix&#039;&#039;&#039; &lt;br /&gt;
| Interface for symmetric matrices.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/SymmetricMatrix.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SymmetricPositiveMatrix&#039;&#039;&#039; &lt;br /&gt;
| Interface for symmetric positive matrices.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/SymmetricPositiveMatrix.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Decomposition&#039;&#039;&#039; &lt;br /&gt;
| Interface for matrices decompositions.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/Decomposition.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DecompositionSolver&#039;&#039;&#039; &lt;br /&gt;
| Interface for matrices decompositions solvers. In particular thses solvers provides the inverse of a matrix.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/DecompositionSolver.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UDDecomposition&#039;&#039;&#039;&lt;br /&gt;
|An interface to classes that implement an algorithm to calculate the UD-decomposition of a real matrix.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/UDDecomposition.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
The most relevant classes related to matrices are listed here :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Vector3D&#039;&#039;&#039;&lt;br /&gt;
|This class implements vectors in a three-dimensional space.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Vector3D.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Matrix3D&#039;&#039;&#039;&lt;br /&gt;
|This is a real 3x3 matrix designed to be used in geometric calculations. It is compatible with the Vector3D type.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Matrix3D.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Array2DRowRealMatrix&#039;&#039;&#039;&lt;br /&gt;
|Implementation of RealMatrix using a double[][] array to store entries and LU decomposition to support linear system solution and inverse.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/Array2DRowRealMatrix.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ArrayRowSymmetricMatrix&#039;&#039;&#039; &lt;br /&gt;
| Implementation of a symmetric matrix, implementing AbstractRealMatrix using a double[] array to store entries : storage convention is symmetric conventional full storage.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/ArrayRowSymmetricMatrix.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DiagonalMatrix&#039;&#039;&#039; &lt;br /&gt;
| Implementation of a diagonal matrix.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/DiagonalMatrix.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;QRDecomposition&#039;&#039;&#039;&lt;br /&gt;
|Calculates the QR decomposition of a matrix.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/QRDecomposition.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LUDecomposition&#039;&#039;&#039;&lt;br /&gt;
|Calculates the LU decomposition of a matrix.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/LUDecomposition.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CholeskyDecomposition&#039;&#039;&#039;&lt;br /&gt;
|Calculates the Cholesky decomposition of a matrix.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/CholeskyDecomposition.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SingularValueDecomposition&#039;&#039;&#039;&lt;br /&gt;
|Calculates the SVD decomposition of a matrix.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/linear/SingularValueDecomposition.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Math_frameworks&amp;diff=4135</id>
		<title>User Manual 4.18 Math frameworks</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Math_frameworks&amp;diff=4135"/>
		<updated>2026-06-10T08:52:17Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__ == Introduction == === Scope === This section describes PATRIUS handling of low-level math frameworks. A low-level math framework provides simple math operations such as sin, cos, exp, etc. Before PATRIUS 4.2, the only existing framework is &amp;lt;code&amp;gt;FastMath&amp;lt;/code&amp;gt;. Since version 4.2, the notion of math framework has been generalized and the user can use various framework: * FastMath * Math * StrictMath * JAFAMA 2.3.1 FastMath * JAFAMA 2.3.1 StrictFastMath... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes PATRIUS handling of low-level math frameworks.&lt;br /&gt;
A low-level math framework provides simple math operations such as sin, cos, exp, etc. Before PATRIUS 4.2, the only existing framework is &amp;lt;code&amp;gt;FastMath&amp;lt;/code&amp;gt;.&lt;br /&gt;
Since version 4.2, the notion of math framework has been generalized and the user can use various framework:&lt;br /&gt;
* FastMath&lt;br /&gt;
* Math&lt;br /&gt;
* StrictMath&lt;br /&gt;
* JAFAMA 2.3.1 FastMath&lt;br /&gt;
* JAFAMA 2.3.1 StrictFastMath&lt;br /&gt;
* An implementation corresponding for each function to fastest implementations among all above libraries.&lt;br /&gt;
* Its own defined framework&lt;br /&gt;
&lt;br /&gt;
JAFAMA is a fast open-source Math library. To be usable in PATRIUS, a dependency to JAFAMA 2.3.1 has been added in PATRIUS pom.xml file.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The math framework classes are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.framework&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/framework/package-summary.html Package fr.cnes.sirius.patrius.math.framework]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
One of the framework available is JAFAMA. JAFAMA is an open-source library under Apache 2.0 licence.&lt;br /&gt;
More information can be found at https://github.com/jeffhain/jafama&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
&lt;br /&gt;
=== Features ===&lt;br /&gt;
&lt;br /&gt;
A low-level Math framework is a class implementing all the original &amp;lt;code&amp;gt;FastMath&amp;lt;/code&amp;gt; functions (sin, exp, min, atan, etc.).&lt;br /&gt;
All low-level Math framework should implement the &amp;lt;code&amp;gt;MathLibrary&amp;lt;/code&amp;gt; interface.&lt;br /&gt;
Currently there are three implementations of the MathLibrary interface:&lt;br /&gt;
* &amp;lt;code&amp;gt;FastMathWrapper&amp;lt;/code&amp;gt; which is a wrapper for FastMath static class.&lt;br /&gt;
* &amp;lt;code&amp;gt;MathWrapper&amp;lt;/code&amp;gt; which is a wrapper for Math static class.&lt;br /&gt;
* &amp;lt;code&amp;gt;StrictMathWrapper&amp;lt;/code&amp;gt; which is a wrapper for StrictMath static class.&lt;br /&gt;
* &amp;lt;code&amp;gt;JafamaFastMathWrapper&amp;lt;/code&amp;gt; which is a wrapper for JAFAMA FastMath static class.&lt;br /&gt;
* &amp;lt;code&amp;gt;JafamaStrictFastMathWrapper&amp;lt;/code&amp;gt; which is a wrapper for JAFAMA StrictFastMath static class.&lt;br /&gt;
* &amp;lt;code&amp;gt;FastestMathLibWrapper&amp;lt;/code&amp;gt; which is a wrapper for fastest math library among the listed above. Fastest functions are mainly Jafama FastMath functions except for simple functions (abs, ceil, floor, round, etc.) for which FastMath or StrictMath are faster.&lt;br /&gt;
The user can also define its own low-level Math framework by providing its own implementation of the &amp;lt;code&amp;gt;MathLibrary&amp;lt;/code&amp;gt; interface.&lt;br /&gt;
&lt;br /&gt;
Then in order to use the chosen low-level Math framework, the user must use the static class &amp;lt;code&amp;gt;MathLib&amp;lt;/code&amp;gt;:&lt;br /&gt;
* By first defining the Math framework to use with methods &amp;lt;code&amp;gt;MathLib.setMathLibrary()&amp;lt;/code&amp;gt; if different from FastMath.&lt;br /&gt;
* By then using the MathLib functions like the FastMath functions: &amp;lt;code&amp;gt;MathLib.sin(...)&amp;lt;/code&amp;gt;&lt;br /&gt;
Notes:&lt;br /&gt;
* by default, FastMath is set as the low-level Math library.&lt;br /&gt;
* inner PATRIUS functions call MathLib which by default call FastMath. Hence there is strictly no numerical differences between use of PATRIUS 4.2 or older versions of PATRIUS.&lt;br /&gt;
* MathLib has function sinAndCos which allows the computation of sine and cosine of a value in one single operation. If using Jafama, the computational cost is reduced by about 30%. There is no impact if using another framework.&lt;br /&gt;
&lt;br /&gt;
When the user defines a low-level math framework then all PATRIUS operations are performed using this framework.&lt;br /&gt;
&lt;br /&gt;
=== Performances of available Math framework ===&lt;br /&gt;
&lt;br /&gt;
==== Computation times ====&lt;br /&gt;
&lt;br /&gt;
Here are displayed computation time gains with using JAFAMA library (reference: FastMath).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Item&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Jafama FastMath&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Jafama StrictFastMath&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Numerical propagation&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;center&amp;gt;≈ -10%&amp;lt;/center&amp;gt;&lt;br /&gt;
| &amp;lt;center&amp;gt;≈ -10%&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Analytical propagation&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;center&amp;gt;≈ -30%&amp;lt;/center&amp;gt;&lt;br /&gt;
| &amp;lt;center&amp;gt;≈ -30%&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Attitude computation&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;center&amp;gt;≈ -10%&amp;lt;/center&amp;gt;&lt;br /&gt;
| &amp;lt;center&amp;gt;≈ -10%&amp;lt;/center&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: these are averaged orders of magnitude and may vary from one case to another.&lt;br /&gt;
&lt;br /&gt;
==== Accuracy ====&lt;br /&gt;
&lt;br /&gt;
As stated in JAFAMA website, relative accuracy of operations is 1E-15 (no regression would required a relative accuracy better than 1E-16). As a result, use of PATRIUS with JAFAMA will lead to slightly different results. This will not occur on all operations.&lt;br /&gt;
&lt;br /&gt;
Here are displayed absolute/relative error for standard PATRIUS uses with using JAFAMA library (reference: FastMath).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Item&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Jafama FastMath&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Jafama StrictFastMath&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Framework functions&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;center&amp;gt;&amp;lt;1E-15 rel.&amp;lt;/center&amp;gt;&lt;br /&gt;
| &amp;lt;center&amp;gt;&amp;lt;1E-15 rel.&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Low-level space mechanics functions&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;center&amp;gt;&amp;lt;1E-15 rel.&amp;lt;/center&amp;gt;&lt;br /&gt;
| &amp;lt;center&amp;gt;&amp;lt;1E-15 rel.&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LEO propagation on 24h&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;center&amp;gt;&amp;lt;1E-6m&amp;lt;/center&amp;gt;&lt;br /&gt;
| &amp;lt;center&amp;gt;&amp;lt;1E-6m&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GEO propagation on 24h&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;center&amp;gt;&amp;lt;1E-5m&amp;lt;/center&amp;gt;&lt;br /&gt;
| &amp;lt;center&amp;gt;&amp;lt;1E-5m&amp;lt;/center&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GTO propagation on 24h&#039;&#039;&#039;&lt;br /&gt;
| &amp;lt;center&amp;gt;&amp;lt;1E-6m&amp;lt;/center&amp;gt;&lt;br /&gt;
| &amp;lt;center&amp;gt;&amp;lt;1E-6m&amp;lt;/center&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Roughly, an absolute accuracy on position of 1E-6m for LEO orbits means a relative accuracy of 1E-12.&lt;br /&gt;
&lt;br /&gt;
The accuracy (with respect to FastMath) is directly correlated to the number of used JAFAMA operations. To get an idea of what accuracy to expect:&lt;br /&gt;
* 1 single JAFAMA operation leads to a relative accuracy of 1E-15 or better&lt;br /&gt;
* 1 propagation over 24 h (with millions calls to JAFAMA) leads to a relative accuracy of 1E-12&lt;br /&gt;
&lt;br /&gt;
**Warning: **Except for StrictMath, PATRIUS does not guarantee implementations of various JVM will return the exact same result.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
In the following section are defined potential use of Math framework.&lt;br /&gt;
&lt;br /&gt;
=== Simple user ===&lt;br /&gt;
&lt;br /&gt;
This user does not want to change anything with PATRIUS 4.2 upgrade. He has two options:&lt;br /&gt;
* Continue to use FastMath and do nothing in particular:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final double y = FastMath.sin(x);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Still use FastMath through the use of MathLib&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final double y = MathLib.sin(x);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Note: by default, MathLib calls FastMath.&lt;br /&gt;
&lt;br /&gt;
=== Intermediate user ===&lt;br /&gt;
&lt;br /&gt;
This user wants to use another Math framework (here FastMath from JAFAMA):&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
MathLib.setMathLibrary(MathLibraryType.JAFAMA_FASTMATH);&lt;br /&gt;
final double y = MathLib.sin(x);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Advanced user ===&lt;br /&gt;
&lt;br /&gt;
This user wants to use his own math framework:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;final MathLibrary myOwnFramework = new MathLibrary() {&lt;br /&gt;
    public double sin(final double x) {&lt;br /&gt;
        return ...;&lt;br /&gt;
    }&lt;br /&gt;
    ...&lt;br /&gt;
}&lt;br /&gt;
MathLib.setMathLibrary(myOwnFramework);&lt;br /&gt;
final double y = MathLib.sin(x);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
The library defines the following interfaces related to math frameworks:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MathLibrary&#039;&#039;&#039;&lt;br /&gt;
|Interface for low-level Math framework&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/framework/MathLibrary.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
The library defines the following classes related to low-level Math frameworks:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MathLib&#039;&#039;&#039;&lt;br /&gt;
|Static class for generic low-level math functions use&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/MathLib.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MathLibraryType&#039;&#039;&#039;&lt;br /&gt;
|Enumeration for currently available Math framework in PATRIUS&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/framework/MathLibraryType.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FastMathWrapper&#039;&#039;&#039;&lt;br /&gt;
|Wrapper of FastMath class implementing MathLibrary interface&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/framework/FastMathWrapper.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MathWrapper&#039;&#039;&#039;&lt;br /&gt;
|Wrapper of Math class implementing MathLibrary interface&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/framework/MathWrapper.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;StrictMathWrapper&#039;&#039;&#039;&lt;br /&gt;
|Wrapper of StrictMath class implementing MathLibrary interface&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/framework/StrictMathWrapper.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;JafamaFastMathWrapper&#039;&#039;&#039;&lt;br /&gt;
|Wrapper of Jafama FastMath class implementing MathLibrary interface&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/framework/JafamaFastMathWrapper.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;JafamaStrictFastMathWrapper&#039;&#039;&#039;&lt;br /&gt;
|Wrapper of Jafama StrictFastMath class implementing MathLibrary interface&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/framework/JafamaStrictFastMathWrapper.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FastestMathLibWrapper&#039;&#039;&#039;&lt;br /&gt;
|Implementation wrapping the fastest implementation among Math, FastMath, StrictMath and Jafama for each function&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/framework/FastestMathLibWrapper.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FastMath&#039;&#039;&#039;&lt;br /&gt;
|Original class from PATRIUS providing low-level math functions&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/FastMath.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Interpolation_Methods&amp;diff=4134</id>
		<title>User Manual 4.18 Interpolation Methods</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Interpolation_Methods&amp;diff=4134"/>
		<updated>2026-06-10T08:51:54Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === In this section, a focus is realised on the following interpolation methods: spline, bicubic, tricubic, Lagrange and Newton, covariance matrix and linear in 1D, 2D or 3D interpolation.  === Javadoc === The interpolation objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.analysis.interpolation&amp;lt;/code&amp;gt; and in the  package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.propagation.analytical.covariance&amp;lt;/code&amp;gt;.  {| class=&amp;quot;... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
In this section, a focus is realised on the following interpolation methods: spline, bicubic, tricubic, Lagrange and Newton, covariance matrix and linear in 1D, 2D or 3D interpolation.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The interpolation objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.analysis.interpolation&amp;lt;/code&amp;gt; and in the  package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.propagation.analytical.covariance&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
| Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/package-summary.html Package fr.cnes.sirius.patrius.math.analysis.interpolation]&lt;br /&gt;
|-&lt;br /&gt;
| Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/package-summary.html Package fr.cnes.sirius.patrius.math.analysis.interpolation]&lt;br /&gt;
|-&lt;br /&gt;
| Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/propagation/analytical/covariance/package-summary.html Package fr.cnes.sirius.patrius.propagation.analytical.covariance]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.analysis.interpolation&amp;lt;/code&amp;gt; contains all the interpolation classes described in this section.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Spline interpolation ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;spline interpolator&#039;&#039;&#039;&#039;&#039; generates an interpolating function &amp;lt;math&amp;gt;f(x): \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. The user gives as entries 2 sets of values, the values of x, y. The interpolator gives the function f such as &amp;lt;math&amp;gt;y=f(x)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For the linear equation &amp;lt;math&amp;gt;y=2x+1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double x[] = { 0.0, 1.0, 2.0 };&lt;br /&gt;
double y[] = { 1.0, 3.0, 5.0 };&lt;br /&gt;
&lt;br /&gt;
UnivariateInterpolator interpolator = new SplineInterpolator();&lt;br /&gt;
UnivariateFunction function = interpolator.interpolate(x, y);&lt;br /&gt;
double  value = function .value(0.5);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
=== Bicubic interpolation ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;bicubic interpolator&#039;&#039;&#039;&#039;&#039; generates an interpolating function &amp;lt;math&amp;gt;f(x,y): \mathbb{R}^2 \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. The interpolator computes internally the coefficients of the bicubic function that is the interpolating function. The user gives as entries 3 sets of values, the values of x, y and z. The interpolator gives the function f such as &amp;lt;math&amp;gt;z=f(x,y)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For the equation of the plane &amp;lt;math&amp;gt;z=2x-3y + 5&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double x[] = { 3, 4, 5, 6.5 };&lt;br /&gt;
double y[] = {-4, -3, -1, 2, 2.5 };&lt;br /&gt;
double z[][] = {{ 23, 20, 14, 5, 3.5 },&lt;br /&gt;
  { 25, 22, 16, 7, 5.5 },&lt;br /&gt;
  { 27, 24, 18, 9, 7.5 },&lt;br /&gt;
  { 30, 27, 21, 12, 10.5 }};&lt;br /&gt;
BivariateGridInterpolator interpolator = new BicubicSplineInterpolator();&lt;br /&gt;
BivariateFunction function = interpolator.interpolate(x, y, z);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tricubic interpolation ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;tricubic interpolator&#039;&#039;&#039;&#039;&#039; generates an interpolating function &amp;lt;math&amp;gt;f(x,y,z): \mathbb{R}^3 \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. The interpolator computes internally the coefficients of the tricubic function that is the interpolating function. The user gives as entries 4 sets of values, the values of x, y, z and w. The interpolator gives the function f such as &amp;lt;math&amp;gt;w=f(x,y,z)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For the equation of the plane &amp;lt;math&amp;gt;w=2x- 3y - z + 5&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double x[] = { 3.0, 4.0, 5.0, 6.5 };&lt;br /&gt;
double y[] = {-4.0, -3.0, -1.0, 2.0, 2.5 };&lt;br /&gt;
double z[] = {-12.0, -8.0, -5.5, -3.0, 0.0, 2.5 };&lt;br /&gt;
double w[][][] = {{{ 35, 31, 28.5, 26, 23, 20.5 },&lt;br /&gt;
{ 32, 28, 25.5, 23, 20, 17.5 },&lt;br /&gt;
{ 26, 22, 19.5, 17, 14, 11.5 },&lt;br /&gt;
{ 17, 13, 10.5, 8, 5, 2.5 },&lt;br /&gt;
{ 15.5, 11.5, 9, 6.5, 3.5, 1 }},&lt;br /&gt;
{{ 37, 33, 30.5, 28, 25, 22.5 },&lt;br /&gt;
{ 34, 30, 27.5, 25, 22, 19.5 },&lt;br /&gt;
{ 28, 24, 21.5, 19, 16, 13.5 },&lt;br /&gt;
{ 19, 15, 12.5, 10, 7, 4.13 },&lt;br /&gt;
{ 17.5, 13.5, 11, 8.5, 5.5, 3 }},&lt;br /&gt;
{{ 39, 35, 32.5, 30, 27, 24.13 },&lt;br /&gt;
{ 36, 32, 39.5, 27, 24, 21.5 },&lt;br /&gt;
{ 30, 26, 23.5, 21, 18, 15.5 },&lt;br /&gt;
{ 21, 17, 14.13, 12, 9, 6.5 },&lt;br /&gt;
{ 19.5, 15.5, 13, 10.5, 7.5, 5 }},&lt;br /&gt;
{{ 42, 38, 35.5, 33, 30, 27.5 },&lt;br /&gt;
{ 39, 35, 32.5, 30, 27, 24.13 },&lt;br /&gt;
{ 33, 29, 26.5, 24, 21, 18.5 },&lt;br /&gt;
{ 24, 20, 17.5, 15, 12, 9.5 },&lt;br /&gt;
{ 22.5, 18.5, 16, 13.5, 10.5, 8 }}};&lt;br /&gt;
&lt;br /&gt;
TrivariateGridInterpolator interpolator = new TricubicSplineInterpolator();&lt;br /&gt;
TrivariateFunction function = interpolator.interpolate(x, y, z, w);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Lagrange interpolation ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;Lagrange interpolator&#039;&#039;&#039;&#039;&#039; generates an interpolating function &amp;lt;math&amp;gt;f(x): \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. The user gives as entries 2 sets of values, the values of x, y. The interpolator gives the function f such as &amp;lt;math&amp;gt;y=f(x)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For the linear equation &amp;lt;math&amp;gt;y=2x+1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double x[] = { 0.0, 1.0, 2.0 };&lt;br /&gt;
double y[] = { 1.0, 3.0, 5.0 };&lt;br /&gt;
&lt;br /&gt;
UnivariateFunction interpolator = new PolynomialFunctionLagrangeForm(x,y);&lt;br /&gt;
double  value = interpolator.value(0.5);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Newton interpolation ===&lt;br /&gt;
The &#039;&#039;&#039;&#039;&#039;Newton interpolator&#039;&#039;&#039;&#039;&#039; generates an interpolating function &amp;lt;math&amp;gt;f(x): \mathbb{R} \rightarrow \mathbb{R}&amp;lt;/math&amp;gt;. The user gives as entries 2 sets of values, the coefficients &amp;lt;math&amp;gt;c_i&amp;lt;/math&amp;gt;and the centers &amp;lt;math&amp;gt;x_i&amp;lt;/math&amp;gt;such as the polynomial function &amp;lt;math&amp;gt;P(x)=c_0 + c_1 (x - x_0) + ... + c_n (x - x_n)&amp;lt;/math&amp;gt;. The interpolator gives the function f such as &amp;lt;math&amp;gt;y=P(x)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
For the linear equation &amp;lt;math&amp;gt;y=2x+1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double c_i[] = { 3.0, 2.0 };&lt;br /&gt;
double x_i[] = { 1.0 };&lt;br /&gt;
&lt;br /&gt;
UnivariateFunction interpolator = new PolynomialFunctionNewtonForm(c_i,x_i);&lt;br /&gt;
double  value = interpolator.value(0.5);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Covariance matrix interpolation ===&lt;br /&gt;
The purpose of this interpolation algorithm is to compute the covariance matrix at a given date through a simplified model of the transition matrix. When a covariance in PV coordinates is searched for an object orbiting around an celestial body, a simple dynamical model can be used, meaning limited to the newtonian attraction, plus a constant acceleration. The value of this constant acceleration will not change the transition matrix.&lt;br /&gt;
&lt;br /&gt;
The transition matrix between a date &amp;lt;math&amp;gt;t_1&amp;lt;/math&amp;gt;  and a date &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; can be approximated :&lt;br /&gt;
&lt;br /&gt;
* at order 0 : by  &amp;lt;math&amp;gt;\phi_1(t_1, t) =  I_{3 \times 3}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* at order 1 : by &amp;lt;math&amp;gt;\phi_1(t_1, t) = I_{3 \times 3} +  J_{PV} ( t- t_1)&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
* at order 2 : by&amp;lt;math&amp;gt;\phi_1(t_1, t) =I_{3 \times 3} +  J_{PV} ( t- t_1)+  0.5 * J_{PV}^2 ( t - t_1)^2&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
where &amp;lt;math&amp;gt;J_{PV} = \left(\begin{array}{cc} 0_{3 \times 3} &amp;amp; I_{3 \times 3} \\ A  &amp;amp; 0_{3 \times 3} \end{array} \right)&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;J_{PV}^2 = \left(\begin{array}{cc} A &amp;amp; 0_{3 \times 3}  \\ 0_{3 \times 3} &amp;amp; A \end{array} \right)&amp;lt;/math&amp;gt; and  &amp;lt;math&amp;gt;A =- \frac{ GM}{r^3}\left(I_{3 \times 3} - 3  \frac{ PP^T}{r^2}\right)&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is considered as a constant on the interval &amp;lt;math&amp;gt;[t_1,t]&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;P&amp;lt;/math&amp;gt; is the satellite position vector.&lt;br /&gt;
&lt;br /&gt;
We denote by &amp;lt;math&amp;gt;M(t)&amp;lt;/math&amp;gt; the covariance matrix at instant t. Let &amp;lt;math&amp;gt;t \in [t_1,t]&amp;lt;/math&amp;gt; . The transition matrices &amp;lt;math&amp;gt;\phi_1(t_1, t)&amp;lt;/math&amp;gt;  and  &amp;lt;math&amp;gt;\phi_2(t_2, t)&amp;lt;/math&amp;gt; are given by the above formula, and since matrix &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; is constant on  &amp;lt;math&amp;gt;[t_1,t_2]&amp;lt;/math&amp;gt;, we have that the covariance matrix at instant &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;  is given by&lt;br /&gt;
&amp;lt;math&amp;gt;M(t) = (1- \alpha) \phi_1(t_1, t) M(t_1)\phi_1^T(t_1, t) + \alpha \phi_2(t_2, t) M(t_2)\phi_2^T(t_2, t),&amp;lt;/math&amp;gt;&lt;br /&gt;
with  &amp;lt;math&amp;gt;\alpha = \frac{t-t_1}{t_2-t_1}&amp;lt;/math&amp;gt;.&lt;br /&gt;
=== Linear interpolation ===&lt;br /&gt;
These classes allow linear piecewise interpolations in dimensions 1, 2 or 3.&lt;br /&gt;
&lt;br /&gt;
==== 1D interpolation ====&lt;br /&gt;
&lt;br /&gt;
Let &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; be a real function &amp;lt;math&amp;gt;\mathbb{R} \rightarrow  \mathbb{R}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;[x_1,x_2]&amp;lt;/math&amp;gt; the interpolation interval, where  &amp;lt;math&amp;gt;f(x_1),f(x_2)&amp;lt;/math&amp;gt; are known. For all &amp;lt;math&amp;gt;x \in [x_1,x_2]&amp;lt;/math&amp;gt;, the interpolated value &amp;lt;math&amp;gt;f(x)&amp;lt;/math&amp;gt; is given by &lt;br /&gt;
&amp;lt;math&amp;gt;f(x) = f(x_1) + (x-x_1) \frac{f(x_2)- f(x_1)}{x_2-x_1}.&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
==== 2D interpolation ====&lt;br /&gt;
The two dimensional interpolation will be two successive 1D interpolations.&lt;br /&gt;
Let &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; be a real function &amp;lt;math&amp;gt;\mathbb{R}^2 \rightarrow  \mathbb{R}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;[x_1,x_2] \times [y_1,y_2]&amp;lt;/math&amp;gt; the interpolation interval.&lt;br /&gt;
First, a 1D interpolation in the &amp;lt;math&amp;gt;y&amp;lt;/math&amp;gt; direction is made, leading to &lt;br /&gt;
&amp;lt;math&amp;gt;f(x,y_1) = f(x_1,y_1) + (y-y_1) \frac{f(x_2,y_1)- f(x_1,y_1)}{y_2-y_1},&amp;lt;/math&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;math&amp;gt;f(x,y_2) = f(x_1,y_2) + (y-y_1) \frac{f(x_2,y_2)- f(x_1,y_2)}{y_2-y_1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Then a second 1D interpolation is made in the &amp;lt;math&amp;gt;x&amp;lt;/math&amp;gt; direction with the previous two interpolated values :&lt;br /&gt;
&amp;lt;math&amp;gt;f(x,y) = f(x,y_1) + (x-x_1) \frac{f(x,y_2)- f(x, y_1)}{x_2-x_1}.&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 3D interpolation ====&lt;br /&gt;
&lt;br /&gt;
Let &amp;lt;math&amp;gt;f&amp;lt;/math&amp;gt; be a real function &amp;lt;math&amp;gt;\mathbb{R}^3 \rightarrow  \mathbb{R}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;[x_1,x_2] \times [y_1,y_2] \times [z_1,z_2]&amp;lt;/math&amp;gt; the interpolation interval. There will be &amp;lt;math&amp;gt;2^3- 1&amp;lt;/math&amp;gt; successives 1D interpolations.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f(x,y,z)&amp;lt;/math&amp;gt; is interpolated from &amp;lt;math&amp;gt;f(x,y,z_1)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;f(x,y,z_2)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f(x,y,z_1)&amp;lt;/math&amp;gt; is interpolated from &amp;lt;math&amp;gt;f(x,y_1,z_1)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;f(x,y_2,z_1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f(x,y,z_2)&amp;lt;/math&amp;gt; is interpolated from &amp;lt;math&amp;gt;f(x,y_1,z_2)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;f(x,y_2,z_2)&amp;lt;/math&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f(x,y_1,z_1)&amp;lt;/math&amp;gt; is interpolated from &amp;lt;math&amp;gt;f(x_1,y_1,z_1)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;f(x_2,y_1,z_1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f(x,y_2,z_1)&amp;lt;/math&amp;gt; is interpolated from &amp;lt;math&amp;gt;f(x_1,y_2,z_1)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;f(x_2,y_2,z_1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f(x,y_1,z_2)&amp;lt;/math&amp;gt; is interpolated from &amp;lt;math&amp;gt;f(x_1,y_1,z_2)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;f(x_2,y_1,z_1)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f(x,y_2,z_2)&amp;lt;/math&amp;gt; is interpolated from &amp;lt;math&amp;gt;f(x_1,y_2,z_2)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;f(x_2,y_2,z_2)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
{{specialInclusion prefix=$theme_sub section=&amp;quot;GettingStarted&amp;quot;/}}&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
The library defines the following interfaces related to interpolation :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UnivariateInterpolator&#039;&#039;&#039;&lt;br /&gt;
|Interface for a univariate interpolating function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/UnivariateInterpolator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BivariateGridInterpolator&#039;&#039;&#039;&lt;br /&gt;
|Interface for a bivariate interpolating function where the sample points must be specified on a regular grid.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/BivariateGridInterpolator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TrivariateGridInterpolator&#039;&#039;&#039;&lt;br /&gt;
|Interface for a trivariate interpolating function where the sample points must be specified on a regular grid.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/TrivariateGridInterpolator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UnivariateFunction&#039;&#039;&#039;&lt;br /&gt;
|Interface for a univariate function&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/UnivariateFunction.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
This section is about the following classes related to interpolation :&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SplineInterpolator&#039;&#039;&#039;&lt;br /&gt;
|Spline interpolator for a univariate real function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/SplineInterpolator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BicubicSplineInterpolator&#039;&#039;&#039;&lt;br /&gt;
|Bicubic spline interpolator for a bivariate real function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/BicubicSplineInterpolator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TricubicSplineInterpolator&#039;&#039;&#039;&lt;br /&gt;
|Tricubic spline interpolator for a trivariate real function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/TricubicSplineInterpolator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PolynomialFunctionLagrangeForm&#039;&#039;&#039;&lt;br /&gt;
|Lagrange interpolator, directly usable as a univariate real function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/polynomials/PolynomialFunctionLagrangeForm.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PolynomialFunctionNewtonForm&#039;&#039;&#039;&lt;br /&gt;
|Newton interpolator, directly usable as a univariate real function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/polynomials/PolynomialFunctionNewtonForm.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CovarianceInterpolation&#039;&#039;&#039;&lt;br /&gt;
|Interpolator of a covariance matrix based on its two surrounding covariance matrices.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/propagation/analytical/covariance/CovarianceInterpolation.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CovarianceInterpolation&#039;&#039;&#039;&lt;br /&gt;
|Interpolator of a covariance matrix based on its two surrounding covariance matrices.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/propagation/analytical/covariance/CovarianceInterpolation.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbstractLinearIntervalsFunction&#039;&#039;&#039;&lt;br /&gt;
|Abstract class for linear interpolations.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/AbstractLinearIntervalsFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UniLinearIntervalsFunction&#039;&#039;&#039;&lt;br /&gt;
| Linear one-dimensional function.&lt;br /&gt;
| [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/UniLinearIntervalsFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BiLinearIntervalsFunction&#039;&#039;&#039;&lt;br /&gt;
|Linear two-dimensional function. &lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/BiLinearIntervalsFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TriLinearIntervalsFunction&#039;&#039;&#039;&lt;br /&gt;
|Linear three-dimensional function.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/TriLinearIntervalsFunction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UniLinearIntervalsInterpolator&#039;&#039;&#039;&lt;br /&gt;
|Interpolator of linear one-dimensional functions.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/UniLinearIntervalsInterpolator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BiLinearIntervalsInterpolator&#039;&#039;&#039;&lt;br /&gt;
|Interpolator of linear two-dimensional functions.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/BiLinearIntervalsInterpolator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TriLinearIntervalsInterpolator&#039;&#039;&#039;&lt;br /&gt;
|Interpolator of linear three-dimensional functions.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/analysis/interpolation/TriLinearIntervalsInterpolator.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; |Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Covariance&#039;&#039;&#039;&lt;br /&gt;
|Class containing a covariance matrix and the list of parameter descriptors of every row in the covariance matrix&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/covariance/Covariance.html Covariance]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbstractOrbitalCovariance&#039;&#039;&#039;&lt;br /&gt;
|An orbital covariance associates a Covariance instance with a given date and the frame, orbit type (Cartesian, Keplerian, etc) and position angle type (mean, true, eccentric) in which it is expressed.&lt;br /&gt;
|[{{JavaDoc4.18}}&amp;lt;nowiki&amp;gt;/fr/cnes/sirius/patrius/covariance/AbstractOrbitalCovariance.html AbstractOrbitalCovariance]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OrbitalCovariance&#039;&#039;&#039;&lt;br /&gt;
|Class containing a covariance matrix and its associated Orbit. &lt;br /&gt;
|[{{JavaDoc4.18}}&amp;lt;nowiki&amp;gt;/fr/cnes/sirius/patrius/covariance/OrbitalCovariance.html OrbitalCovariance]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;MultiOrbitalCovariance&#039;&#039;&#039;&lt;br /&gt;
|Class containing a covariance matrix associated to multiple orbits&lt;br /&gt;
|[{{JavaDoc4.18}}&amp;lt;nowiki&amp;gt;/fr/cnes/sirius/patrius/covariance/MultiOrbitalCovariance.html MultiOrbitalCovariance]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User Manual 4.18 Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Geometry&amp;diff=4133</id>
		<title>User Manual 4.18 Geometry</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Geometry&amp;diff=4133"/>
		<updated>2026-06-10T08:51:25Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === The geometry objects implemented in the PATRIUS library are both infinite and finite shapes.  The finite shapes shall be used for example to represent parts of a spacecraft or celestial bodies. The infinite ones can represent more mathematical surfaces such as instruments&amp;#039; characteristics.  All the objects provide methods to compute interactions with lines (intersections, distances, etc...), points and other objects.... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The geometry objects implemented in the PATRIUS library are both infinite and finite shapes.&lt;br /&gt;
&lt;br /&gt;
The finite shapes shall be used for example to represent parts of a spacecraft or celestial bodies. The infinite ones can represent more mathematical surfaces such as instruments&#039; characteristics.&lt;br /&gt;
&lt;br /&gt;
All the objects provide methods to compute interactions with lines (intersections, distances, etc...), points and other objects.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The geometry objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.geometry.euclidean.threed&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/package-summary.html Package fr.cnes.sirius.patrius.math.geometry.euclidean.threed]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/package-summary.html Package fr.cnes.sirius.patrius.math.geometry.euclidean.threed]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
The math package contains several other packages related to geometry (1D, 2D, 3D) and provides objects for Binary Space Partitioning (BSP) Tree. See javadoc for more information.&lt;br /&gt;
Some other &amp;quot;basic&amp;quot; objects are contained in the threed package and documented in other parts of this manual (eg : Rotations, Matrix3D).&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
Useful reference documents for this theme can be found here :&lt;br /&gt;
&lt;br /&gt;
* Nürnberg, R.; &#039;&#039;Distance from a Point to an Ellipse&#039;&#039;, Imperial College London, 2006, [http://www2.imperial.ac.uk/~~rn/distance2ellipse.pdf http://www2.imperial.ac.uk/~~rn/distance2ellipse.pdf].&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The aim of the following diagram is to present the architecture implemented for the Geometry package. This does not mean that all the classes and/or interfaces are in the Geometry package and it does not mean that all the classes and interfaces of the package are presented.&lt;br /&gt;
&lt;br /&gt;
[[File:geometry.PNG|center]]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== 2D Objects ===&lt;br /&gt;
The two dimensional objects (in three dimensional space) implemented in the PATRIUS library are given hereunder :&lt;br /&gt;
&lt;br /&gt;
* Lines&lt;br /&gt;
* Planes&lt;br /&gt;
* Plates&lt;br /&gt;
* Disks&lt;br /&gt;
* Ellipses&lt;br /&gt;
&lt;br /&gt;
Please refer to the [MAT_GEO_Home#HClasses Classes section] for more information.&lt;br /&gt;
&lt;br /&gt;
=== 3D Objects ===&lt;br /&gt;
The three dimensional objects (in three dimensional space) implemented in the PATRIUS library are given hereunder :&lt;br /&gt;
&lt;br /&gt;
* Infinite and Finite Cylinders (right circular, elliptic and rectangular)&lt;br /&gt;
* Infinite and Finite Cones (right circular, oblique circular and rectangular)&lt;br /&gt;
* Spheres, Spheroids and Spherical Caps&lt;br /&gt;
* Parallelepipeds&lt;br /&gt;
&lt;br /&gt;
Please refer to the [MAT_GEO_Home#HClasses Classes section] for more information.&lt;br /&gt;
&lt;br /&gt;
=== Interactions between objects ===&lt;br /&gt;
[MAT_GEO_Home#HInterfaces Interfaces] have been implemented for geometrical objects in order to set a standard as to what method each and any geometrical object should implement.&lt;br /&gt;
&lt;br /&gt;
As of now, (some of the) geometrical objects must provide methods to :&lt;br /&gt;
* Check if a line intersects with said objects,&lt;br /&gt;
* Compute and return the intersection points,&lt;br /&gt;
* Compute and return the closest point on the object surface to a given user point,&lt;br /&gt;
* Compute and return the distance between these two points,&lt;br /&gt;
* Compute and return the closest point on the object surface to a given user line and return the closest points on the line and on the object,&lt;br /&gt;
* Compute and return the distance between an object and a given user line.&lt;br /&gt;
&lt;br /&gt;
Plese refer to the [MAT_GEO_Home#HInteractions Interactions section] for more details.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Interactions ===&lt;br /&gt;
Given an object implementing the [MAT_GEO_Home#HInterfaces Shape] interface, the following methods are available :&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;intersects(Line) : boolean&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Test the intersection of the object with a user given line.&lt;br /&gt;
&lt;br /&gt;
Code snippet :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Line line = new Line(lineOrigin, lineDirection);&lt;br /&gt;
boolean result = myObject.intersects(line);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;getIntersectionPoints(Line) : Vector3D[]&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Compute the intersection point of the object with a user given line.&lt;br /&gt;
&lt;br /&gt;
Code snippet :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Line line = new Line(lineOrigin, lineDirection);&lt;br /&gt;
Vector3D[] intersectionPoints = myObject.getIntersectionPoints(line);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;closestPointTo(Vector3D) : Vector3D&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Compute the point on the surface of the object that is the closest to a user given point.&lt;br /&gt;
&lt;br /&gt;
Code snippet :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Vector3D point = new Vector3D(1.0, 2.0, 3.0);&lt;br /&gt;
Vector3D result = myObject.closestPointTo(point);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;distanceTo(Vector3D) : double&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Compute the shortest distance from the surface of the object and user given point. &lt;br /&gt;
&lt;br /&gt;
Code snippet :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Line line = new Line(lineOrigin, lineDirection);&lt;br /&gt;
double distance = myObject.distanceTo(line);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;closestPointTo(Line) : Vector3D[]&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Compute the points realizing the shortest distance to a line (the first one is from the line, the second one from the object ). If the line intersects the object , the two points are identical, and equal to the first one returned by the &amp;quot;getIntersectionPoints&amp;quot; method. If the line is parallel to the object &#039;s side, the closest point to the origin is used.&lt;br /&gt;
&lt;br /&gt;
Code snippet :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Line line = new Line(lineOrigin, lineDirection);&lt;br /&gt;
Vector3D[] points = myObject.closestPointTo(line);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;distanceTo(Line) : double&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Compute the shortest distance from a line to the surface of the object.&lt;br /&gt;
&lt;br /&gt;
Code snippet :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Line line = new Line(lineOrigin, lineDirection);&lt;br /&gt;
double distance = myObject.distanceTo(line);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Cone&#039;&#039;&#039;&lt;br /&gt;
|This interface extends the SolidShape interface for the particular case of cones.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Cone.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CrossSectionProvider&#039;&#039;&#039;&lt;br /&gt;
|Interface for all geometric objects that can provide their cross section from a direction defined by a Vector3D.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/CrossSectionProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Cylinder&#039;&#039;&#039;&lt;br /&gt;
|This interface extends the SolidShape interface for the particular case of cylinders.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Cylinder.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IEllipsoid&#039;&#039;&#039;&lt;br /&gt;
|This interface extends the InfiniteShape interface for the particular cases of ellipsoid objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/IEllipsoid.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;InfiniteCone&#039;&#039;&#039;&lt;br /&gt;
|This interface extends the InfiniteShape interface for the particular cases of infinite cones.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/InfiniteCone.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;InfiniteCylinder&#039;&#039;&#039;&lt;br /&gt;
|This interface extends the InfiniteShape interface for the particular cases of infinite cylinders.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/InfiniteCylinder.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;InfiniteShape&#039;&#039;&#039;&lt;br /&gt;
|This interface extends the Shape interface for the particular cases of infinite shapes.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/InfiniteShape.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Shape&#039;&#039;&#039;&lt;br /&gt;
|This interface is the &#039;&#039;&#039;main interface for all shapes&#039;&#039;&#039;, including infinite and solid shapes. It defines the general methods required by each geometrical object implementing any of the above interfaces : All of them must be able to compute their intersection and distance to a line. See [MAT_GEO_Home#HInteractionsbetweenobjects Interactions].&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Shape.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SolidShape&#039;&#039;&#039;&lt;br /&gt;
|This interface extends the Shape interface for the particular cases of solids.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/SolidShape.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
&#039;&#039;&#039;Basic Shapes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Disk&#039;&#039;&#039;&lt;br /&gt;
|The class represent disks in a three dimensional space.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Disk.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Ellipse&#039;&#039;&#039;&lt;br /&gt;
|The class represent ellipses in a three dimensional space.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Ellipse.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Line&#039;&#039;&#039;&lt;br /&gt;
|The class represent lines in a three dimensional space.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Line.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Plane&#039;&#039;&#039;&lt;br /&gt;
|The class represent planes in a three dimensional space.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Plane.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Plate&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for a 3D rectangle plate shape, with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Plate.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Parallelepiped&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for a rectangle parallelepiped shape, with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Parallelepiped.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cylinders&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;InfiniteEllipticCylinder&#039;&#039;&#039;&lt;br /&gt;
|This class is the Infinite Elliptic Cylinder class.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/InfiniteEllipticCylinder.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;InfiniteRightCircularCylinder&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for a 3D infinite right circular cylinder, with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/InfiniteRightCircularCylinder.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;InfiniteRectangleCylinder&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for a 3D infinite rectangle cylinder, with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math//geometry/euclidean/threed/InfiniteRectangleCylinder.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EllipticCylinder&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for a 3D oblique circular cylinder ended by two planes normal to its axis, with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/EllipticCylinder.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RightCircularCylinder&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for a 3D right circular cylinder ended by two planes normal to its axis, with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/RightCircularCylinder.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
NB : For the rectangular cylinder, please refer to the parallelepiped class mentioned above.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Cones&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;InfiniteRightCircularCone&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for a 3D infinite cone, with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/InfiniteRightCircularCone.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;InfiniteEllipticCone&#039;&#039;&#039;&lt;br /&gt;
|This class is the Infinite Elliptic Cone class.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/InfiniteEllipticCone.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;InfiniteRectangleCone&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for a 3D infinite cone, with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/InfiniteRectangleCone.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RightCircularCone&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for a 3D right circular cone ended by a plane normal to its axis, with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/RightCircularCone.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EllipticCone&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for a 3D elliptic cone ended by a plane normal to its axis, with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/EllipticCone.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RectangleCone&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for a 3D rectangle cone ended by a plane normal to its axis (pyramid), with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/RectangleCone.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Ellipsoids&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Ellipsoid&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for an ellipsoid, with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Ellipsoid.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sphere&#039;&#039;&#039;&lt;br /&gt;
|This is a describing class for a 3D spherical shape, with some algorithm to compute intersections and distances to some other objects.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Sphere.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Spheroid&#039;&#039;&#039;&lt;br /&gt;
|This is the Spheroid (also called Revolved Ellipsoid) class.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Spheroid.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Other objects&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Facet&#039;&#039;&#039;&lt;br /&gt;
|Implements a representation of a facet.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/assembly/properties/features/Facet.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SphericalCap&#039;&#039;&#039;&lt;br /&gt;
|Implements a representation of a spherical cap solid.&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/SphericalCap.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SphericalCoordinates&#039;&#039;&#039;&lt;br /&gt;
|Spherical coordinates to Vector3D .&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/SphericalCoordinates.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Double_Comparisons&amp;diff=4132</id>
		<title>User Manual 4.18 Double Comparisons</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.18_Double_Comparisons&amp;diff=4132"/>
		<updated>2026-06-10T08:51:01Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === The « Comparators » class contains static methods to perform relative comparisons of doubles.  === Javadoc === The Comparators class is available in the &amp;lt;code&amp;gt;package fr.cnes.sirius.patrius.math.interval&amp;lt;/code&amp;gt;.  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=&amp;quot;col&amp;quot;| Javadoc |- |Patrius  |[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/interval/package-summary.html Package fr.cnes.sirius.patrius.math.interval] |}... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The « Comparators » class contains static methods to perform relative comparisons of doubles.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The Comparators class is available in the &amp;lt;code&amp;gt;package fr.cnes.sirius.patrius.math.interval&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/interval/package-summary.html Package fr.cnes.sirius.patrius.math.interval]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
Some elements about the “equals” comparators previously proposed in the “MathUtils” class are described in the document “Comparing floating point numbers” by Bruce Dawson : [http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm].&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The doubles comparison issue is adressed through a single utility class, [{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/Comparators.html Comparators],  in the fr.cnes.sirius.patrius.utils package.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Algorithms and espilon value ===&lt;br /&gt;
The need here is to compare two values with a known maximum relative difference.&lt;br /&gt;
&lt;br /&gt;
The “equals” comparators previously proposed in the “MathUtils” class are of two types :&lt;br /&gt;
&lt;br /&gt;
* a simple absolute comparison using an epsilon&lt;br /&gt;
* a more complex one, described in the document “Comparing floating point numbers” by Bruce Dawson (see the Links paragraph)&lt;br /&gt;
&lt;br /&gt;
This last comparison makes more sense to compare real values and takes into account the precision issues due to the double type. It works as well with any exponent (high values or close to zero…), but the relative difference accepted between two equal doubles is uncontrolled, between 2.5e-16 and 1.25e-16 for a maxUlps of 1 (difference between two consecutive doubles).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is proposed a new comparison method to control the maximum relative difference and still have a comparison that makes sense when computed.&lt;br /&gt;
&lt;br /&gt;
=== The Comparators class ===&lt;br /&gt;
The new comparison method is implemented in the Comparators class. Its simplified algorithm is described below with pseudo-code.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;x and y are two doubles.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039; IF x equals y in the Bruce Dawson’s way &#039;&#039;&lt;br /&gt;
** &#039;&#039;=&amp;gt; Then the return is “TRUE” regardless to relative difference&#039;&#039;&lt;br /&gt;
* &#039;&#039; ELSE :&#039;&#039;&lt;br /&gt;
** &#039;&#039;=&amp;gt; IF the absolute relative difference is lower than the epsilon, then the return is “TRUE”&#039;&#039;&lt;br /&gt;
* &#039;&#039;ENDIF&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
NB : the epsilon can be chosen by the user, eventually between 2.5e-16 and 1.25e-16 (min and max values for the relative difference in Bruce Dawson’s algorithm). In that case, the comparison becomes at worst uncontrolled and doesn’t make any sense : sometimes the epsilon will be used, sometimes not, without information to the user. If the chosen epsilon is lower than 1.25e-16, it becomes useless.&lt;br /&gt;
&lt;br /&gt;
The default epsilon proposed is :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Comparators.DOUBLE_COMPARISON_EPSILON&#039;&#039; = 1.0e-14&lt;br /&gt;
&lt;br /&gt;
(two orders higher than the max relative difference between to consecutive doubles)&lt;br /&gt;
&lt;br /&gt;
==== Using the Comparators class ====&lt;br /&gt;
&lt;br /&gt;
The Comparators class provides the following static methods &#039;&#039;equal, lowerOrEqual, greaterOrEqual, lowerStrict, greaterStrict,&#039;&#039; for doubles comparison purposes.&lt;br /&gt;
&lt;br /&gt;
Their returns are Booleans, in order to be used the same way as classical « &amp;gt; », « == »…&lt;br /&gt;
&lt;br /&gt;
Code examples :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
if (Comparators.equals(x, y, eps)) { } // epsilon given by the user&lt;br /&gt;
if (Comparators.equals(x, y)) { }  // default epsilon&lt;br /&gt;
if (Comparators.lowerOrEqual(x, y)) { }  // default epsilon&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
These comparisons are relative and use an epsilon value. Each method is duplicated, so the choice is given to use the default epsilon (&#039;&#039;Comparators.DOUBLE_COMPARISON_EPSILON&#039;&#039;) or any other value, by adding it to the method’s signature.&lt;br /&gt;
&lt;br /&gt;
To respect the &#039;&#039;&#039;IEEE Standard 754&#039;&#039;&#039;, a “NaN” is considered different to any other double, including “NaN” itself, and the positive and negative infinite values are considered only equal to themselves (see behaviour examples).&lt;br /&gt;
&lt;br /&gt;
==== Examples of &amp;quot;equals&amp;quot; method behaviour (using default epsilon) : ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| X&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Y&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| |X-Y|/Y&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| MathUtils.equals result&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Comparators.equals result&lt;br /&gt;
|-&lt;br /&gt;
|0.0&lt;br /&gt;
|1.0e-300&lt;br /&gt;
|1.0&lt;br /&gt;
|false&lt;br /&gt;
|false&lt;br /&gt;
|-&lt;br /&gt;
|1.25000000000000025&lt;br /&gt;
|1.25&lt;br /&gt;
|2.0e-16&lt;br /&gt;
|false&lt;br /&gt;
|true&lt;br /&gt;
|-&lt;br /&gt;
|1.0000000000000002&lt;br /&gt;
|1.0&lt;br /&gt;
|2.0e-16&lt;br /&gt;
|true&lt;br /&gt;
|true&lt;br /&gt;
|-&lt;br /&gt;
|1.0000000000000001e+300&lt;br /&gt;
|1.0e+300&lt;br /&gt;
|1.0e-16&lt;br /&gt;
|true&lt;br /&gt;
|true&lt;br /&gt;
|-&lt;br /&gt;
|1.0000000000000001e-300&lt;br /&gt;
|1.0e-300&lt;br /&gt;
|1.0e-16&lt;br /&gt;
|true&lt;br /&gt;
|true&lt;br /&gt;
|-&lt;br /&gt;
|1.000000000000001&lt;br /&gt;
|1.0&lt;br /&gt;
|1.0e-15&lt;br /&gt;
|false&lt;br /&gt;
|true&lt;br /&gt;
|-&lt;br /&gt;
|1.000000000000001e+300&lt;br /&gt;
|1.0e+300&lt;br /&gt;
|1.0e-15&lt;br /&gt;
|false&lt;br /&gt;
|true&lt;br /&gt;
|-&lt;br /&gt;
|1.000000000000001e-300&lt;br /&gt;
|1.0e-300&lt;br /&gt;
|1.0e-15&lt;br /&gt;
|false&lt;br /&gt;
|true&lt;br /&gt;
|-&lt;br /&gt;
|1.0000000000001&lt;br /&gt;
|1.0&lt;br /&gt;
|1.0e-13&lt;br /&gt;
|false&lt;br /&gt;
|false&lt;br /&gt;
|-&lt;br /&gt;
|1.0000000000001e+300&lt;br /&gt;
|1.0e+300&lt;br /&gt;
|1.0e-13&lt;br /&gt;
|false&lt;br /&gt;
|false&lt;br /&gt;
|-&lt;br /&gt;
|1.0000000000001e-300&lt;br /&gt;
|1.0e-300&lt;br /&gt;
|1.0e-13&lt;br /&gt;
|false&lt;br /&gt;
|false&lt;br /&gt;
|-&lt;br /&gt;
|NaN&lt;br /&gt;
|NaN&lt;br /&gt;
| -&lt;br /&gt;
|false&lt;br /&gt;
|false&lt;br /&gt;
|-&lt;br /&gt;
|NaN&lt;br /&gt;
|Any other double&lt;br /&gt;
| -&lt;br /&gt;
|false&lt;br /&gt;
|false&lt;br /&gt;
|-&lt;br /&gt;
|POSITIVE_INFINITE&lt;br /&gt;
|POSITIVE_INFINITE&lt;br /&gt;
| -&lt;br /&gt;
|true&lt;br /&gt;
|true&lt;br /&gt;
|-&lt;br /&gt;
|POSITIVE_INFINITE&lt;br /&gt;
|Any other double&lt;br /&gt;
| -&lt;br /&gt;
|false&lt;br /&gt;
|false&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Notice the second and third lines : two pair of doubles with the same relative difference imply a “false” for the first, and a “true” for the second.&lt;br /&gt;
&lt;br /&gt;
Using a relative epsilon allows us to stay coherent in any case.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Beware :&#039;&#039;&#039; when realizing a comparison close to zero, you must think about the type of comparison needed. In order to perform comparison in the same way regardless to the exponents, our comparator considers a double with a very low exponent different to zero (first line of the example). In some cases, an absolute comparison with epsilon shall be needed (to compare the result of a computation to zero...).&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
{{specialInclusion prefix=$theme_sub section=&amp;quot;GettingStarted&amp;quot;/}}&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
None as of now.&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
The only class is &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.Comparators&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Class&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Comparators&#039;&#039;&#039;&lt;br /&gt;
|Static comparison methods for real numbers&lt;br /&gt;
|[{{JavaDoc4.18}}/fr/cnes/sirius/patrius/math/Comparators.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.18_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
</feed>