<?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-04-26T14:58:41Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Data_management_system&amp;diff=4099</id>
		<title>User Manual 4.17 Data management system</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Data_management_system&amp;diff=4099"/>
		<updated>2025-12-12T15:24:33Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The scope of this chapter is to present data management. This section presents the three modules of the data management system originally provided by Orekit :&lt;br /&gt;
&lt;br /&gt;
* how does the data management system work?&lt;br /&gt;
* how to set it up?&lt;br /&gt;
* how to use it?&lt;br /&gt;
* how to add data to what already exists?&lt;br /&gt;
* what are the pros and cons of this system?&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The data objects are available in the packages :&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&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;
|[https://patrius.cnes.fr/images/upload/JavaDocs/V4.17/fr/cnes/sirius/patrius/data/package-summary.html Package fr.cnes.sirius.patrius.data]&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 data loading process is organized through three main objects.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;DataProvider&amp;lt;/code&amp;gt; classes handle data sources. Each one of them has a particular type of source it can browse. The &amp;lt;code&amp;gt;DirectoryCrawler&amp;lt;/code&amp;gt; performs a bottom-first search in a directory tree. The &amp;lt;code&amp;gt;ZipJarCrawler&amp;lt;/code&amp;gt; works alike, but inside a compressed file. The &amp;lt;code&amp;gt;ClassPathCrawler&amp;lt;/code&amp;gt; handles a list of data files and/or compressed files that are in the classpath (it can not search recursively like the &amp;lt;code&amp;gt;DirectoryCrawler&amp;lt;/code&amp;gt; though). Finally, the &amp;lt;code&amp;gt;NetworkCrawler&amp;lt;/code&amp;gt; works like the &amp;lt;code&amp;gt;ClassPathCrawler&amp;lt;/code&amp;gt;, although in its case, it has a list of URLs instead of files. There is no limit to the number of DataProviders a program can use at once.&lt;br /&gt;
&lt;br /&gt;
The Providers are listed and put to work through the &amp;lt;code&amp;gt;DataProvidersManager&amp;lt;/code&amp;gt; singleton. This is the single point of access to the data management system. It contains a list of Providers that are queried every time a user needs data.&lt;br /&gt;
&lt;br /&gt;
The various crawlers provide streams to the &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt;. From these streams, the DataLoaders can reconstruct data that was stored in files (either compressed or not), even if some files come from different sources. These streams effectively separate the machine world from the program world, because they hide the former to the latter. Therefore, parsing data from a new format only means creating a loader, and being able to read another kind of file means creating a &amp;lt;code&amp;gt;DataProvider&amp;lt;/code&amp;gt;. Note that the DataLoaders usually serve as a facade for the higher layers of the program.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
&lt;br /&gt;
=== Data providers (&amp;lt;code&amp;gt;DataProvidersManager&amp;lt;/code&amp;gt;) ===&lt;br /&gt;
&lt;br /&gt;
==== Default provider ====&lt;br /&gt;
The data management system can use a system-wide property, &amp;lt;code&amp;gt;orekit.data.path&amp;lt;/code&amp;gt;, as an entry point for default data. This default data must be file-based (either a file system entry point or a java resource) and either a directory or a zip/jar file.&lt;br /&gt;
Setting a default provider is not mandatory, and must be done explicitly by :&lt;br /&gt;
&lt;br /&gt;
* setting a value to &amp;lt;code&amp;gt;orekit.data.path&amp;lt;/code&amp;gt;,&lt;br /&gt;
* calling &amp;lt;code&amp;gt;addDefaultProviders&amp;lt;/code&amp;gt; method on the data provider manager,&lt;br /&gt;
* calling &amp;lt;code&amp;gt;addProvider(DataProvider)&amp;lt;/code&amp;gt; method to add a provider.&lt;br /&gt;
&lt;br /&gt;
==== Using the data management system ====&lt;br /&gt;
The data management system main operation is through the &amp;lt;code&amp;gt;feed&amp;lt;/code&amp;gt; method. This method takes a &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt;, and a regexp string matching the name of files the &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt; is able to process. In this method call :&lt;br /&gt;
&lt;br /&gt;
* the &amp;lt;code&amp;gt;DataProviders&amp;lt;/code&amp;gt; list is traversed in the priority order.&lt;br /&gt;
* the first &amp;lt;code&amp;gt;DataProvider&amp;lt;/code&amp;gt; providing a file matching the regexp is the one (and only) used to feed the &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== File formats ===&lt;br /&gt;
Patrius can read a variety of files:&lt;br /&gt;
* &#039;&#039;&#039;Static potential files&#039;&#039;&#039;&lt;br /&gt;
These files contains static potential coefficients up to a certain order and degree and are used to compute Earth (or any other body) static potential perturbation.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Variable potential files&#039;&#039;&#039;&lt;br /&gt;
Theses files contains variable potential coefficients up to a certain order and degree and are used to compute Earth (or any other body) variable potential perturbation.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Geomagnetic coefficients files&#039;&#039;&#039;&lt;br /&gt;
These files contains geomagnetic coefficients and are used to compute Earth (or any other body) geomagnetic field.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Ionospheric coefficients files&#039;&#039;&#039;&lt;br /&gt;
These files contains ionospheric data and are used to compute Earth ionospheric correction.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Solar activity files&#039;&#039;&#039;&lt;br /&gt;
These files contains solar flux and geomagnetic coefficients are used to get solar activity in order to compute drag perturbation.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Earth Orientation Parameters files&#039;&#039;&#039;&lt;br /&gt;
These files contains earth orientation parameters (polar motion, LOD, etc.) used in frames transformation.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;TAI-UTC shift files&#039;&#039;&#039;&lt;br /&gt;
These files contains TAI-TUC shift.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Orbital data files&#039;&#039;&#039;&lt;br /&gt;
These files are used to store orbital ephemeris&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Third body ephemeris files&#039;&#039;&#039;&lt;br /&gt;
These files are used to store third-body orbital ephemeris (Sun, Moon, etc.)&lt;br /&gt;
&lt;br /&gt;
The following sections describe all file readable in PATRIUS. When the file format is not described anywhere, a short description is detailed below the tab.&lt;br /&gt;
&lt;br /&gt;
==== Static Potential ====&lt;br /&gt;
&lt;br /&gt;
Static potential coefficients files contains potential coefficients up to a certain order and degree.&amp;lt;br&amp;gt;&lt;br /&gt;
Warning: at very high order and degree (&amp;gt; 100), some numerical quality issues can appear and results may be degraded.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GRGS&#039;&#039;&#039;&lt;br /&gt;
|Not direct link. This link provides GRGC potential coefficients [https://grace.obs-mip.fr/variable-models-grace-lageos/formats/spherical-harmonics-coefficients-format-grace/]&lt;br /&gt;
|[https://grace.obs-mip.fr/variable-models-grace-lageos/formats/]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/potential/GRGSFormatReader.html GRGSFormatReader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EGM&#039;&#039;&#039;&lt;br /&gt;
|[http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008/first_release.html]&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/potential/EGMFormatReader.html EGMFormatReader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ICGEM&#039;&#039;&#039;&lt;br /&gt;
|[http://icgem.gfz-potsdam.de/tom_longtime]&lt;br /&gt;
|[https://icgem.gfz.de/files/6defd9f87a64b16ec96bd657a74d0292ae3447cc7418da5104441102d8cb2b58.pdf]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/potential/ICGEMFormatReader.html ICGEMFormatReader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SHM&#039;&#039;&#039;&lt;br /&gt;
|Not provided (not used any more, replaced by ICGEM format)&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/potential/SHMFormatReader.html SHMFormatReader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EGM file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Degree of coefficients&amp;lt;br&amp;gt;&lt;br /&gt;
2:Order of coefficients&amp;lt;br&amp;gt;&lt;br /&gt;
3:Tesseral-sectorial cosinus coefficient&amp;lt;br&amp;gt;&lt;br /&gt;
4:Tesseral-sectorial sinus coefficient&amp;lt;br&amp;gt;&lt;br /&gt;
5:Sigma applied to the cosinus&amp;lt;br&amp;gt;&lt;br /&gt;
6:Sigma applied to the sinus&lt;br /&gt;
&lt;br /&gt;
[[File:EGM.png|center]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SHM file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
2:Degree of coefficients&amp;lt;br&amp;gt;&lt;br /&gt;
3:Order of coefficients&amp;lt;br&amp;gt;&lt;br /&gt;
4:Tesseral-sectorial cosinus coefficient&amp;lt;br&amp;gt;&lt;br /&gt;
5:Tesseral-sectorial sinus coefficient&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:SHM.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== Variable Potential ====&lt;br /&gt;
&lt;br /&gt;
Variable potential coefficients files contains potential coefficients up to a certain order and degree.&amp;lt;br&amp;gt;&lt;br /&gt;
Warning: at very high order and degree (&amp;gt; 100), some numerical quality issues can appear and results may be degraded.&lt;br /&gt;
&lt;br /&gt;
FES2004 is used to model oceanic tides.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GRGSRL02&#039;&#039;&#039;&lt;br /&gt;
|[https://grace.obs-mip.fr/variable-models-grace-lageos/formats/spherical-harmonics-coefficients-format-grace/]&lt;br /&gt;
|[https://grace.obs-mip.fr/variable-models-grace-lageos/formats/]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/variations/coefficients/GRGSRL02FormatReader.html GRGSRL02FormatReader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FES2004&#039;&#039;&#039;&lt;br /&gt;
|[https://www.aviso.altimetry.fr/en/data/products/auxiliary-products/global-tide-fes.html]&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/FES2004FormatReader.html FES2004FormatReader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FES2004 file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Doodson number&amp;lt;br&amp;gt;&lt;br /&gt;
2:Darwin number&amp;lt;br&amp;gt;&lt;br /&gt;
3:Degree of coefficients &amp;lt;br&amp;gt;&lt;br /&gt;
4:Order of coefficients&amp;lt;br&amp;gt;&lt;br /&gt;
5:Sinus coefficient positif&amp;lt;br&amp;gt;&lt;br /&gt;
6:Cosinus coefficient positif&amp;lt;br&amp;gt;&lt;br /&gt;
7:Sinus coefficient negatif&amp;lt;br&amp;gt;&lt;br /&gt;
8:Cosinus coefficient negatif&amp;lt;br&amp;gt;&lt;br /&gt;
9:Positif coefficient&amp;lt;br&amp;gt;&lt;br /&gt;
10:Epsilon positif&amp;lt;br&amp;gt;&lt;br /&gt;
11:Negatif coefficient&amp;lt;br&amp;gt;&lt;br /&gt;
12:Negatif epsilon&lt;br /&gt;
&lt;br /&gt;
[[File:FES2004.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== Geomagnetic coefficients ====&lt;br /&gt;
&lt;br /&gt;
Geomagnetic coefficients fiels contains geomagnetic coefficients up to a certain order and degree.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;COF&#039;&#039;&#039;&lt;br /&gt;
|IGCRF data: [https://www.ngdc.noaa.gov/IAGA/vmod/igrf.html] WMM data: [https://www.ngdc.noaa.gov/geomag/WMM/soft.shtml]&lt;br /&gt;
|See below &lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/models/earth/COFFileFormatReader.html COFFileFormatReader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;COF file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Degree of coefficients &amp;lt;br&amp;gt;&lt;br /&gt;
2:Order of coefficients&amp;lt;br&amp;gt;&lt;br /&gt;
3:g coefficient at position n,m&amp;lt;br&amp;gt;&lt;br /&gt;
4:h coefficient at position n,m&amp;lt;br&amp;gt;&lt;br /&gt;
5:dg coefficient at position n,m&amp;lt;br&amp;gt;&lt;br /&gt;
6:dh coefficient at position n,m&amp;lt;br&amp;gt;&lt;br /&gt;
g and h are the Gauss coefficients of main geomagnetic model (nT)&amp;lt;br&amp;gt;&lt;br /&gt;
dg and dh are the Gauss coefficients of secular geomagnetic model (nT/years)&lt;br /&gt;
&lt;br /&gt;
[[File:COF.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== Ionospheric coefficients ====&lt;br /&gt;
&lt;br /&gt;
Ionospheric coefficients files contains ionospheric coefficient to model the state of the ionosphere.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CCIR12&#039;&#039;&#039;&lt;br /&gt;
|N/A&lt;br /&gt;
|See below&lt;br /&gt;
|[&amp;lt;nowiki/&amp;gt;{{JavaDoc4.17}}/fr/cnes/sirius/patrius/signalpropagation/ionosphere/R12Loader.html R12Loader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USK(NEWUSK)&#039;&#039;&#039;&lt;br /&gt;
|N/A&lt;br /&gt;
|See below&lt;br /&gt;
|[&amp;lt;nowiki/&amp;gt;{{JavaDoc4.17}}/fr/cnes/sirius/patrius/signalpropagation/ionosphere/USKLoader.html USKLoader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CCIR12 file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Year &amp;lt;br&amp;gt;&lt;br /&gt;
2:Month&amp;lt;br&amp;gt;&lt;br /&gt;
3:Unused&amp;lt;br&amp;gt;&lt;br /&gt;
4:Midval&amp;lt;br&amp;gt;&lt;br /&gt;
5:Unused&amp;lt;br&amp;gt;&lt;br /&gt;
6:Midday&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CCIR12.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USK file format&#039;&#039;&#039; (&#039;&#039;Line text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[File:NEWUSK.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== Solar activity ====&lt;br /&gt;
&lt;br /&gt;
Solar activity contains solar flux and geomagnetic coefficients for a given timespan. ACSOL and NOAA files usually provide data for several years.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ACSOL&#039;&#039;&#039;&lt;br /&gt;
|N/A&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/ACSOLFormatReader.html ACSOLFormatReader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NOAA&#039;&#039;&#039;&lt;br /&gt;
|N/A&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/NOAAFormatReader.html NOAAFormatReader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACSOL file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Julian day since 1950&amp;lt;br&amp;gt;&lt;br /&gt;
2:Seconds of the day (UTC)&amp;lt;br&amp;gt;&lt;br /&gt;
3:Flux at JD + seconds&amp;lt;br&amp;gt;&lt;br /&gt;
4-11 are the three-hours AP of the intervals &lt;br /&gt;
&lt;br /&gt;
[[File:ACSOL.png|center]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOAA file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Day&amp;lt;br&amp;gt;&lt;br /&gt;
2:Flux at the day&amp;lt;br&amp;gt;&lt;br /&gt;
3:The background flux &amp;lt;br&amp;gt;&lt;br /&gt;
4-11:the three-hours AP of the intervals &amp;lt;br&amp;gt;&lt;br /&gt;
12:Year&amp;lt;br&amp;gt;&lt;br /&gt;
13:Unused character flag&lt;br /&gt;
&lt;br /&gt;
==== Pole data ====&lt;br /&gt;
&lt;br /&gt;
These files contains earth orientation parameters (polar motion, LOD, etc.) used in frames transformation.&amp;lt;br&amp;gt;&lt;br /&gt;
These data are usually valid of a timespan of several days/months, although there is no theoretical limit.&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;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Bulletin B&#039;&#039;&#039;&lt;br /&gt;
|[http://hpiers.obspm.fr/eoppc/bul/bulb_new/]&lt;br /&gt;
|[https://datacenter.iers.org/productMetadata.php?id=207]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/frames/configuration/eop/BulletinBFilesLoader.html BulletinBFilesLoader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EOP 05 C04&#039;&#039;&#039;&lt;br /&gt;
|[http://hpiers.obspm.fr/iers/eop/eopc04_05/]&lt;br /&gt;
|See below&lt;br /&gt;
|[&amp;lt;nowiki/&amp;gt;{{JavaDoc4.17}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOPC04FilesLoader.html EOPC04FilesLoader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Datas &amp;quot;Rapid and Prediction&amp;quot; (TXT)&#039;&#039;&#039;&lt;br /&gt;
|[http://maia.usno.navy.mil/ser7]&lt;br /&gt;
|[http://maia.usno.navy.mil/ser7/readme.finals]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/frames/configuration/eop/RapidDataAndPredictionColumnsLoader.html RapidDataAndPredictionColumnsLoader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Datas &amp;quot;Rapid and Prediction&amp;quot; (XML)&#039;&#039;&#039;&lt;br /&gt;
|[http://www.iers.org/IERS/EN/DataProducts/EarthOrientationData/eop.html]&lt;br /&gt;
|Same datas than the column file but write in the xml format&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/frames/configuration/eop/RapidDataAndPredictionXMLLoader.html RapidDataAndPredictionXMLLoader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EOP 05 C04 files format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Date at 0h(UTC)&amp;lt;br&amp;gt;&lt;br /&gt;
2:Modified Julian Day&amp;lt;br&amp;gt;&lt;br /&gt;
3:x(&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
4:y(&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
5:UT1-UTC(s)&amp;lt;br&amp;gt;&lt;br /&gt;
6:LOD(s)&amp;lt;br&amp;gt;&lt;br /&gt;
7:DPsi(&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
8:DEps(&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
9:x error (&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
10:y error (&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
11:UT1-UTC error (s)&amp;lt;br&amp;gt;&lt;br /&gt;
12:LOD error(s)&amp;lt;br&amp;gt;&lt;br /&gt;
13:Dpsi error(&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
14:DEpsilon error(&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
x and y are the coordinales of the Celestial Ephemeris Pole.&amp;lt;br&amp;gt;&lt;br /&gt;
UT1: Universal time, the time of the earth clock&amp;lt;br&amp;gt;&lt;br /&gt;
LOD: Length Of Day is the excess of revolution time&lt;br /&gt;
&lt;br /&gt;
[[File:EOP08C04.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== TAI-UTC shift====&lt;br /&gt;
&lt;br /&gt;
These files contains TAI-TUC shift. Official data contains shift since the beginning of space era (1961).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gap TAI-UTC&#039;&#039;&#039;&lt;br /&gt;
|[https://hpiers.obspm.fr/eop-pc/index.php?index=TAI-UTC_tab&amp;amp;lang=en]&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/time/UTCTAIHistoryFilesLoader.html UTCTAIHistoryFilesLoader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TAI-UTC file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Begining date-Ending date&amp;lt;br&amp;gt;&lt;br /&gt;
2:Difference TAI-UTC between the begining date and the ending date&lt;br /&gt;
&lt;br /&gt;
[[File:TAI-TUC.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== Orbital data ====&lt;br /&gt;
&lt;br /&gt;
These files are used to store orbital ephemeris.&amp;lt;br&amp;gt;&lt;br /&gt;
TLE provides orbit at one date. Ephemeris is then retrieved thanks to SGP4/SDP4 propagation model.&amp;lt;br&amp;gt;&lt;br /&gt;
SP3 files provide orbit over an extended time span (ex: 1 day).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TLE&#039;&#039;&#039;&lt;br /&gt;
|Celestrack or others providers&lt;br /&gt;
|[https://ensatellite.com/tle/]&lt;br /&gt;
[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/analytical/tle/TLESeries.html TLESeries]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SP3&#039;&#039;&#039;&lt;br /&gt;
|GPS and GLONASS only [https://gssc.esa.int/portal/?vuePage=1&amp;amp;size=20&amp;amp;mode=map&amp;amp;sortOption=recent&amp;amp;resource_format=SP3]&lt;br /&gt;
|[https://files.igs.org/pub/data/format/sp3c.txt]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/files/sp3/SP3File.html SP3File]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: * SP3 files can be written by anyone. They are however mainly used ton provide GPS and GLONASS ephemeris.&lt;br /&gt;
&lt;br /&gt;
Note2: * If the accuracy is not present in the SP3 file, a value of 0 automatically given. This allows the parsing of the SP3 to continue while giving the user the information that the accuracy field was not read (0 is an impossible value since the accuracy is given as 2^n). &lt;br /&gt;
&lt;br /&gt;
==== Third body ephemeris ====&lt;br /&gt;
&lt;br /&gt;
Third body ephemeris files contains ephemeris for third bodies (Moon, Sun, Jupiter) over an extended time span (ex: 1 or several days).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;JPL&#039;&#039;&#039;&lt;br /&gt;
|[https://ssd.jpl.nasa.gov/ephem.html]&lt;br /&gt;
|[https://ssd.jpl.nasa.gov/planets/eph_export.html]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/bodies/JPLCelestialBodyLoader.html JPLCelestialBodyLoader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
The data package includes the following interfaces :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data&#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;DataLoader&#039;&#039;&#039;&lt;br /&gt;
|Interface for loading data files from DataProvider data providers.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/DataLoader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DataProvider&#039;&#039;&#039;&lt;br /&gt;
|Interface for providing data files to DataLoader file loaders.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/DataProvider.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
The data package includes the following classes :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data&#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;DataProvidersManager&#039;&#039;&#039;&lt;br /&gt;
|This class is the single point of access for all data loading features.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/DataProvidersManager.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DirectoryCrawler&#039;&#039;&#039;&lt;br /&gt;
|This class handles data files recursively starting from a root directories.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/DirectoryCrawler.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NetworkCrawler&#039;&#039;&#039;&lt;br /&gt;
|This class handles a list of URLs pointing to data files or zip/jar on the net.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/NetworkCrawler.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ZipJarCrawler&#039;&#039;&#039;&lt;br /&gt;
|This class browses all entries in a zip/jar archive in filesystem or in classpath.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/ZipJarCrawler.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== [[File:lightBulb.png]] Tips &amp;amp;amp; Tricks ==&lt;br /&gt;
=== Strengths ===&lt;br /&gt;
&lt;br /&gt;
* Lightweight implementation. The providers never load data, they merely provide streams on demand to the loaders.&lt;br /&gt;
* Scalable for using data from several heterogeneous sources.&lt;br /&gt;
* Scalable for new data types : the user only needs to create a new &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt; implementation to use a new data type in this system.&lt;br /&gt;
&lt;br /&gt;
=== Weaknesses ===&lt;br /&gt;
&lt;br /&gt;
* The user must be aware the data loading overhead happens any time a &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt; is fed, so the user must manage its loaders so that they are fed only once.&lt;br /&gt;
* Several sources for the same type of data cannot be used, since only the last provider added is used to feed data to a loader - unless the user manages the providers list accordingly, knowing one can only add elements or reset the whole list.&lt;br /&gt;
* The regexp is the only way to match a data file and a &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt;.&lt;br /&gt;
* As of today, the data management system is a thread-hostile singleton : a multithreaded application shares the same providers list for all threads, and it may deadlock on a concurrent access!&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Force_models&amp;diff=4098</id>
		<title>User Manual 4.17 Force models</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Force_models&amp;diff=4098"/>
		<updated>2025-12-12T13:38:32Z</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 force models available in PATRIUS. Forces models can be added to Patrius Numerical propagator.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&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.17}}/fr/cnes/sirius/patrius/forces/package-summary.html Package fr.cnes.sirius.patrius.forces]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/drag/package-summary.html Package fr.cnes.sirius.patrius.forces.drag]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/package-summary.html Package fr.cnes.sirius.patrius.forces.gravity]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/forces/gravity/variations/coefficients/package-summary.html Package fr.cnes.sirius.patrius.forces.gravity.variations.coefficients]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/package-summary.html Package fr.cnes.sirius.patrius.forces.gravity.tides]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/radiation/package-summary.html Package fr.cnes.sirius.patrius.forces.radiation]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/radiation/package-summary.html Package fr.cnes.sirius.patrius.forces.radiation]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/package-summary.html Package fr.cnes.sirius.patrius.forces]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
&#039;&#039;&#039;Algorithms used&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The algorithms used for the tides (earth and ocean) are taken from the FORTRAN code in ZOOM- see Manuel algorithmique OBELIX below. The routines used as references are given hereunder :&lt;br /&gt;
* f_maroce.f90 &lt;br /&gt;
* fmf_ccadmt.f90&lt;br /&gt;
* obelixutil.f90&lt;br /&gt;
* mc_argfond.f90&lt;br /&gt;
&lt;br /&gt;
The algorithms used for the rediffused radiation pressure are taken from OBELIX library. The routines used as references are given hereunder :&lt;br /&gt;
* fpr_elements&lt;br /&gt;
* fai_daccdd&lt;br /&gt;
&lt;br /&gt;
The method used to compute the resulting acceleration is the same as that used in the [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/CunninghamAttractionModel.html Cunnigham attraction model].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Other Documents&#039;&#039;&#039;&lt;br /&gt;
* Manuel algorithmique OBELIX (Obelix-NT-12-1, version 4 révision 0 du 30/03/2012)&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
* Cunningham; Leland E., &#039;&#039;On the computation of the spherical harmonic terms needed during the numerical integration of the orbital motion of an artificial satellite (Celestial Mechanics 2)&#039;&#039;, Lockheed Missiles and Space Company, Sunnyvale and Astronomy Department University of California, Berkeley), 1970. Available [http://adsabs.harvard.edu/full/1970CeMec...2..207C here].&lt;br /&gt;
* Drozyner; A., &#039;&#039;Recurrent calculation of gravitational acceleration of a satellite&#039;&#039;, Acta Astronomica, vol. 27, no. 1, 1977, p. 15-22. Available [http://adsabs.harvard.edu/full/1977AcA....27...15D here].&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
==== Parameterizable models====&lt;br /&gt;
Parameterizable models are supported. &amp;lt;br&amp;gt;&lt;br /&gt;
A parameter of a model can be define as Parameter (given its descriptor and value), a constant function, a linear function, a Nth order polynomial function, a piecewise function or an intervals function.&lt;br /&gt;
&lt;br /&gt;
All parameters are handled in a the [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/parameter/Parameterizable.html Parameterizable] class.&amp;lt;br&amp;gt;&lt;br /&gt;
In case of a using a function for a model&#039;s paramater (Fx), the [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/parameter/Parameter.html Parameter] defined are automatically stored in the super class [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/parameter/Parameterizable.html Parameterizable]. &amp;lt;br&amp;gt;&lt;br /&gt;
Note that in this case, it is not Fx that is stored but ax and bx (with Fx = ax*t + bx).&lt;br /&gt;
&lt;br /&gt;
==== Tides ====&lt;br /&gt;
&lt;br /&gt;
The architecture of the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.tides&amp;lt;/code&amp;gt; package is given hereunder. The classes [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/OceanTides.html OceanTides] and [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/TerrestrialTides.html TerrestrialTides] extend [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/AbstractTides.html AbstractTides].&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:Tides.png|center]]&lt;br /&gt;
&lt;br /&gt;
The architecture of the &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.gravity.tides.coefficients&amp;lt;/code&amp;gt; package is given hereunder. The user must use the [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsFactory.html OceanTidesCoefficientsFactory class] to get an instance of the OceanTidesCoefficientsProvider interface, and pass it as an argument to the constructor of the [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/OceanTidesDataProvider.html OceanTidesDataProvider class].&lt;br /&gt;
&lt;br /&gt;
[[File:TidesCoeffs2.png|center]]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Available force models ===&lt;br /&gt;
The force models implemented are (by using DirectBodyAttraction as a wrapper for these gravity models) :&lt;br /&gt;
* Central gravity force (note that the harmonic gravity models have the central term contribution activated by default; it can be deactivated by means of the setCentralTermContribution(boolean) method of the AbstractHarmonicGravityModel abstract class) :&lt;br /&gt;
** Normalized attraction model : Balmino&lt;br /&gt;
** Unnormalized attraction models : Cunningham and Droziner&lt;br /&gt;
** Model defined by a grid with interpolated values: GridAttractionModel&lt;br /&gt;
* Third body gravity force (including harmonics)&lt;br /&gt;
* Atmospheric drag&lt;br /&gt;
** Based on DTM2000, DTM2012, JB2006, US76 and MSIS2000 atmosphere models and solar activity data&lt;br /&gt;
* Solar radiation pressure force&lt;br /&gt;
* Terrestrial tides: the earth tide is the deformation of the solid earth caused by the gravitational attraction of the Sun and moon. The standard used for constants and Love numbers is IERS 2003. The potential of the earth deformation is composed of 3 terms:&lt;br /&gt;
** the potential of earth tide: the potential is computed for degree 2 and takes into account complex Love numbers for long period (k20), diurnal (k21) and semi-diurnal (k22) terms. The potential for degree 3 is optional.&lt;br /&gt;
** the frequency correction of the Love numbers is also optional. It is applied on diurnal Love number (k21) [see Wahr and Zhu theory].&lt;br /&gt;
** the ellipticity correction is also optional. The ellipticity effect involves corrections on terms of degree 4 [see Wahr theory, 1981]&lt;br /&gt;
* Ocean Tides&lt;br /&gt;
* Solar pressure rediffused by the earth (albedo pressure and infrared emissivity pressure)&lt;br /&gt;
* Empirical forces&lt;br /&gt;
&lt;br /&gt;
* Relativistic effects :&lt;br /&gt;
** Schwarzschild effect : the most important effect&lt;br /&gt;
** Coriolis effect (or geodetic precession)&lt;br /&gt;
** Lense-Thirring effect : due to the rotation of central body&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The acceleration derivatives implemented 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;| Force model&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| wrt Position&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| wrt Velocity&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot;| wrt additional parameters&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot;|&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Parameter&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| ParamDiffFunction&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Parameter or ParamDiffFunction from a model&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Cunningham attraction&#039;&#039;&#039;&lt;br /&gt;
|yes&lt;br /&gt;
|no&lt;br /&gt;
|k&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Balmino attraction&#039;&#039;&#039;&lt;br /&gt;
|yes&lt;br /&gt;
|no&lt;br /&gt;
|k&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Droziner attraction&#039;&#039;&#039;&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|k&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Grid attraction model&#039;&#039;&#039;&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|k&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Newtonian attraction&#039;&#039;&#039;&lt;br /&gt;
|yes&lt;br /&gt;
|no&lt;br /&gt;
|k, MU&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Variable potential model&#039;&#039;&#039;&lt;br /&gt;
|yes&lt;br /&gt;
|no&lt;br /&gt;
|k&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Third body attraction&#039;&#039;&#039;&lt;br /&gt;
|yes&lt;br /&gt;
|no&lt;br /&gt;
|k&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Drag force&#039;&#039;&#039;&lt;br /&gt;
|yes&lt;br /&gt;
|yes&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|DragSensitive(AeroModel: Cx, Cn, Ct)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Direct solar radiation&#039;&#039;&#039;&lt;br /&gt;
|yes&lt;br /&gt;
|NA(null derivatives)&lt;br /&gt;
|Reference flux&lt;br /&gt;
|no&lt;br /&gt;
|RadiationSensitive(DirectRadiativeModel : k0, ka, ks, kd)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Rediffused solar radiation&#039;&#039;&#039;&lt;br /&gt;
|yes&lt;br /&gt;
|NA(null derivatives)&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|RediffusedRadiationSensitive(RediffusedRadiativeModel : k0Ir, k0Al, ka, ks, kd)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Empirical force&#039;&#039;&#039;&lt;br /&gt;
|NA(null derivatives)&lt;br /&gt;
|NA(null derivatives)&lt;br /&gt;
|no&lt;br /&gt;
|AX_COEFFICIENT, AY_COEFFICIENT, AZ_COEFFICIENT, BX_COEFFICIENT, BY_COEFFICIENT, BZ_COEFFICIENT, CX_COEFFICIENT, CY_COEFFICIENT, CZ_COEFFICIENT&lt;br /&gt;
|no&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Ocean tides&#039;&#039;&#039;&lt;br /&gt;
|yes&lt;br /&gt;
|NA(null derivatives)&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Terrestrial tides&#039;&#039;&#039;&lt;br /&gt;
|yes&lt;br /&gt;
|NA(null derivatives)&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Schwarzschild&#039;&#039;&#039;&lt;br /&gt;
|yes&lt;br /&gt;
|yes&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Coriolis&#039;&#039;&#039;&lt;br /&gt;
|NA(null derivatives)&lt;br /&gt;
|yes&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Lense-Thirring&#039;&#039;&#039;&lt;br /&gt;
|yes&lt;br /&gt;
|yes&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|no&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note : The partial derivatives of the Balmino acceleration model are that of the Cunningham attraction model. They are thus limited in degree and order (sum should be lower or equal than approx. 160).&lt;br /&gt;
&lt;br /&gt;
=== Gravity potential ===&lt;br /&gt;
==== Static potential models ====&lt;br /&gt;
&lt;br /&gt;
The data is read through the Orekit &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt; infrastructure; it provides several ways to load gravitational data. Please see the [[User Manual 3.4.1 Data management system|Data Management System section]] for more information.&lt;br /&gt;
&lt;br /&gt;
The user access point is the &amp;lt;code&amp;gt;GravityFieldFactory&amp;lt;/code&amp;gt; which automatically detects available files and uses the adequate loader. If no file is specified by the user, this factory uses the first available file.&lt;br /&gt;
&lt;br /&gt;
The normalized attraction model is more accurate that the unnormalized attraction models in that it allows computing gravity fields to a much higher degree / order.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039; : using a 0x0 Earth potential model (Cunningham, Drozyner, Balmino, etc.) is equivalent to a simple Newtonian attraction. However computation times will be much slower since this case is not particularized and hence conversion from body frame (often ITRF) to integration frame is necessary.&lt;br /&gt;
&lt;br /&gt;
==== Variable potential models ====&lt;br /&gt;
&lt;br /&gt;
The data is read through the Orekit &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt; infrastructure; it provides several ways to load gravitational data. Please see the [[User Manual 4.1 Data management system|Data Management System section]] for more information.&lt;br /&gt;
&lt;br /&gt;
The user access point is the &amp;lt;code&amp;gt;VariableGravityFieldFactory&amp;lt;/code&amp;gt; which automatically detects available files and uses the adequate loader. If no file is specified by the user, this factory uses the first available file.&lt;br /&gt;
&lt;br /&gt;
Regarding the corrections computation, the user has three choices :&lt;br /&gt;
* not to take any corrections into account, using the first constructor (VariablePotentialAttractionModel(Frame, VariablePotentialCoefficientsProvider, int, int))&lt;br /&gt;
* compute corrections at instanciation only (see code snippet hereunder),&lt;br /&gt;
* compute corrections every time.&lt;br /&gt;
&lt;br /&gt;
The user specifies, with the computeAtEachCall boolean set to true, if corrections are to be recomputed each time.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Get the variable potential data provider&lt;br /&gt;
final VariablePotentialCoefficientsProvider provider = VariableGravityFieldFactory.getVariablePotentialProvider();&lt;br /&gt;
// Variable potential force model&lt;br /&gt;
final int degree = 80;&lt;br /&gt;
final int order = 80;&lt;br /&gt;
final int degreeOptional = 50;&lt;br /&gt;
final int orderOptional = 50;&lt;br /&gt;
final boolean computeAtEachCall = true;&lt;br /&gt;
final VariablePotentialAttractionModel grav = new VariablePotentialAttractionModel(FramesFactory.getITRF(),&lt;br /&gt;
    provider, degree, order, degreeOptional, orderOptional, computeAtEachCall);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;grav&amp;lt;/code&amp;gt; force model can then be used with the numerical propagator.&lt;br /&gt;
&lt;br /&gt;
==== Static grid potential model ====&lt;br /&gt;
&lt;br /&gt;
For small bodies where body cannot be considered as spherical with uniform gravity field, a class &amp;lt;code&amp;gt;GridAttractionModel&amp;lt;/code&amp;gt; can be used. This class loads a static gravity field and then interpolate potential and attraction data at user required position.&lt;br /&gt;
This class requires at construction:&lt;br /&gt;
* A &amp;lt;code&amp;gt;GridAttractionProvider&amp;lt;/code&amp;gt;: this is a generic provider providing potential and acceleration at grid points. Currently two implements are available: &amp;lt;code&amp;gt;CartesianGridAttractionLoader&amp;lt;/code&amp;gt; (for cartesian grids) and &amp;lt;code&amp;gt;SphericalGridAttractionLoader&amp;lt;/code&amp;gt; (for spherical grids).&lt;br /&gt;
* An 3D interpolator &amp;lt;code&amp;gt;TrivariateGridInterpolator&amp;lt;/code&amp;gt;. Currently two interpolators are available: linear (&amp;lt;code&amp;gt;TriLinearIntervalsInterpolator&amp;lt;/code&amp;gt;) and Spline (&amp;lt;code&amp;gt;TricubicSplineInterpolator&amp;lt;/code&amp;gt;).&lt;br /&gt;
* A back-up attraction model &amp;lt;code&amp;gt;ForceModel&amp;lt;/code&amp;gt; which will be used if requested position is out of grid boundaries (for instance Cunhingham, Droziner or event Newtonian model).&lt;br /&gt;
* The body Frame&lt;br /&gt;
This model then works like any other force model: it can be used in a numerical propagator.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: when using this model, Newtonian attraction included in numerical propagator should be disabled! In order to do so, call the method &amp;lt;code&amp;gt;Numericalpropagator.disableNewtonianAttraction()&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tides ===&lt;br /&gt;
&lt;br /&gt;
In the very same way, the user access point to Ocean Tides Coefficients is the &amp;lt;code&amp;gt;OceanTidesCoefficientsFactory&amp;lt;/code&amp;gt; which automatically detects available files and uses the adequate loader. If no file is specified by the user, this factory uses the first available file. The loaded data can then be used by the &amp;lt;code&amp;gt;OceanTides&amp;lt;/code&amp;gt; model.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Directory containing the file fes2004_gr&lt;br /&gt;
final File tiDir = new File(&amp;quot;/my/data/gravity/tides&amp;quot;);&lt;br /&gt;
// The directory is given to the data loader&lt;br /&gt;
DataProvidersManager.getInstance().addProvider(new DirectoryCrawler(tiDir));&lt;br /&gt;
// The FES2004 file is registered in the OceanTidesCoefficientsFactory&lt;br /&gt;
OceanTidesCoefficientsFactory.addOceanTidesCoefficientsReader(new FES2004FormatReader(&amp;quot;fes2004_gr&amp;quot;));&lt;br /&gt;
// A provider for the FES2004 data is created&lt;br /&gt;
final OceanTidesCoefficientsProvider provider = OceanTidesCoefficientsFactory.getCoefficientsProvider();&lt;br /&gt;
// Get the C± ans S± coefficients and C± and ε± for a given Doodson number&lt;br /&gt;
final double doodson = 65.555;&lt;br /&gt;
final int order = 2;&lt;br /&gt;
final int degree = 1;&lt;br /&gt;
final double[] CS = provider.getCpmSpm(doodson, order, degree);&lt;br /&gt;
final double[] CE = provider.getCpmEpm(doodson, order, degree);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/OceanTides.html OceanTides] uses a [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/OceanTidesDataProvider.html OceanTidesDataProvider] which uses itself a [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/OceanTidesCoefficientsProvider.html OceanTidesCoefficientsProvider], such as the [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/FES2004FormatReader.html FES 2004 format reader class], and calls the &amp;lt;code&amp;gt;getCpmSpm(double, double, double)&amp;lt;/code&amp;gt; methods internally. When the user has created an instance of the [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/OceanTidesDataProvider.html OceanTidesDataProvider] class, he can pass it on to the constructor of [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/OceanTides.html OceanTides], like so :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final Frame earthFrame = FramesFactory.getITRF();&lt;br /&gt;
final double earthRadius = 6378136.;&lt;br /&gt;
final double mu = Constants.EIGEN5C_EARTH_MU;&lt;br /&gt;
final double density = 1025;&lt;br /&gt;
final int degree = 10;&lt;br /&gt;
final int order = 10;&lt;br /&gt;
final boolean ignoreSecondaryWaves = true;&lt;br /&gt;
&lt;br /&gt;
final OceanTidesCoefficientsProvider coefficientsProvider = OceanTidesCoefficientsFactory.getCoefficientsProvider();&lt;br /&gt;
final TidesStandard convention = TidesStandard.GINS2004;&lt;br /&gt;
final OceanTidesDataProvider dataProvider = new OceanTidesDataProvider(coefficientsProvider, convention);&lt;br /&gt;
&lt;br /&gt;
final OceanTides tides = new OceanTides(earthFrame, earthRadius, mu,&lt;br /&gt;
           density, degree, order, ignoreSecondaryWaves, dataProvider);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/TerrestrialTides.html TerrestrialTides] uses a [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/TerrestrialTidesDataProvider.html TerrestrialTidesDataProvider]. When the user has created an instance of the [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/TerrestrialTidesDataProvider.html TerrestrialTidesDataProvider] class, he can pass it on to the constructor of [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/OceanTides.html OceanTides], like so :&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final List&amp;lt;CelestialBody&amp;gt; bodies = new ArrayList&amp;lt;CelestialBody&amp;gt;();&lt;br /&gt;
bodies.add(CelestialBodyFactory.getSun());&lt;br /&gt;
bodies.add(CelestialBodyFactory.getMoon());&lt;br /&gt;
final TerrestrialTides terrestrialTides = new TerrestrialTides(earthFrame, earthRadius, mu, bodies, false, false, false, new TerrestrialTidesDataProvider());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Drag force ===&lt;br /&gt;
Before implementing the drag force, one has to define a vehicle with aerodynamic properties. To do so, it is advised to consult the page about [SPC_FORCES_Home assembly models for force models]. Given an assembly with the right aerodynamic properties, the user can create an instance of [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/assembly/models/AeroModel.html AeroModel] or [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/assembly/models/DragLiftModel.html DragLiftModel], and use it to create an instance of DragForce.&lt;br /&gt;
&lt;br /&gt;
The implementation of the DragForce class allows at construction to take in account a multiplicative coefficient on the drag acceleration.&lt;br /&gt;
Let k be this coefficient, then the attribute k instance of IParamDiffFunction can be instantiated in the following constructors :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Simple constructor with multiplicative factor k = 1.0&lt;br /&gt;
public DragForce(final Atmosphere atmosphere, final DragSensitive spacecraft)&lt;br /&gt;
&lt;br /&gt;
// Constructor for k being a double&lt;br /&gt;
public DragForce(final double k, final Atmosphere atmosphere, final DragSensitive spacecraft)&lt;br /&gt;
&lt;br /&gt;
// Constructor for k being a Parameter&lt;br /&gt;
public DragForce(final Parameter k, final Atmosphere atmosphere, final DragSensitive spacecraft)&lt;br /&gt;
&lt;br /&gt;
// General constructor for k being an IParamDiffFunction&lt;br /&gt;
// This constructor is called by the others&lt;br /&gt;
public DragForce(final IParamDiffFunction k, final Atmosphere atmosphere, final DragSensitive spacecraft)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the main constructor, the derivable parameters of function k are stored in the jacobians parameters list the via the method &lt;br /&gt;
&amp;lt;code&amp;gt; addJacobiansParameter &amp;lt;/code&amp;gt;, the other in the parameters list via &amp;lt;code&amp;gt; addParameter &amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Partial derivatives ====&lt;br /&gt;
&lt;br /&gt;
The drag force model allows the user to compute the partial derivatives of the atmospheric drag acceleration, only for a spherical spacecraft; the available derivatives are the following:&lt;br /&gt;
&lt;br /&gt;
* with respect to the spacecraft position in the inertial frame;&lt;br /&gt;
* with respect to the spacecraft velocity in the inertial frame;&lt;br /&gt;
* with respect to the drag coefficient (Cx);&lt;br /&gt;
* with respect to parameters of function k which are derivable.&lt;br /&gt;
&lt;br /&gt;
===== Partial derivatives with respect to spacecraft position =====&lt;br /&gt;
&lt;br /&gt;
The derivatives with respect to position require the derivative of the atmospheric density with respect to the altitude &amp;lt;math&amp;gt;\frac{\partial \rho }{\partial h}&amp;lt;/math&amp;gt;, which is computed by finite differences by a method of altitude variation. We present here the case where the DragSensitive used is an instance of &amp;lt;code&amp;gt;AeroModel&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
They are given by MontenBruck, &amp;quot;Satellite Orbit&amp;quot;, according the following equation :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\partial^{2} {r}} {\partial {r}} = - \frac{1}{2} C_{d} \frac{S}{m} ||v_r|| v_r \frac{\partial \rho }{\partial r}- \frac{\partial^{2} {r}} {\partial {v}} X(\omega_{Earth})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;lt;math&amp;gt;v_r&amp;lt;/math&amp;gt; is the relative velocity such that &amp;lt;math&amp;gt;v_r = v- \omega_{Earth} \times r&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
Moreover, we have :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;X(\omega) = \left( \begin{array}{ccc}&lt;br /&gt;
0 &amp;amp;-\omega_{z} &amp;amp; \omega_{y} \\&lt;br /&gt;
\omega_{z} &amp;amp; 0 &amp;amp;-\omega_{x} \\&lt;br /&gt;
-\omega_{y} &amp;amp; \omega_{x} &amp;amp; 0 \end{array} \right)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\frac{\partial \rho }{\partial r} = (\frac{\partial \rho}{\partial x}, \frac{\partial \rho}{\partial y}, \frac{\partial \rho}{\partial z})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The density partial derivatives are computed by considering the variation of density while the altitude varies :&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\delta r = r (1 + \frac{step_{alt}} {||r||} )&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\delta \rho = \frac{\rho(r + \delta r)- \rho(r)}{step_{alt}}&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\frac{\partial \rho }{\partial r} = (\cos(long) \cos(lat) \delta \rho,\sin(long) \cos(lat) \delta \rho,\sin(lat) \delta \rho)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where &amp;lt;math&amp;gt;step_{alt}&amp;lt;/math&amp;gt; can be chosen at construction of the &amp;lt;code&amp;gt;AeroModel&amp;lt;/code&amp;gt; (equal to 10m by default).&lt;br /&gt;
&lt;br /&gt;
===== Partial derivatives with respect to spacecraft velocity =====&lt;br /&gt;
&lt;br /&gt;
The partial derivatives of the drag force with respect to the spacecraft velocity in the inertial frame are computed using the exact equations.&lt;br /&gt;
&lt;br /&gt;
===== Partial derivatives with respect to the drag coefficient (Cx) =====&lt;br /&gt;
&lt;br /&gt;
The partial derivatives of the drag force with respect to the drag coefficient are computed using the exact equations.&amp;lt;br&amp;gt;&lt;br /&gt;
Note that the ballistic coefficient for a spherical spacecraft is equal to &amp;lt;math&amp;gt;{B}_{c}=\frac{S {C}_{X}}{M}&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;S&amp;lt;/math&amp;gt; is the cross-sectional area of the sphere, &amp;lt;math&amp;gt;{C}_{X}&amp;lt;/math&amp;gt; is the drag coefficient and &amp;lt;math&amp;gt;M&amp;lt;/math&amp;gt; is the mass.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Partial derivatives with respect to k parameters =====&lt;br /&gt;
&lt;br /&gt;
The partial derivatives of the drag force with respect to k parameters are simply computed by multiplying the drag acceleration by the partial derivative value of k with respect to the considered parameter.&lt;br /&gt;
&lt;br /&gt;
=== Solar radiation pressure ===&lt;br /&gt;
Before implementing the solar radiation pressure or the rediffused solar radiation pressure, one has to define a vehicle with radiative properties. To do so, it is advised to consult the page about [SPC_FORCES_Home forces models using the assembly].&lt;br /&gt;
&lt;br /&gt;
==== Direct solar radiation pressure ====&lt;br /&gt;
&lt;br /&gt;
Direct solar radiation pressure is the force created by Sun photons impacting the spacecraft. The class is &amp;lt;code&amp;gt;SolarRadiationPressure&amp;lt;/code&amp;gt;.&lt;br /&gt;
It provides the following features:&lt;br /&gt;
* Any occulting body can be provided (Earth, Moon, etc.). Multiple occulting bodies can be added using method &amp;lt;code&amp;gt;addOccultingBody&amp;lt;/code&amp;gt;. By default, one occulting body is included at construction.&lt;br /&gt;
* Eclipses computation can be deactivated through method &amp;lt;code&amp;gt;setEclipsesComputation&amp;lt;/code&amp;gt;. By default eclipses computation are activated.&lt;br /&gt;
&lt;br /&gt;
Before implementing the solar radiation pressure (that takes into account Earth flattening), one has to define a vehicle with radiative properties. To do so, it is advised to consult the page which describes how to build and use [SPC_VEH_Home the Assembly] ([SPC_VBU_Home see also...]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet allows the user to create an instance of the ForceModel class that can be passed to the NumericalPropagator. This instance will calculate the SRP by computing penumbra and umbra events for a flattened Earth.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Constants&lt;br /&gt;
final double ae = 6.3781360000000000E+06;&lt;br /&gt;
final double f = 3.3528040724231161E-03;&lt;br /&gt;
&lt;br /&gt;
// ITRF frame&lt;br /&gt;
final Frame itrf = FramesFactory.getITRF();&lt;br /&gt;
&lt;br /&gt;
// Sun and Earth&lt;br /&gt;
final CelestialBody sun = CelestialBodyFactory.getSun();&lt;br /&gt;
final BodyShape earth = new OneAxisEllipsoid(ae, f, itrf, &amp;quot;earth&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
// Assembly definition&lt;br /&gt;
final AssemblyBuilder builder = new AssemblyBuilder();&lt;br /&gt;
final String mainPart = &amp;quot;satellite&amp;quot;;&lt;br /&gt;
builder.addMainPart(mainPart);&lt;br /&gt;
builder.addProperty(new RadiativeProperty(1, 0, 0), mainPart);&lt;br /&gt;
builder.addProperty(new MassProperty(mass), mainPart);&lt;br /&gt;
builder.addProperty(new RadiativeSphereProperty(1), mainPart);&lt;br /&gt;
&lt;br /&gt;
// The RadiationSensitive instance&lt;br /&gt;
final DirectRadiativeModel sc = new DirectRadiativeModel(builder.returnAssembly());&lt;br /&gt;
&lt;br /&gt;
// SRP&lt;br /&gt;
final SolarRadiationPressure srp = new SolarRadiationPressure(sun, earth, sc);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Rediffused solar radiation pressure ====&lt;br /&gt;
&lt;br /&gt;
Example for the rediffused solar radiation pressure implementation :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        // sun ephemerides&lt;br /&gt;
        CelestialBodyFactory.clearCelestialBodyLoaders();&lt;br /&gt;
        final JPLCelestialBodyLoader loader = new JPLCelestialBodyLoader(&amp;quot;unxp2000.405&amp;quot;,&lt;br /&gt;
                EphemerisType.SUN);&lt;br /&gt;
        final CelestialBody sun = loader.loadCelestialBody(CelestialBodyFactory.SUN);&lt;br /&gt;
        &lt;br /&gt;
        // emissivity model&lt;br /&gt;
        final IEmissivityModel modelE = new KnockeRiesModel();&lt;br /&gt;
&lt;br /&gt;
        // build the assembly&lt;br /&gt;
        final AssemblyBuilder builder = new AssemblyBuilder();&lt;br /&gt;
                                .&lt;br /&gt;
                                .&lt;br /&gt;
                                .&lt;br /&gt;
        final Assembly assembly = builder.returnAssembly();&lt;br /&gt;
        &lt;br /&gt;
        // RSRP model (albedo=true/false, ir=true/false, albedo global multiplicative factor=1, &lt;br /&gt;
        //infrared global multiplicative factor=1&lt;br /&gt;
        final RediffusedRadiativeModel RSRP = new RediffusedRadiativeModel(albedo, ir, 1, 1, assembly);&lt;br /&gt;
        &lt;br /&gt;
        // RSRP force, number of corona, number of meridian=10&lt;br /&gt;
        final RediffusedRadiationPressure f = new RediffusedRadiationPressure(sun, FramesFactory.getITRF(), &lt;br /&gt;
        10, 10, modelE, RSRP);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is also possible to compute these forces using assemblies, as seen in the [SPC_VEH_Home spacecraft chapter].&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: This model is valid only if the number of corona and the number of meridian are higher than (5,5).&lt;br /&gt;
&lt;br /&gt;
=== Relativistic Effects ===&lt;br /&gt;
&lt;br /&gt;
The computation of the relativistic effects is available in PATRIUS, in the force models. The model used to represent these effects is composed of 3 terms :&lt;br /&gt;
* the Schwarzschild term, which is the most important&lt;br /&gt;
* the Coriolis term, also known as the geodetic precession term&lt;br /&gt;
* the Lense-Thirring term, involving the rotation of the considered central body&lt;br /&gt;
&lt;br /&gt;
Three classes (one for each effect) are implemented in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.forces.relativistic&amp;lt;/code&amp;gt;. The SchwarzschildRelativisticEffect, CoriolisRelativisticEffect, and LenseThirringRelativisticEffect implement the &amp;lt;code&amp;gt;ForceModel&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GradientModel&amp;lt;/code&amp;gt; interfaces like all force models classes, and extend &amp;lt;code&amp;gt;JacobianParameterizable&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The following sections focus on each relativistic effect.&amp;lt;br&amp;gt;&lt;br /&gt;
Implementing the same &amp;lt;code&amp;gt;ForceModel&amp;lt;/code&amp;gt; interface, the computation of the acceleration is available via the method &amp;lt;code&amp;gt;computeAcceleration(final SpacecraftState s)&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Also, the computation of the acceleration partial derivatives with respect to state (position and velocity) is available via &amp;lt;code&amp;gt;addDAccDState(final SpacecraftState s, final double[][] dAccdPos, final double[][] dAccdVel)&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
The computation of partial derivatives with respect to parameters in &amp;lt;code&amp;gt;addDAccDParam(final SpacecraftState s, final Parameter param, final double[] dAccdParam)&amp;lt;/code&amp;gt; raise an exception since no parameter is supported by these force models.&lt;br /&gt;
&lt;br /&gt;
==== Schwarzschild effect ====&lt;br /&gt;
&lt;br /&gt;
An instance of the class SchwarzschildRelativisticEffect can be created using one of the following constructor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public SchwarzschildRelativisticEffect(final double mu, final boolean computePartialDerivativesPos, final boolean computePartialDerivativesVel)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public SchwarzschildRelativisticEffect(final double mu)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where mu is the central attraction coefficient, the boolean allowing the computation (or not) of the partial derivatives. In the second constructor, booelan are set to true.&lt;br /&gt;
&lt;br /&gt;
The acceleration due to the Schwarzschild effect is analytically computed using the formula:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\vec{a}_{sch} = \frac{\mu} {c^{2} r^{3}} ((4 \frac{{\mu}}{r}- v^{2}) \vec{r} + 4 (\vec{v}.\vec{r}) \vec{v})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where :&lt;br /&gt;
* &amp;lt;math&amp;gt;\vec{r}&amp;lt;/math&amp;gt; is the spacecraft position in an inertial centered central body frame&lt;br /&gt;
* &amp;lt;math&amp;gt;\vec{v}&amp;lt;/math&amp;gt; is the spacecraft velocity in an inertial centered central body frame&lt;br /&gt;
* &amp;lt;math&amp;gt;\mu&amp;lt;/math&amp;gt; is the attraction coefficient of the central body &amp;lt;math&amp;gt;(m^3 s^{-2})&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; the constant speed of light&lt;br /&gt;
&lt;br /&gt;
The partial derivatives with respect to state are computed with the following formulae :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;(\frac{\partial a_{i,sch}}{\partial r_j})_{1 \leq i,j \leq 3} = \frac{-3 r_j}{r^2} a_{i,sch} + \frac{\mu} {c^{2} r^{3}} (\frac{-4 \mu r_j}{r^3} r_i + (4 \frac{\mu}{r}- v^2) \delta_{ij} + 4 v_j v_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;(\frac{\partial a_{i,sch}}{\partial v_j})_{1 \leq i,j \leq 3} = \frac{\mu} {c^{2} r^{3}} (-2 v_j r_i + 4 r_j v_i + 4 (\vec{v}.\vec{r}) \delta_{ij})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\delta_{ij}&amp;lt;/math&amp;gt; being the Kronecker symbol.&lt;br /&gt;
&lt;br /&gt;
==== Coriolis effect ====&lt;br /&gt;
&lt;br /&gt;
An instance of the class CoriolisRelativisticEffect can be created using one of the following constructor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public CoriolisRelativisticEffect(final double muSun, final PVCoordinatesProvider sun, final boolean computePartialDerivativesVel)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public CoriolisRelativisticEffect(final double muSun, final PVCoordinatesProvider sun)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where  &lt;br /&gt;
* muSun is the central attraction coefficient of the Sun&lt;br /&gt;
* sun represent the sun PV coordinates in an inertial body centered frame&lt;br /&gt;
* axis is an orthogonal axis to the ecliptic plane of the body. &lt;br /&gt;
&lt;br /&gt;
In the second constructor, boolean is set to true.&lt;br /&gt;
&lt;br /&gt;
The acceleration due to the Coriolis effect is analytically computed using the formula:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\vec{a}_{cor} = 2 \vec{\Omega}_{cor} \times \vec{v}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
with :&lt;br /&gt;
* &amp;lt;math&amp;gt;\mu_{Sun}&amp;lt;/math&amp;gt; the attraction coefficient of the Sun&lt;br /&gt;
* &amp;lt;math&amp;gt;{r}_{body/Sun}&amp;lt;/math&amp;gt; the distance between Sun and the central body&lt;br /&gt;
* &amp;lt;math&amp;gt;\vec{u}_{z,ecl}&amp;lt;/math&amp;gt; the normal axis to the ecliptic plane of the body&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\vec{\Omega}_{cor} = \frac{-3}{2} \frac{\mu_{Sun}}{c^2 {r^3}_{Sun}} (\vec{v}_{Sun} \times \vec{r}_{Sun})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this formula for &amp;lt;math&amp;gt;\vec{\Omega}_{cor}&amp;lt;/math&amp;gt; is valid for a IERS2003 model.&lt;br /&gt;
&lt;br /&gt;
with :&lt;br /&gt;
* &amp;lt;math&amp;gt;\vec{r}_{Sun}&amp;lt;/math&amp;gt; the position of the Sun in an inertial body centered frame&lt;br /&gt;
* &amp;lt;math&amp;gt;\vec{v}_{Sun}&amp;lt;/math&amp;gt; the velocity of the Sun in an inertial body centered frame&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The partial derivatives with respect to velocity are computed with the following formula :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;(\frac{\partial a_{i,cor}}{\partial v_j})_{1 \leq i,j \leq 3} = 2 \left( \begin{array}{ccc}&lt;br /&gt;
0 &amp;amp;-\Omega_{cor,3} &amp;amp; \Omega_{cor,2} \\&lt;br /&gt;
\Omega_{cor,3} &amp;amp; 0 &amp;amp;-\Omega_{cor,1} \\&lt;br /&gt;
-\Omega_{cor,2} &amp;amp; \Omega_{cor,1} &amp;amp; 0 \end{array} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
if we denote &amp;lt;math&amp;gt;\vec{\Omega}_{cor} = (\Omega_{cor,1} \hspace{0.4cm} \Omega_{cor,2} \hspace{0.4cm} \Omega_{cor,3})^T&amp;lt;/math&amp;gt;. We show easily that the derivatives with respect to the position are null.&lt;br /&gt;
&lt;br /&gt;
==== Lense-Thirring effect ====&lt;br /&gt;
&lt;br /&gt;
An instance of the class LenseThirringRelativisticEffect can be created using one of the following constructor:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public LenseThirringRelativisticEffect(final double mu, final Frame frame, final boolean computePartialDerivativesPos, final boolean computePartialDerivativesVel)&amp;lt;/syntaxhighlight &amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;public LenseThirringRelativisticEffect(final double mu, final Frame frame)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where  &lt;br /&gt;
* mu is the central attraction coefficient&lt;br /&gt;
* frame defines pole of the central body&lt;br /&gt;
&lt;br /&gt;
In the second constructor, boolean are set to true.&lt;br /&gt;
&lt;br /&gt;
The acceleration due to the Lense-Thirring effect is analytically computed using the formula (IERS 20003 standard):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\vec{a}_{LT} = 2 \frac{\mu}{c^2 r^3} (\frac{3}{r^2} (\vec{r}.\vec{J}) \vec{r}- \vec{J}) \times \vec{v}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where :&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;\vec{J} = 9.8* 10^8 \hspace{0.4cm} \vec{u}_{z,Earth}&amp;lt;/math&amp;gt; is the Earth angular momentum.&lt;br /&gt;
&lt;br /&gt;
Finally, the partial derivatives are computed with the following formulae:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;(\frac{\partial a_{i,LT}}{\partial r_j})_{1 \leq i,j \leq 3} = \frac{-3 r_j}{r} a_{i,LT} + \frac{6 \mu} {c^2 r^5} ((J_j- \frac{2 r_j} {r^2} (\vec{r}.\vec{J})) (\vec{r} \times \vec{v})_i + (\vec{r}.\vec{J}) \frac{\partial}{\partial r_j} (\vec{r} \times \vec{v})_i)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;(\frac{\partial a_{i,LT}} {\partial v_j})_{1 \leq i,j \leq 3} = \left( \begin{array}{ccc}&lt;br /&gt;
0 &amp;amp;-\Omega_{LT,3} &amp;amp; \Omega_{LT,2} \\&lt;br /&gt;
\Omega_{LT,3} &amp;amp; 0 &amp;amp;-\Omega_{LT,1} \\&lt;br /&gt;
-\Omega_{LT,2} &amp;amp; \Omega_{LT,1} &amp;amp; 0 \end{array} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;(\frac{\partial}{\partial r_j} (\vec{r} \times \vec{v})_i)_{1 \leq i,j \leq 3} = \left( \begin{array}{ccc}&lt;br /&gt;
0 &amp;amp; v_3 &amp;amp;-v_2 \\&lt;br /&gt;
-v_3 &amp;amp; 0 &amp;amp;-v_1 \\&lt;br /&gt;
v_2 &amp;amp; v_1 &amp;amp; 0 \end{array} \right)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and &amp;lt;math&amp;gt;\Omega_{LT} = \frac{\mu}{c^2 r^3} ( \frac{3}{r^2}(\vec{r}.\vec{J}) \vec{r}- \vec{J})&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Thrust ===&lt;br /&gt;
Thrust models include:&lt;br /&gt;
* Continuous thrust maneuver&lt;br /&gt;
* Constant thrust error&lt;br /&gt;
&lt;br /&gt;
Note that impulse thrust are defined as events.&lt;br /&gt;
&lt;br /&gt;
==== Continuous thrust maneuver ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ContinuousThrustManeuver&amp;lt;/code&amp;gt; class implements the &amp;lt;code&amp;gt;ForceModel&amp;lt;/code&amp;gt; interface.&amp;lt;br&amp;gt;&lt;br /&gt;
Maneuvers can be defined providing values for thrust, ISP fuel tank using &amp;lt;code&amp;gt;TankProperty&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;PropulsiveProperty&amp;lt;/code&amp;gt; and the acceleration direction and its related frame:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;ContinuousThrustManeuver(final AbsoluteDate date, final double duration, final PropulsiveProperty engine,&lt;br /&gt;
final Vector3D direction, final MassProvider massProvider, final TankProperty tank)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More information on these properties are available at [SPC_FORCES_Prop4 TankProperty] and [SPC_FORCES_Prop5 PropulsiveProperty].&lt;br /&gt;
&lt;br /&gt;
==== Constant thrust error ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ConstantThrustError&amp;lt;/code&amp;gt; class implements the &amp;lt;code&amp;gt;ForceModel&amp;lt;/code&amp;gt; interface like the &amp;lt;code&amp;gt;ContinuousThrustManeuver&amp;lt;/code&amp;gt; class. The constant thrust error model is a fictitious force model used to compute the difference between the expected maneuver and the actual one. The user defines the three functions representing the three components (x, y, z) of the error as well as the thrust start and end (which can be defined either by its start date and its duration or using event detectors). These functions can depend on parameters. Thrust start and stop criterion can be defined in two different ways (see below).&lt;br /&gt;
Being a force model, an acceleration value (the error value) can be computed at any date. Moreover, the partial derivatives of the error at any date with respect to the parameters are available via the method &#039;&#039;&#039;computeDerivative(SpacecraftState, Parameter)&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Maneuver start and stop criterion can either be defined:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
◦ With a start date and a duration (former method)&amp;lt;br&amp;gt;&lt;br /&gt;
◦ With event detectors, first detector for starting the thrust, second detector for stopping the thrust. Action.STOP is required to trigger (start/stop) the thrust. Any other action will be discarded.&amp;lt;br&amp;gt;When using event detectors, pay attention to events that may occur several times. If you want the thrust to perform only once, the event detectors the event detectors have to be included in a nth occurrence detector or its &amp;lt;code&amp;gt;shouldBeRemoved()&amp;lt;/code&amp;gt; method have to return &amp;lt;code&amp;gt;true&amp;lt;/code&amp;gt;. Otherwise the thrust may be performed more than once: if a thrust starts at the perigee (using a perigee detector) and stops at the apogee (using an apogee detector), then the thrust will start at every perigee and stop at every apogee.&lt;br /&gt;
&lt;br /&gt;
=== Empirical force ===&lt;br /&gt;
The &amp;lt;code&amp;gt;EmpiricalForce&amp;lt;/code&amp;gt; class provides a model describing a generic empirical force; an empirical force is a &amp;quot;pseudo acceleration&amp;quot; with the same frequency of the spacecraft orbital frequency (or a multiple of this frequency). One or more instances of this force can be added to a propagator in order to represent a more complex empirical force model.&lt;br /&gt;
&lt;br /&gt;
Given a local frame (usually a LOF frame), and three vectors A, B and C defined in this frame, the acceleration in this local frame due to empirical force is the following:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\overrightarrow{a}_{local}=\overrightarrow{A}\cos(n\omega t) + \overrightarrow{B}\sin(n\omega t) + \overrightarrow{C}&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
n is the harmonic factor and &amp;lt;math&amp;gt;\omega&amp;lt;/math&amp;gt; is the orbital period. &amp;lt;br&amp;gt;&lt;br /&gt;
As &amp;lt;math&amp;gt;\omega&amp;lt;/math&amp;gt; is usually unknown, &amp;lt;math&amp;gt;\cos(n\omega t)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\sin(n\omega t)&amp;lt;/math&amp;gt; are computed from the orbital position of the spacecraft:&lt;br /&gt;
&lt;br /&gt;
* when the orbit is highly inclined, the orbital position can be computed from the position of the ascending node;&lt;br /&gt;
&lt;br /&gt;
* when the orbit is heliosyncronous, the orbital position can be computed from the projection of the Sun in the orbital plane;&lt;br /&gt;
&lt;br /&gt;
The user is free to choose a reference vector &amp;lt;math&amp;gt;\overrightarrow{S}&amp;lt;/math&amp;gt; that, once projected in the orbital plane, defines a reference direction used to compute the spacecraft position and then &amp;lt;math&amp;gt;\cos(n\omega t)&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;\sin(n\omega t)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Components of the vectors A, B and C can be defined as parameter and/or parameterizable functions : &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final int harmoCoef = 1;&lt;br /&gt;
EmpiricalForce f = new EmpiricalForce(harmoCoef, Vector3D.PLUS_K,&lt;br /&gt;
    new LinearFunction(new AbsoluteDate(), new Parameter(&amp;quot;ax&amp;quot;, 1), new Parameter(&amp;quot;bx&amp;quot;, 2)), &lt;br /&gt;
    new ConstantFunction(new Parameter(&amp;quot;ay&amp;quot;, 1)), &lt;br /&gt;
    new ConstantFunction(new Parameter(&amp;quot;az&amp;quot;, 0)),&lt;br /&gt;
    new LinearFunction(new AbsoluteDate(), new Parameter(&amp;quot;by&amp;quot;, 1), new Parameter(&amp;quot;b&amp;quot;, 2)), &lt;br /&gt;
    new ConstantFunction(new Parameter(&amp;quot;by&amp;quot;, 1)), &lt;br /&gt;
    new ConstantFunction(new Parameter(&amp;quot;bz&amp;quot;, 0)),&lt;br /&gt;
    new LinearFunction(new AbsoluteDate(), new Parameter(&amp;quot;bz&amp;quot;, 1), new Parameter(&amp;quot;b&amp;quot;, 2)), &lt;br /&gt;
    new ConstantFunction(new Parameter(&amp;quot;cy&amp;quot;, 1)) , &lt;br /&gt;
    new ConstantFunction(new Parameter(&amp;quot;cz&amp;quot;, 0)),&lt;br /&gt;
    LOFType.TNW);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
In this section, code samples are given in order to show user how to define some forces and how to correctly set the propagator by passing it these forces.&lt;br /&gt;
&lt;br /&gt;
=== Static potential models ===&lt;br /&gt;
&lt;br /&gt;
The following code sample shows how to set a gravity potential model (static) :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Directory containing the file grim5_C1.dat&lt;br /&gt;
final File potdir = new File(&amp;quot;/my/data/gravity/potential&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 GRGS file is registered in the GravityFieldFactory&lt;br /&gt;
GravityFieldFactory.addPotentialCoefficientsReader(new GRGSFormatReader(&amp;quot;grim5_C1.dat&amp;quot;, true));&lt;br /&gt;
// A provider for the GRGS data is created&lt;br /&gt;
final PotentialCoefficientsProvider provider = GravityFieldFactory.getPotentialProvider();&lt;br /&gt;
&lt;br /&gt;
// Get the tesserial-sectorial and zonal coefficients,&lt;br /&gt;
// degree 5, order 3, normalized&lt;br /&gt;
// normalized Cosine coefficients&lt;br /&gt;
final double[][] normalizedC = provider.getC(5, 3, true);&lt;br /&gt;
// normalized Sine coefficients&lt;br /&gt;
final double[][] normalizedS = provider.getS(5, 3, true);&lt;br /&gt;
&lt;br /&gt;
// degree 5, order 3, normalized&lt;br /&gt;
// unnormalized Cosine coefficients&lt;br /&gt;
final double[][] unnormalizedC = provider.getC(5, 3, false);&lt;br /&gt;
// unnormalized Sine coefficients&lt;br /&gt;
final double[][] unnormalizedS = provider.getS(5, 3, false);&lt;br /&gt;
&lt;br /&gt;
// Balmino model : normalized&lt;br /&gt;
final Frame itrfFrame = FramesFactory.getITRF();&lt;br /&gt;
final double mu = Constants.GRIM5C1_EARTH_MU;&lt;br /&gt;
final double ae = Constants.GRIM5C1_EARTH_EQUATORIAL_RADIUS;&lt;br /&gt;
&lt;br /&gt;
final BalminoAttractionModel balmino = new BalminoAttractionModel(itrfFrame, ae, mu, normalizedC, normalizedS);&lt;br /&gt;
&lt;br /&gt;
// Cunningham model : unnormalized- Same as DrozinerAttractionModel&lt;br /&gt;
final CunninghamAttractionModel Cunningham = new CunninghamAttractionModel(itrfFrame, ae, mu, normalizedC, normalizedS);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Drag force ===&lt;br /&gt;
&lt;br /&gt;
Hereunder the steps to define an instance of &amp;lt;code&amp;gt;DragForce&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;
// sun ephemerides&lt;br /&gt;
CelestialBodyFactory.clearCelestialBodyLoaders();&lt;br /&gt;
final JPLEphemeridesLoader loader = new JPLEphemeridesLoader(&amp;quot;unxp2000.405&amp;quot;,&lt;br /&gt;
        JPLEphemeridesLoader.EphemerisType.SUN);&lt;br /&gt;
&lt;br /&gt;
final JPLEphemeridesLoader loaderEMB = new JPLEphemeridesLoader(&amp;quot;unxp2000.405&amp;quot;,&lt;br /&gt;
        JPLEphemeridesLoader.EphemerisType.EARTH_MOON);&lt;br /&gt;
final JPLEphemeridesLoader loaderSSB = new JPLEphemeridesLoader(&amp;quot;unxp2000.405&amp;quot;,&lt;br /&gt;
        JPLEphemeridesLoader.EphemerisType.SOLAR_SYSTEM_BARYCENTER);&lt;br /&gt;
&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;
loader.loadCelestialBody(CelestialBodyFactory.SUN);&lt;br /&gt;
&lt;br /&gt;
final PVCoordinatesProvider sun = CelestialBodyFactory.getSun();&lt;br /&gt;
&lt;br /&gt;
// DTM2000 atmosphere&lt;br /&gt;
final Frame itrf = FramesFactory.getITRF();&lt;br /&gt;
final OneAxisEllipsoid earth = new OneAxisEllipsoid(6378136.460, 1.0 / 298.257222101, itrf);&lt;br /&gt;
SolarActivityDataFactory.addSolarActivityDataReader(new ACSOLFormatReader(&lt;br /&gt;
        SolarActivityDataFactory.ACSOL_FILENAME));&lt;br /&gt;
final SolarActivityDataProvider data = SolarActivityDataFactory.getSolarActivityDataProvider();&lt;br /&gt;
final DTMSolarData in = new DTMSolarData(data);&lt;br /&gt;
earth.setAngularThreshold(1e-10);&lt;br /&gt;
final DTM2000 atm = new DTM2000(in, sun, earth);&lt;br /&gt;
&lt;br /&gt;
// aero model of the assembly&lt;br /&gt;
final AeroModel model = new AeroModel(createAssemblyWithAeroProperties());&lt;br /&gt;
&lt;br /&gt;
// force&lt;br /&gt;
final ForceModel drag = new DragForce(atm, model);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following lines show how to set the proper configuration in order to compute the derivatives defined by given equations (see part &amp;lt;u&amp;gt;Partial derivatives with respect to spacecraft position&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;
// create the spherical spacecraft:&lt;br /&gt;
final AssemblyBuilder builder = new AssemblyBuilder();&lt;br /&gt;
// add main part (one sphere)&lt;br /&gt;
builder.addMainPart(&amp;quot;MAIN_BODY&amp;quot;);&lt;br /&gt;
// sphere property&lt;br /&gt;
final double radius = 10.;&lt;br /&gt;
final double cx = 2.;&lt;br /&gt;
final AeroSphereProperty asp = new AeroSphereProperty(radius, cx);&lt;br /&gt;
builder.addProperty(asp, &amp;quot;MAIN_BODY&amp;quot;);&lt;br /&gt;
// adding aero properties&lt;br /&gt;
// one facet&lt;br /&gt;
final Vector3D normal = Vector3D.PLUS_J;&lt;br /&gt;
final double area = 10.;&lt;br /&gt;
final Facet facet = new Facet(normal, area);&lt;br /&gt;
// aero facet property&lt;br /&gt;
final double cn = 2., ct = 1.;&lt;br /&gt;
final IPartProperty aeroFacetProp = new AeroFacetProperty(facet, cn, ct);&lt;br /&gt;
builder.addProperty(aeroFacetProp, &amp;quot;MAIN_BODY&amp;quot;);&lt;br /&gt;
// adding mass properties&lt;br /&gt;
final IPartProperty massMainProp = new MassProperty(100.);&lt;br /&gt;
builder.addProperty(massMainProp, &amp;quot;MAIN_BODY&amp;quot;);&lt;br /&gt;
// assembly creation&lt;br /&gt;
final Assembly assembly = builder.returnAssembly();&lt;br /&gt;
&lt;br /&gt;
// create the atmosphere:&lt;br /&gt;
final double ae = Constants.GRIM5C1_EARTH_EQUATORIAL_RADIUS;&lt;br /&gt;
final double f = Constants.GRIM5C1_EARTH_FLATTENING;&lt;br /&gt;
final Atmosphere atmosphere = new SimpleExponentialAtmosphere(&lt;br /&gt;
                new OneAxisEllipsoid(ae, 1.0 / 298.257222101, FramesFactory.getITRF()), 0.0004, 42000.0, 7500.0);&lt;br /&gt;
&lt;br /&gt;
// Build an AeroModel with an atmosphere model and a GeodPosition &lt;br /&gt;
//(compulsory for density partial derivatives computation)&lt;br /&gt;
final GeodPosition geodPos = new GeodPosition(ae, f)&lt;br /&gt;
final AeroModel aeroModel = new AeroModel(assembly, atmosphere, geodPos);&lt;br /&gt;
&lt;br /&gt;
// create the drag force:&lt;br /&gt;
final DragForce force = new DragForce(atmosphere, aeroModel);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Constant thrust error ===&lt;br /&gt;
&lt;br /&gt;
Here is an example of how to define a constant thrust error model:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
AbsoluteDate date = new AbsoluteDate(2005, 03, 01, TimeScalesFactory.getTAI());&lt;br /&gt;
double duration = 360;&lt;br /&gt;
Parameter ax = new Parameter(&amp;quot;ax&amp;quot;, 1.e-12);&lt;br /&gt;
Parameter ay = new Parameter(&amp;quot;ay&amp;quot;, 2.e-12);&lt;br /&gt;
Parameter az = new Parameter(&amp;quot;az&amp;quot;, 3.e-12);&lt;br /&gt;
Parameter bx = new Parameter(&amp;quot;bx&amp;quot;, 4.e-12);&lt;br /&gt;
Parameter by = new Parameter(&amp;quot;by&amp;quot;, 5.e-12);&lt;br /&gt;
Parameter bz = new Parameter(&amp;quot;bz&amp;quot;, 6.e-12);&lt;br /&gt;
Parameter cx = new Parameter(&amp;quot;cx&amp;quot;, 7.e-12);&lt;br /&gt;
Parameter cy = new Parameter(&amp;quot;cy&amp;quot;, 8.e-12);&lt;br /&gt;
Parameter cz = new Parameter(&amp;quot;cz&amp;quot;, 9.e-12);&lt;br /&gt;
IParamDiffFunction fx = new QuadraticFunction(date, ax, bx, cx);&lt;br /&gt;
IParamDiffFunction fy = new QuadraticFunction(date, ay, by, cy);&lt;br /&gt;
IParamDiffFunction fz = new QuadraticFunction(date, az, bz, cz);&lt;br /&gt;
ConstantThrustError error = new ConstantThrustError(date, duration, LOFType.TNW, fx, fy, fz);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Propagator settings : force models and events ==&lt;br /&gt;
&lt;br /&gt;
Forces implement the &amp;lt;code&amp;gt;ForceModel&amp;lt;/code&amp;gt; interface (true for all forces except ImpulseManeuver). They are intended to be used with the &amp;lt;code&amp;gt;NumericalPropagator&amp;lt;/code&amp;gt;. The &amp;lt;code&amp;gt;addForceModel(ForceModel)&amp;lt;/code&amp;gt; will add a ForceModel to the list of forces the propagator uses at each step.&lt;br /&gt;
&lt;br /&gt;
The simplest way to include a force in the dynamic model is to make an instance of it and to add it to the propagator. Given a &amp;lt;code&amp;gt;ForceModel force&amp;lt;/code&amp;gt;, one can use the following code :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
myPropagator.addForceModel(force);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the NumericalPropagator and the MultiNumericalPropagator do not use anymore the Newtonian gravity model by default. It should now be added manually to the list of the force models before starting the propagation.&lt;br /&gt;
&lt;br /&gt;
Please refer to the [ORB_PGEN_Home Propagation page ] for more information.&lt;br /&gt;
&lt;br /&gt;
Nota : The ImpulseManeuver force does not implement the ForceModel interface. It implements the EventDetector and should be handled as such (see code below). For more information about Events, please refer to the [MIS_EVT_Home Events section].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
myPropagator.addEventDetector(myImpulse);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Important note: forces implement also the &amp;lt;code&amp;gt;GradientModel&amp;lt;/code&amp;gt; necessary to provide partial dérivatives computation information. If creating a force model and wishing to compute partial dérivatives, the created force should both inherit &amp;lt;code&amp;gt;ForceModel&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;GradientModel&amp;lt;/code&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;ForceModel&#039;&#039;&#039;&lt;br /&gt;
|This interface represents a force modifying spacecraft motion.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/ForceModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GradientModel&#039;&#039;&#039;&lt;br /&gt;
|This interface provides information about partial derivatives computation.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/GradientModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GravityModel&#039;&#039;&#039;&lt;br /&gt;
|This interface provides information about gravitational attraction models.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/GravityModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbstractGravityModel&#039;&#039;&#039;&lt;br /&gt;
|This abstract class represents a gravitational attraction model.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/AbstractGravityModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbstractHarmonicGravityModel&#039;&#039;&#039;&lt;br /&gt;
|This abstract class represents a gravitational attraction model with harmonics.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/AbstractHarmonicGravityModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GridAttractionProvider&#039;&#039;&#039;&lt;br /&gt;
|Data providers for grid attraction model.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/grid/GridAttractionProvider.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.17}}/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.17}}/fr/cnes/sirius/patrius/forces/radiation/RediffusedRadiationSensitive.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;DragForce&#039;&#039;&#039;&lt;br /&gt;
|Atmospheric drag force model.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/drag/DragForce.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EarthGravitationalModelFactory&#039;&#039;&#039;&lt;br /&gt;
|Factory to provide earth gravitational model.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/EarthGravitationalModelFactory.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CunninghamGravityModel&#039;&#039;&#039;&lt;br /&gt;
|This class represents the gravitational field of a celestial body. It uses &amp;lt;u&amp;gt;unnormalized&amp;lt;/u&amp;gt; zonal, tesseral and sectorial coefficients.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/CunninghamGravityModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DrozinerGravityModel&#039;&#039;&#039;&lt;br /&gt;
|This class represents the gravitational field of a celestial body. It uses &amp;lt;u&amp;gt;unnormalized&amp;lt;/u&amp;gt; zonal, tesseral and sectorial coefficients.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/DrozinerGravityModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;BalminoGravityModel&#039;&#039;&#039;&lt;br /&gt;
|This class represents the Balmino attraction model of a gravitational field of a celestial body. It uses &amp;lt;u&amp;gt;normalized&amp;lt;/u&amp;gt; zonal, tesseral and sectorial coefficients.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/BalminoGravityModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;VariablePotentialGravityModel&#039;&#039;&#039;&lt;br /&gt;
|This class represents a variable gravity field. It computes a static potential and a time variable potential.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/variations/VariablePotentialGravityModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NewtonianGravityModel&#039;&#039;&#039;&lt;br /&gt;
|Force model for Newtonian central body attraction.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/NewtonianGravityModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GridGravityModel&#039;&#039;&#039;&lt;br /&gt;
|Gravity model for small bodies using a precomputed grid and a 3D interpolator.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/grid/GridGravityModel.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CartesianGridAttractionLoader&#039;&#039;&#039;&lt;br /&gt;
|Cartesian-based grid for grid attraction model.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/grid/CartesianGridAttractionLoader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SphericalGridAttractionLoader&#039;&#039;&#039;&lt;br /&gt;
|Spherical-based grid for grid attraction model.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/grid/SphericalGridAttractionLoader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbstractTides&#039;&#039;&#039;&lt;br /&gt;
|This class implements the methods for perturbating force due to tides.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/AbstractTides.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;OceanTides&#039;&#039;&#039;&lt;br /&gt;
|This class implements the perturbating force due to ocean tides.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/OceanTides.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TerrestrialTides&#039;&#039;&#039;&lt;br /&gt;
|This class implements the perturbating force due to terrestrial tides.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/TerrestrialTides.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PoleTides&#039;&#039;&#039;&lt;br /&gt;
|This class implements the perturbating force due to solid Earth and oceanic pole tides.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/PoleTides.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DirectBodyAttraction&#039;&#039;&#039;&lt;br /&gt;
|Direct body attraction force model used to include gravity models in the list of force models.&lt;br /&gt;
|[&amp;lt;nowiki/&amp;gt;{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/DirectBodyAttraction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ThirdBodyAttraction&#039;&#039;&#039;&lt;br /&gt;
|Third body attraction force model (including harmonics).&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/ThirdBodyAttraction.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SolarRadiationPressure&#039;&#039;&#039;&lt;br /&gt;
|Direct solar radiation pressure force model.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/radiation/SolarRadiationPressure.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RediffusedRadiationPressure&#039;&#039;&#039;&lt;br /&gt;
|PATRIUS Rediffused solar pressure force model.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/radiation/RediffusedRadiationPressure.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EmpiricalForce&#039;&#039;&#039;&lt;br /&gt;
|Empirical force model.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/EmpiricalForce.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ConstantThrustError&#039;&#039;&#039;&lt;br /&gt;
|Model of the error of a simple maneuver with constant thrust.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/maneuvers/ConstantThrustError.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SchwarzschildRelativisticEffect&#039;&#039;&#039;&lt;br /&gt;
|This class computes the relativistic Schwarzschild effect.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/relativistic/SchwarzschildRelativisticEffect.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CoriolisRelativisticEffect&#039;&#039;&#039;&lt;br /&gt;
|This class computes the relativistic Coriolis effect.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/relativistic/CoriolisRelativisticEffect.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;LenseThirringRelativisticEffect&#039;&#039;&#039;&lt;br /&gt;
|This class computes the relativistic Lense-Thirring effect.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/relativistic/LenseThirringRelativisticEffect.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_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.17_Progmission&amp;diff=4097</id>
		<title>User Manual 4.17 Progmission</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Progmission&amp;diff=4097"/>
		<updated>2025-11-27T14:24:00Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « == Introduction == === Scope === The scope of this section is to present the mission analysis features available in Patrius library.  These features are localized in the &amp;#039;&amp;#039;&amp;#039;progmission&amp;#039;&amp;#039;&amp;#039; package to host mission analysis features inspired by Celestlab.  === Javadoc === All the classes related to mission analysis are in the following packages:  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=&amp;quot;col&amp;quot;| Javadoc |- |Patrius  |[{{JavaDoc4.17}}/fr/cnes/sirius/patri... »&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 mission analysis features available in Patrius library.&lt;br /&gt;
&lt;br /&gt;
These features are localized in the &#039;&#039;&#039;progmission&#039;&#039;&#039; package to host mission analysis features inspired by Celestlab.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
All the classes related to mission analysis are 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.17}}/fr/cnes/sirius/patrius/progmission/package-summary.html Package fr.cnes.sirius.patrius.progmission]&lt;br /&gt;
|}&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;
The mission analysis provides the following main features:&lt;br /&gt;
* Interplanetary functions&lt;br /&gt;
* Visibility and eclipse computation functions&lt;br /&gt;
* Keplerian orbits properties&lt;br /&gt;
&lt;br /&gt;
== Interplanetary functions ==&lt;br /&gt;
&lt;br /&gt;
The following Celestlab functions are imported into Patrius:&lt;br /&gt;
* &amp;lt;code&amp;gt;CL_ip_sphereInfluence&amp;lt;/code&amp;gt;: Analytical computation of the radius of the sphere of influence from the gravitational parameters of the two bodies and the distance between them.&lt;br /&gt;
* &amp;lt;code&amp;gt;CL_ip_insertionDv&amp;lt;/code&amp;gt;: Analytical computation of the ΔV for insertion into an elliptical orbit around a planet from an initial hyperbolic orbit.&lt;br /&gt;
* &amp;lt;code&amp;gt;CL_ip_escapeDv&amp;lt;/code&amp;gt;: Analytical computation of the ΔV to escape a planet into a hyperbolic orbit from an initial elliptical orbit. The final class InterplanetaryUtils will group all these static functions and will not be instantiable.&lt;br /&gt;
&lt;br /&gt;
=== Sphere of influence computation ===&lt;br /&gt;
The following methods allow to compute the sphere of influence (SOI) radius around the lightest body (smallest mu) given the provided mu values and distance:&lt;br /&gt;
* &amp;lt;code&amp;gt;double computeSphereInfluenceRadius(double mu1, double mu2, double distance)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;double[] computeSphereInfluenceRadius(double[] mu1, double[] mu2, double[] distance)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;double computeSphereInfluenceRadius(CelestialBody body1, CelestialBody body2, AbsoluteDate date)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;double[] computeSphereInfluenceRadius(List bodiesList1, List bodiesList2, List dates)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspired by the Celestlab function&amp;lt;code&amp;gt;CL_ip_sphereInfluence&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Insertion ΔV computation ===&lt;br /&gt;
The following methods allow to compute the instantaneous DV needed at the perigee to reach the targeted elliptic orbit from the current hyperbolic orbit around the Earth:&lt;br /&gt;
* &amp;lt;code&amp;gt;double[] computeInsertionDV (double vinf, double rph, double sma, double tanoh, double mu)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;double[] computeInsertionDV (double vinf, double rph, double sma)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;List&amp;lt;double[]&amp;gt; computeInsertionDV (double[] vinf, double[] rph, double[] sma, double[] tanoh, double mu)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;List&amp;lt;double[]&amp;gt; computeInsertionDV (double[] vinf, double[] rph, double[] sma)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;Pair&amp;lt;Orbit, double&amp;gt;computeInsertionDV (Orbit orbit, double sma)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;List&amp;lt;Pair&amp;lt;Orbit, double&amp;gt;&amp;gt; computeInsertionDV (List&amp;lt;Orbit&amp;gt; orbitList, double[] sma)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspired by the Celestlab function &amp;lt;code&amp;gt;CL_ip_insertionDv&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Escape ΔV computation ===&lt;br /&gt;
The following methods allow to compute the instantaneous DV needed at the perigee to reach the targeted hyperbolic orbit from the current elliptic orbit around the Earth:&lt;br /&gt;
* &amp;lt;code&amp;gt;double[] computeEscapeDV (double sma, double ecc, double vinf, double tanoe, double mu)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;double[] computeEscapeDV (double sma, double ecc, double vinf)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;List&amp;lt;double[]&amp;gt; computeEscapeDV (double[] sma, double[] ecc, double[] vinf, double[] tanoe, double mu)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;List&amp;lt;double[]&amp;gt; computeEscapeDV (double[] sma, double[] ecc, double[] vinf)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;Pair&amp;lt;Orbit, double&amp;gt; computeEscapeDV (Orbit orbit, double vInf)&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;List&amp;lt;Pair&amp;lt;Orbit, double&amp;gt;&amp;gt; computeEscapeDV (List&amp;lt;Orbit&amp;gt; orbitList, double[] vInf)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inspired by the Celestlab function &amp;lt;code&amp;gt;CL_ip_escapeDv&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Visibility and eclipse computation functions ==&lt;br /&gt;
&lt;br /&gt;
The following Celestlab functions are imported into Patrius:&lt;br /&gt;
* &amp;lt;code&amp;gt;CL_ev_eclipse&amp;lt;/code&amp;gt;: Computation of eclipse intervals between a satellite, a star (light source), and an occulting body.&lt;br /&gt;
* &amp;lt;code&amp;gt;CL_ev_stationVisibility&amp;lt;/code&amp;gt;: Computation of visibility intervals between a satellite and a station that defines a minimum elevation angle.&lt;br /&gt;
* &amp;lt;code&amp;gt;CL_gm_eclipse&amp;lt;/code&amp;gt;: Analytical computation of various eclipse results for an elliptical orbit. The results include the eclipse duration, the initial and final PSO values (start/end of eclipse), and the angle describing the portion of the orbit in eclipse.&lt;br /&gt;
* &amp;lt;code&amp;gt;CL_gm_visiParams&amp;lt;/code&amp;gt;: Analytical computation of various visibility parameters around a spherical body, specifying the distances between the body’s center and, respectively, the observing satellite and the point of interest. The results include central angles, the distance between the satellite and the target, the elevation angle, and the incidence angle.&lt;br /&gt;
&lt;br /&gt;
=== ProgDetectorUtils class features ===&lt;br /&gt;
&lt;br /&gt;
This class can be used to compute the interval lists associated to detectors (rather the phenomena derived from them) for a given propagator and propagation interval.&lt;br /&gt;
&lt;br /&gt;
The event detectors will be wrapped with coding event detectors that will be added to the propagator.&lt;br /&gt;
&lt;br /&gt;
The main usage of this class is to make event detectors usages more convenient for users. It offers severals kind of constructors and provides only one service : &amp;lt;code&amp;gt;getIntervals()&amp;lt;/code&amp;gt; to retrieve the map linking each event detector provided to the instance and the list of the intervals of their associated phenomenon.&lt;br /&gt;
&lt;br /&gt;
== Keplerian orbits properties ==&lt;br /&gt;
&lt;br /&gt;
The following Celestlab functions are imported into Patrius:&lt;br /&gt;
* &amp;lt;code&amp;gt;CL_kp_anomConvert&amp;lt;/code&amp;gt;: Analytical computation to convert one type of orbital anomaly to another.&lt;br /&gt;
* &amp;lt;code&amp;gt;CL_kp_apsConvert&amp;lt;/code&amp;gt;: Analytical computation to convert orbital characteristics at periapsis or apoapsis.&lt;br /&gt;
* &amp;lt;code&amp;gt;CL_kp_characteristics&amp;lt;/code&amp;gt;: Analytical computation of various orbital parameters for elliptical or hyperbolic orbits. The results include the orbital period, mean motion, hyperbolic excess velocity, orbital energy, escape velocities, and others.&lt;br /&gt;
&lt;br /&gt;
=== AnomalyUtils class features ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;CL_kp_anomConvert&amp;lt;/code&amp;gt; service is provided by the &amp;lt;code&amp;gt;AnomalyUtils&amp;lt;/code&amp;gt; class (in fr.cnes.sirius.patrius.orbits package).&lt;br /&gt;
&lt;br /&gt;
This class describes static methods allowing to convert anomaly types from/to true/mean/eccentric for elliptical or hyperbolic orbits. It supports &amp;quot;e&amp;quot; or &amp;quot;ex/ey&amp;quot; representations.&lt;br /&gt;
&lt;br /&gt;
=== KeplerianParamComputer class features ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;CL_kp_apsConvert&amp;lt;/code&amp;gt; service is provided by the &amp;lt;code&amp;gt;KeplerianParamComputer&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
This class describes static methods allowing to compute various keplerian characteristics based on the semi-major axis, eccentricity and true anomaly such as the periapsis radius/altitude, the apoapsis radius/altitude, the periapsis/apoapsis velocity and the hyperbolic excess velocity.&lt;br /&gt;
&lt;br /&gt;
=== KeplerianParamUtils class features ===&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;CL_kp_characteristics&amp;lt;/code&amp;gt; service is provided by the &amp;lt;code&amp;gt;KeplerianParamUtils&amp;lt;/code&amp;gt; class.&lt;br /&gt;
&lt;br /&gt;
This class describes static methods allowing to compute various type of parameters for elliptical or hyperbolic orbits such as the orbital period, mean motion, hyperbolic excess velocity, orbital energy, escape velocities, and others. It uses an internal enumerate class ApsParamType to make easier to get the expected parameter without having to deal with a large number of methods.&lt;br /&gt;
&lt;br /&gt;
== Contents ==&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;AnomalyUtils&#039;&#039;&#039;&lt;br /&gt;
|Anomalies conversion features.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/orbits/AnomalyUtils.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EventUtils&#039;&#039;&#039;&lt;br /&gt;
|Event features imported from CelestLab.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/progmission/EventUtils.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;InterplanetaryUtils&#039;&#039;&#039;&lt;br /&gt;
|Interplanetary features imported from CelestLab.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/progmission/InterplanetaryUtils.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;KeplerianParamComputer&#039;&#039;&#039;&lt;br /&gt;
|Keplerian parameters characteristics from kep params features imported from CelestLab.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/progmission/KeplerianParamComputer.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;KeplerianParamUtils&#039;&#039;&#039;&lt;br /&gt;
|Keplerian parameters characteristics features imported from CelestLab.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/progmission/KeplerianParamUtils.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ProgDetectorUtils&#039;&#039;&#039;&lt;br /&gt;
|Event detectors simplified usage.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/progmission/ProgDetectorUtils.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Propagation&amp;diff=4096</id>
		<title>User Manual 4.17 Propagation</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Propagation&amp;diff=4096"/>
		<updated>2025-11-27T09:38:20Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section makes a general presentation of propagators : explanations about using them are given with practical examples of use illustrated by code chuncks.&lt;br /&gt;
&lt;br /&gt;
The PATRIUS library offers different propagators :&lt;br /&gt;
&lt;br /&gt;
* Numerical propagator (see [[User Manual 4.17 Numerical propagation|dedicated User Manual]])&lt;br /&gt;
* Analytical propagators (Keplerian, Eckstein-Hechler, J2 secular, Lyddane secular and long period) (see [[User Manual 4.17 Analytical propagation|dedicated User Manual]])&lt;br /&gt;
* Analytical 2D propagator (see [[User Manual 4.17 Analytical propagation|dedicated User Manual]])&lt;br /&gt;
* TLE propagator (Two Line Element) (see [[User Manual 4.17 Analytical propagation|dedicated User Manual]])&lt;br /&gt;
* Precomputed ephemeris propagator (see [[User Manual 4.17 Analytical propagation|dedicated User Manual]])&lt;br /&gt;
* The STELA propagator (see [[User Manual 4.17 Semi-analytical propagation|dedicated User Manual]])&lt;br /&gt;
&lt;br /&gt;
Features presented in this section are available to all propagators.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
Some of the propagation packages available in the Patrius library 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;| Library&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Javadoc&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/package-summary.html Package fr.cnes.sirius.patrius.propagation]&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.&lt;br /&gt;
&lt;br /&gt;
== Features description ==&lt;br /&gt;
&lt;br /&gt;
=== Propagation mode ===&lt;br /&gt;
There are three different propagation modes : slave, master and ephemeris generation.&lt;br /&gt;
&lt;br /&gt;
==== Slave mode ====&lt;br /&gt;
Set to &#039;&#039;&#039;slave mode&#039;&#039;&#039;, the propagator computes the final orbit for a given date and returns it to the user without any intermediate feedback.&lt;br /&gt;
&lt;br /&gt;
==== Master mode : using step handlers ====&lt;br /&gt;
When the user wants to call some specific function at the end of each successful step or at the end of a given fixed step during the integration, the propagator has to be set to &#039;&#039;&#039;master mode&#039;&#039;&#039; and a step handler which represents the specific function has to be designed by the user and given to the propagator : the associated method is &amp;lt;code&amp;gt;handleStep()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
To illustrate how to use this mode on a pratical example, let&#039;s define some initial state with :&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039; an inertial frame &#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039; a date in some time scale &#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039; a central attraction coefficient &#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039; an orbit defined by its keplerian parameters &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Inertial frame&lt;br /&gt;
Frame inertialFrame = FramesFactory.getEME2000();&lt;br /&gt;
// Initial date&lt;br /&gt;
TimeScale utc = TimeScalesFactory.getUTC();&lt;br /&gt;
AbsoluteDate initialDate = new AbsoluteDate(2004, 01, 01, 23, 30, 00.000,utc);&lt;br /&gt;
// Central attraction coefficient&lt;br /&gt;
double mu =  3.986004415e+14;&lt;br /&gt;
// Initial orbit&lt;br /&gt;
double a = 24396159;                // semi major axis in meters&lt;br /&gt;
double e = 0.72831215;              // eccentricity&lt;br /&gt;
double i = Math.toRadians(7);       // inclination&lt;br /&gt;
double omega = Math.toRadians(180); // perigee argument&lt;br /&gt;
double raan = Math.toRadians(261);  // right ascention of ascending node&lt;br /&gt;
double lM = 0;                      // mean anomaly&lt;br /&gt;
Orbit initialOrbit = new KeplerianOrbit(a, e, i, omega, raan, lM, PositionAngle.MEAN, &lt;br /&gt;
                                        inertialFrame, initialDate, mu);&lt;br /&gt;
// Initial state definition&lt;br /&gt;
SpacecraftState initialState = new SpacecraftState(initialOrbit);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we use a more sophisticated NumericalPropagator based on an some adaptive step integrator provided by the math package, but no matter which integrator is used.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Adaptive step integrator&lt;br /&gt;
// with a minimum step of 0.001 and a maximum step of 1000&lt;br /&gt;
double minStep = 0.001;&lt;br /&gt;
double maxstep = 1000.0;&lt;br /&gt;
double positionTolerance = 10.0;&lt;br /&gt;
OrbitType propagationType = OrbitType.KEPLERIAN;&lt;br /&gt;
double[][] tolerances =&lt;br /&gt;
    NumericalPropagator.tolerances(positionTolerance, initialOrbit, propagationType);&lt;br /&gt;
AdaptiveStepsizeIntegrator integrator =&lt;br /&gt;
    new DormandPrince853Integrator(minStep, maxstep, tolerances[0], tolerances[1]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We set up the integrator, and force it to use Keplerian parameters for propagation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
NumericalPropagator propagator = new NumericalPropagator(integrator);&lt;br /&gt;
propagator.setOrbitType(propagationType);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A force model, reduced here to a single perturbing gravity field, is taken into account.&lt;br /&gt;
More precisions on force models can be found in [ORB_FORCE_Home in Force models page].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Frame ITRF = FramesFactory.getITRF(); // terrestrial frame&lt;br /&gt;
double ae  =  6378137.;                       // equatorial radius in meter&lt;br /&gt;
double c20 = -1.08262631303e-3;               // J2 potential coefficient&lt;br /&gt;
&lt;br /&gt;
// potential coefficients arrays (only J2 is considered here)&lt;br /&gt;
double[][] c = new double[3][1];&lt;br /&gt;
c[0][0] = 0.0;&lt;br /&gt;
c[2][0] = c20;&lt;br /&gt;
double[][] s = new double[3][1];&lt;br /&gt;
ForceModel cunningham = new CunninghamAttractionModel(ITRF, ae, mu, c, s);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This force model is simply added to the propagator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
propagator.addForceModel(cunningham);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The propagator operating mode is set to master mode with fixed step and a TutorialStepHandler which implements the interface PatriusFixedStepHandler in order to fulfill the handleStep method to be called within the loop. For the purpose of this tutorial, the handleStep method will just print the current state at the moment.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
propagator.setMasterMode(60., new TutorialStepHandler());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, the initial state is set for the propagator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
propagator.setInitialState(initialState);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, the propagator is just asked to propagate, from the initial state, for a given duration.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
SpacecraftState finalState =&lt;br /&gt;
    propagator.propagate(new AbsoluteDate(initialDate, 630.));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Clearly, with a few lines of code, the main application delegates to the propagator the care of handling regular outputs through a variable step integration loop.&lt;br /&gt;
&lt;br /&gt;
The only need is to derived some class from the interface PatriusFixedStepHandler to realize a handleStep method, as follows:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
private static class TutorialStepHandler implements PatriusFixedStepHandler {&lt;br /&gt;
&lt;br /&gt;
    public void handleStep(SpacecraftState currentState, boolean isLast) {&lt;br /&gt;
        System.out.println(&amp;quot; time : &amp;quot; + currentState.getDate());&lt;br /&gt;
        System.out.println(&amp;quot; &amp;quot; + currentState.getOrbit());&lt;br /&gt;
        if (isLast) {&lt;br /&gt;
            System.out.println(&amp;quot; this was the last step &amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the same result, with the slave mode, it would have required much more programming.&lt;br /&gt;
&lt;br /&gt;
The printed results are shown below:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
 time : 2004-01-01T23:30:00.000&lt;br /&gt;
 keplerian parameters: {a: 2.4396159E7; e: 0.72831215; i: 7.0; pa: 180.0; raan: 261.0; v: 0.0;}&lt;br /&gt;
 time : 2004-01-01T23:31:00.000&lt;br /&gt;
 keplerian parameters: {a: 2.439564424480015E7; e: 0.7283054179012741; i: 6.999949573716115; pa: 180.01089879431635; raan: 260.9999744509341; v: 5.270522984259634;}&lt;br /&gt;
 time : 2004-01-01T23:32:00.000&lt;br /&gt;
 keplerian parameters: {a: 2.4394130981544524E7; e: 0.7282856263106472; i: 6.999800432744152; pa: 180.02168751826343; raan: 260.9997982967906; v: 10.50387496695558;}&lt;br /&gt;
 time : 2004-01-01T23:33:00.000&lt;br /&gt;
 keplerian parameters: {a: 2.4391710665289845E7; e: 0.7282539637676634; i: 6.999563066306985; pa: 180.03226220891892; raan: 260.99933874845317; v: 15.664604011799053;}&lt;br /&gt;
 time : 2004-01-01T23:34:00.000&lt;br /&gt;
 keplerian parameters: {a: 2.438852138985819E7; e: 0.7282122258929671; i: 6.9992532645274546; pa: 180.04252939476373; raan: 260.9984960696569; v: 20.720499012905563;}&lt;br /&gt;
 time : 2004-01-01T23:35:00.000&lt;br /&gt;
 keplerian parameters: {a: 2.438473009191154E7; e: 0.7281625851163973; i: 6.998890000900681; pa: 180.05240967921347; raan: 260.9972118041821; v: 25.643756282394765;}&lt;br /&gt;
 time : 2004-01-01T23:36:00.000&lt;br /&gt;
 keplerian parameters: {a: 2.4380513619406037E7; e: 0.7281073453198131; i: 6.998493179635541; pa: 180.06183982161005; raan: 260.9954699357843; v: 30.411707875362936;}&lt;br /&gt;
 time : 2004-01-01T23:37:00.000&lt;br /&gt;
 keplerian parameters: {a: 2.4376042162606522E7; e: 0.7280487266192758; i: 6.998081669198389; pa: 180.0707733525973; raan: 260.9932919569584; v: 35.00709604303499;}&lt;br /&gt;
 time : 2004-01-01T23:38:00.000&lt;br /&gt;
 keplerian parameters: {a: 2.4371467133870374E7; e: 0.727988707383731; i: 6.997671877833683; pa: 180.07917999091737; raan: 260.99072804117174; v: 39.41795154717632;}&lt;br /&gt;
 time : 2004-01-01T23:39:00.000&lt;br /&gt;
 keplerian parameters: {a: 2.4366914169719197E7; e: 0.7279289324335715; i: 6.99727695633292; pa: 180.08704419756123; raan: 260.98784670576674; v: 43.63716855903322;}&lt;br /&gt;
 time : 2004-01-01T23:40:00.000&lt;br /&gt;
 keplerian parameters: {a: 2.436248074752743E7; e: 0.7278706810843818; i: 6.996906568384245; pa: 180.09436319418123; raan: 260.9847250080804; v: 47.66188030915512;}&lt;br /&gt;
 this was the last step &lt;br /&gt;
 Final date  : 2004-01-01T23:40:30.000&lt;br /&gt;
 Final state : keplerian parameters: {a: 2.4360331834936075E7; e: 0.7278424290862751; i: 6.996732681960374; pa: 180.097820317503; raan: 260.98309840201875; v: 49.6013850854552;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Ephemeris mode ====&lt;br /&gt;
The &#039;&#039;&#039;ephemeris generation mode&#039;&#039;&#039; is used when the user needs random access to the orbit state at any date after the propagation. Be aware that this mode may be memory intensive since all intermediate results are stored.&lt;br /&gt;
&lt;br /&gt;
To illstrate it, let&#039;s also first define some initial state with :&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039; an inertial frame &#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039; a date in some time scale &#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039; a central attraction coefficient &#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039; an orbit defined by its keplerian parameters &#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Inertial frame&lt;br /&gt;
Frame inertialFrame = FramesFactory.getEME2000();&lt;br /&gt;
// Initial date&lt;br /&gt;
TimeScale utc = TimeScalesFactory.getUTC();&lt;br /&gt;
AbsoluteDate initialDate = new AbsoluteDate(2004, 01, 01, 23, 30, 00.000,utc);&lt;br /&gt;
// Central attraction coefficient&lt;br /&gt;
double mu =  3.986004415e+14;&lt;br /&gt;
// Initial orbit&lt;br /&gt;
double a = 24396159;                // semi major axis in meters&lt;br /&gt;
double e = 0.72831215;              // eccentricity&lt;br /&gt;
double i = Math.toRadians(7);       // inclination&lt;br /&gt;
double omega = Math.toRadians(180); // perigee argument&lt;br /&gt;
double raan = Math.toRadians(261);  // right ascention of ascending node&lt;br /&gt;
double lM = 0;                      // mean anomaly&lt;br /&gt;
Orbit initialOrbit = new KeplerianOrbit(a, e, i, omega, raan, lM, PositionAngle.MEAN, &lt;br /&gt;
                                        inertialFrame, initialDate, mu);&lt;br /&gt;
// Initial state definition&lt;br /&gt;
SpacecraftState initialState = new SpacecraftState(initialOrbit);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here we use a simple NumericalPropagator, without perturbation, based on a classical fixed step Runge-Kutta integrator provided by the math package.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double stepSize = 10;&lt;br /&gt;
FirstOrderIntegrator integrator = new ClassicalRungeKuttaIntegrator(stepSize);&lt;br /&gt;
NumericalPropagator propagator = new NumericalPropagator(integrator);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The initial state is set for this propagator:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
propagator.setInitialState(initialState);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then, the propagator operating mode is simply set to ephemeris mode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
propagator.setEphemerisMode();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the propagation is performed for a given duration.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
SpacecraftState finalState =&lt;br /&gt;
    propagator.propagate(new AbsoluteDate(initialDate, 6000));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This finalState can be used for anything, to be printed for example just like below:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
 Numerical propagation :&lt;br /&gt;
 Final date : 2004-01-02T01:10:00.000&lt;br /&gt;
 equinoctial parameters: {a: 2.4396159E7;&lt;br /&gt;
                           ex: 0.11393312156755062; ey: 0.719345418868777;&lt;br /&gt;
                           hx: -0.009567941763699867; hy: -0.06040960680288257;&lt;br /&gt;
                           lv: 583.1250344407331;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Throughout the propagation, intermediate states are stored within an ephemeris which can be recovered now just with one instruction:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
BoundedPropagator ephemeris = propagator.getGeneratedEphemeris();&lt;br /&gt;
System.out.println(&amp;quot; Ephemeris defined from &amp;quot; + ephemeris.getMinDate() +&lt;br /&gt;
                   &amp;quot; to &amp;quot; + ephemeris.getMaxDate());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The ephemeris is defined as a BoundedPropagator, which means that it is valid only between the propagation initial and final dates. The code above give the following result:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Ephemeris defined from 2004-01-01T23:30:00.000 to 2004-01-02T01:10:00.000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Between these dates, the ephemeris can be used as any propagator to propagate the orbital state towards any intermediate date just with one instruction:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
SpacecraftState intermediateState = ephemeris.propagate(intermediateDate);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here are results obtained with intermediate dates set to 3000 second after start date and to exactly the final date:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
 Ephemeris propagation :&lt;br /&gt;
 date :  2004-01-02T00:20:00.000&lt;br /&gt;
 equinoctial parameters: {a: 2.4396159E7;&lt;br /&gt;
                           ex: 0.11393312156755062; ey: 0.719345418868777;&lt;br /&gt;
                           hx: -0.009567941763699867; hy: -0.06040960680288257;&lt;br /&gt;
                           lv: 559.0092657655284;}&lt;br /&gt;
  date :  2004-01-02T01:10:00.000&lt;br /&gt;
  equinoctial parameters: {a: 2.4396159E7;&lt;br /&gt;
                           ex: 0.11393312156755062; ey: 0.719345418868777;&lt;br /&gt;
                           hx: -0.009567941763699867; hy: -0.06040960680288257;&lt;br /&gt;
                           lv: 583.1250344407331;}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following shows the error message we get when we try to use a date outside of the ephemeris range (in this case, the intermediate date was set to 1000 seconds before ephemeris start:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
out of range date for ephemerides: 2004-01-01T23:13:20.000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Choosing the suitable mode ====&lt;br /&gt;
&lt;br /&gt;
Here are given advantages and drawbacks of each mode according the context : be sure to use the suitable one reading it !&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| Use case&lt;br /&gt;
| without dense output&lt;br /&gt;
| with dense output&lt;br /&gt;
| with event detection&lt;br /&gt;
| with step handler&lt;br /&gt;
|-&lt;br /&gt;
|slave&lt;br /&gt;
|  + faster than the others since it has no step handler&lt;br /&gt;
|  - not adapted when it comes to generate a dense output&lt;br /&gt;
|  + adapted&lt;br /&gt;
|  - not adapted&lt;br /&gt;
|-&lt;br /&gt;
|master&lt;br /&gt;
|  - not really adapted&lt;br /&gt;
|  - not really adapted (could be adapted with a specific step handler)&lt;br /&gt;
|  + adapted&lt;br /&gt;
|  + adapted&lt;br /&gt;
|-&lt;br /&gt;
|ephemeris generation&lt;br /&gt;
|  - not really adapted&lt;br /&gt;
|  + adapted&lt;br /&gt;
|  + adapted&lt;br /&gt;
|  - not adapted&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
NB : To get a dense output, the user should not propagate on a series of time intervals to get intermediate results because at the end of any propagation, the last step is likely readjusted to reach exactly the propagation end date. This behavior differs from the expected one : the integrator parametrization is bypassed, this behavior should remain rare.&lt;br /&gt;
&lt;br /&gt;
=== Propagation frame ===&lt;br /&gt;
Both analytical and numerical propagators are able to propagate orbits which are defined in a not inertial or pseudo-inertial frame.&lt;br /&gt;
However, the propagation has to be performed in an inertial frame, as a result:&lt;br /&gt;
* If initial state frame is inertial and user did not specify propagation frame, then propagation will be performed in initial state frame&lt;br /&gt;
* If initial state frame is not inertial and user did not specify propagation frame, then an exception will be thrown&lt;br /&gt;
* If the user specified a propagation frame, then propagation is performed in specified frame, independently of initial state frame&lt;br /&gt;
&lt;br /&gt;
Propagation frame can be specified using method &amp;lt;code&amp;gt;setOrbitFrame(final Frame frame)&amp;lt;/code&amp;gt; of propagators.&lt;br /&gt;
&lt;br /&gt;
=== Events management ===&lt;br /&gt;
This paragraph aims to show the power and simplicity of the event handling mechanism. One needs to check the visibility between a satellite and a ground station during some time range.&amp;lt;br&amp;gt;&lt;br /&gt;
We will use, and extend, the predefined ElevationDetector to perform the task. The goal is not to make a complete presentation of events detectors but to introduce it in the context of propagators :&amp;lt;br&amp;gt;&lt;br /&gt;
events detectors are spreadly developped at the [MIS_EVT_Home dedicated Events detection page].&lt;br /&gt;
First, let&#039;s set up an initial state for the satellite defined by a position and a velocity at one date in some inertial frame.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Vector3D position  = new Vector3D(-6142438.668, 3492467.560, -25767.25680);&lt;br /&gt;
Vector3D velocity  = new Vector3D(505.8479685, 942.7809215, 7435.922231);&lt;br /&gt;
PVCoordinates pvCoordinates = new PVCoordinates(position, velocity);&lt;br /&gt;
AbsoluteDate initialDate =&lt;br /&gt;
    new AbsoluteDate(2004, 01, 01, 23, 30, 00.000, TimeScalesFactory.getUTC());&lt;br /&gt;
Frame inertialFrame = FramesFactory.getEME2000();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We also need to set the central attraction coefficient to define the initial orbit as a KeplerianOrbit.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double mu =  3.986004415e+14;&lt;br /&gt;
Orbit initialOrbit =&lt;br /&gt;
    new KeplerianOrbit(pvCoordinates, inertialFrame, initialDate, mu);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As a propagator, we consider a KeplerianPropagator to compute the simple keplerian motion. It could be more elaborate without modifying the general purpose of this speech.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Propagator kepler = new KeplerianPropagator(initialOrbit);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Then, let&#039;s define the ground station by its coordinates as an EllipsoidPoint:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double ae =  6378137.0;                // equatorial radius in meter&lt;br /&gt;
double f  =  1.0 / 298.257223563;      // flattening&lt;br /&gt;
Frame ITRF = FramesFactory.getITRF();  // terrestrial frame at an arbitrary date&lt;br /&gt;
BodyShape earth = new OneAxisEllipsoid(ae, f, ITRF);&lt;br /&gt;
double longitude = Math.toRadians(45.);&lt;br /&gt;
double latitude  = Math.toRadians(25.);&lt;br /&gt;
double altitude  = 0.;&lt;br /&gt;
EllipsoidPoint station1 = new EllipsoidPoint(earth, LLHCoordinatesSystem.ELLIPSODETIC, latitude, longitude, altitude, &amp;quot;point&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And let&#039;s associate to it a TopocentricFrame related to a BodyShape in some terrestrial frame.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
TopocentricFrame sta1Frame = new TopocentricFrame(earth, station1, &amp;quot;station1&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
More precisions on BodyShape and BodyPoint can be found in [FDY_BODY_Home Bodies page].&lt;br /&gt;
More precisions on TopocentricFrame can be found in [FDY_FRAME_Home Frames page].&lt;br /&gt;
&lt;br /&gt;
An EventDetector is defined as a VisibilityFromStationDetector which is derived from an ElevationDetector with the same specific parameters.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
double maxcheck  = 1.;&lt;br /&gt;
double elevation = Math.toRadians(5.);&lt;br /&gt;
EventDetector sta1Visi = new VisibilityFromStationDetector(maxcheck, elevation, sta1Frame);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This EventDetector is added to the propagator:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
kepler.addEventDetector(sta1Visi);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Finally, the propagator is simply asked to perform until some final date, in slave mode by default.&lt;br /&gt;
&lt;br /&gt;
It will propagate from the initial date to the first raising or for the fixed duration according to the behavior implemented in the VisibilityDetector class.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
SpacecraftState finalState =&lt;br /&gt;
    kepler.propagate(new AbsoluteDate(initialDate, 1500.));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
The main application code is very simple, all the work is done inside the propagator thanks to the VisibilityDetector class especially created for the purpose.&lt;br /&gt;
&lt;br /&gt;
This class extends the ElevationDetector class, by overriding the eventOccurred method with the special ability to print the results of the visibility check, both the raising and the setting time, and to stop the propagation just after the setting detection.&lt;br /&gt;
&lt;br /&gt;
The printed result is shown below. We can see that the propagation stopped just after detecting the raising:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
Visibility on station1 begins at 2004-01-01T23:31:52.097&lt;br /&gt;
Visibility on station1 ends at 2004-01-01T23:42:48.850&lt;br /&gt;
Final state : 2004-01-01T23:42:48.850&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Content ==&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;BoundedPropagator&lt;br /&gt;
|This interface is intended for ephemerides valid only during a time range.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/BoundedPropagator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Propagator&lt;br /&gt;
|This interface provides a way to propagate an orbit at any time.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/Propagator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SpacecraftStateProvider&lt;br /&gt;
|This interface is a generic interface for all SpacecraftState providers (such as propagator).&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/SpacecraftStateProvider.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.17}}/fr/cnes/sirius/patrius/propagation/SpacecraftState.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_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.17_Ephemeris&amp;diff=4095</id>
		<title>User Manual 4.17 Ephemeris</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Ephemeris&amp;diff=4095"/>
		<updated>2025-11-27T09:36:11Z</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;
This section describes the propagation of spacecraftstates based on interpolation of position velocity ephemeris.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The concerned classes are avalaible 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.17}}/fr/cnes/sirius/patrius/utils/package-summary.html Package fr.cnes.sirius.patrius.utils]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/package-summary.html Package fr.cnes.sirius.patrius.propagation]&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;
See the [ORB_PRO_PkgOverview Propagator ] page for more generic information about propagators.&lt;br /&gt;
&lt;br /&gt;
Propagation based on interpolation of position velocity ephemeris has been design to be very simple to use:&lt;br /&gt;
&lt;br /&gt;
* Ephemeris propagators extend &amp;lt;code&amp;gt;AbstractPropagator&amp;lt;/code&amp;gt; class. As a result all propagators features (event detection, etc.) are available.&lt;br /&gt;
&lt;br /&gt;
* Ephemeris propagators are based on a &amp;lt;code&amp;gt;PVCoordinateProvider&amp;lt;/code&amp;gt; to retrieve the orbital parameters at required date.&lt;br /&gt;
&lt;br /&gt;
* Implementation of &amp;lt;code&amp;gt;PVCoordinateProvider&amp;lt;/code&amp;gt; based on ephemeris interpolation (Hermite, or Lagrange).&lt;br /&gt;
&lt;br /&gt;
* Implementation of &amp;lt;code&amp;gt;AdditionalStatesProvider&amp;lt;/code&amp;gt; based on an ephemeris of additional states.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== PVCoordinatesPropagator ===&lt;br /&gt;
The PV coordinate propagator extends &amp;lt;code&amp;gt;AbstractPropagator&amp;lt;/code&amp;gt; and provides a simple way to propagate an initial spacecraft state coherent with the provided &amp;lt;code&amp;gt;PVCoordinatesProvider&amp;lt;/code&amp;gt; and the eventual attitude and additional states provider. &lt;br /&gt;
&lt;br /&gt;
The propagation of position velocity is based on the getPVCoordinates of the given &amp;lt;code&amp;gt;PVCoordinatesProvider&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
The propagation of attitude is based on the given &amp;lt;code&amp;gt;AttitudeProvider&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
The propagation of the additional states is based on the given &amp;lt;code&amp;gt;AdditionalStatesProvider&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
A classical simple use case is :&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;PVCoordinatesProvider&amp;lt;/code&amp;gt; : One of the provider based on ephemeris interpolation (Lagrange or Hermite)&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;AttitudeProvider&amp;lt;/code&amp;gt; : Null. The attitude of the propagated spacecraft state is null.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;AdditionalStatesProvider&amp;lt;/code&amp;gt; : Null. The additional states of the propagated spacecraft state is null.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A classical advanced use case is to add an attitude provider and the SimpleAdditionalStateProvider described in next paragraph.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039;: Events detector with &amp;lt;code&amp;gt;Action.RESET_STATE&amp;lt;/code&amp;gt; should not be used with this propagator fed with a &amp;quot;precomputed&amp;quot; PV coordinate provider (such as an ephemeris or an orbit object). In particular, impulse maneuvers cannot be used. Otherwise propagation will fail.&amp;lt;br&amp;gt;&lt;br /&gt;
This is due to the fact that the provided PV coordinate provider is not valid any more after the &amp;lt;code&amp;gt;Action.RESET_STATE&amp;lt;/code&amp;gt; action.&lt;br /&gt;
&lt;br /&gt;
=== SimpleAdditionalStateProvider ===&lt;br /&gt;
The &amp;lt;code&amp;gt;SimpleAdditionalStateProvider&amp;lt;/code&amp;gt; is an implementation of &amp;lt;code&amp;gt;AdditionalStateProvider&amp;lt;/code&amp;gt; based on additional states ephemeris.&lt;br /&gt;
&lt;br /&gt;
The computation of an additional state for a given date is the following:&lt;br /&gt;
&lt;br /&gt;
* If the given date is found in the ephemeris, the associated additional state vector is returned&lt;br /&gt;
&lt;br /&gt;
* Otherwise a linera interpolation is performed.&lt;br /&gt;
&lt;br /&gt;
=== PVCoordinateProvider Ephemeris ===&lt;br /&gt;
Two classes provide PVCoordinates at a given date from an ephemeris interpolation :&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;EphemerisPvLagrange&amp;lt;/code&amp;gt; : Computes the PVCoordinates using a Hermite interpolation (&amp;lt;code&amp;gt;HermiteInterpolator&amp;lt;/code&amp;gt;) of the ephemeris without providing any derivatives on points to be interpolated (this allows to improve the computation performance with respect to a classical Lagrange approach - &amp;lt;code&amp;gt;PolynomialFunctionLagrangeForm&amp;lt;/code&amp;gt; - by a factor 4).&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;EphemerisPvHermite&amp;lt;/code&amp;gt; : Computes the PVCoordinates using a Hermite interpolation of the ephemeris&lt;br /&gt;
&lt;br /&gt;
Both can be built from a list of spacecraftstates or from list of dates- positions - velocities expressed in a given frame.&lt;br /&gt;
&lt;br /&gt;
It is possible to accept the interpolation in a non-optimal range through a setting at the construction (disabled by default). Meaning the ephemeris can still be interpolated in a degraded case with less samples than required by the order in the lower or upper bound.&lt;br /&gt;
&lt;br /&gt;
==== Lagrange interpolation ====&lt;br /&gt;
&lt;br /&gt;
Intermediate states are computed with a Lagrange interpolator (order 8 by default) which :&lt;br /&gt;
&lt;br /&gt;
* expects that spacecraft states are chronologically sorted (duplicates are allowed). If not sorted, no exception will be thrown and result might be wrong. &lt;br /&gt;
&lt;br /&gt;
* is based on an instance of PolynomialFunctionLagrangeForm, which is stored at each interpolation to be reused for same interpolation interval, and updated if the interpolation is not in the same interval &amp;lt;math&amp;gt;t \in [t_{i}, t_{i+1}[&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;i \in \left\{0, ..., N \right\}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the size of the handled ephemeris. &lt;br /&gt;
&lt;br /&gt;
The interpolation order &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt; for LagrangeEphemeris should be an even number, and the interpolation date should correspond to an index that belongs in &amp;lt;math&amp;gt;n/2- 1 \leq i \leq N-1-n/2&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Hermite interpolation ====&lt;br /&gt;
&lt;br /&gt;
Intermediate states are computed with a Hermite interpolator which :&lt;br /&gt;
&lt;br /&gt;
* expects the spacecraft states to be chronologically sorted (duplicates are allowed). If not sorted, no exception will be thrown and result might be wrong. &lt;br /&gt;
&lt;br /&gt;
* is based on an instance of HermiteInterpolator, which is stored at each interpolation to be reused for same interpolation interval, and updated if the interpolation is not in the same interval &amp;lt;math&amp;gt;t \in [t_{i}, t_{i+1}[&amp;lt;/math&amp;gt;, where &amp;lt;math&amp;gt;i \in \left\{0, ..., N \right\}&amp;lt;/math&amp;gt; and &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; is the size of the handled ephemeris (in closed-open convention). &lt;br /&gt;
&lt;br /&gt;
For HermiteEphemeris, the interpolation can use the acceleration array if it is available.&lt;br /&gt;
&lt;br /&gt;
=== PVCoordinateProvider AlmanacPVCoordinates ===&lt;br /&gt;
The class &amp;lt;code&amp;gt;AlmanacPVCoordinates&amp;lt;/code&amp;gt; extends the &amp;lt;code&amp;gt;PVCoordinateProvider&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It provides PVCoordinates (position and velocity) of GNSS almanacs.&amp;lt;br&amp;gt;&lt;br /&gt;
Almanacs can be provided using the &amp;lt;code&amp;gt;AlmanacGNSSParameters&amp;lt;/code&amp;gt; class.&amp;lt;br&amp;gt;&lt;br /&gt;
The classes &amp;lt;code&amp;gt;CNAVGNSSParameters&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;LNAVGNSSParameters&amp;lt;/code&amp;gt; are simple containers for broadcast model CNAV and LNAV ephemeris description parameters of GNSS satellites (GPS and BeiDou for CNAV and GPS, BeiDou and Galileo for LNAV).&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;
{| 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;IntegratedEphemeris&#039;&#039;&#039;&lt;br /&gt;
|This class stores sequentially generated orbital parameters for later retrieval.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/precomputed/IntegratedEphemeris.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Ephemeris&#039;&#039;&#039;&lt;br /&gt;
|This class is designed to accept and handle tabulated orbital entries. Tabulated entries are classified and then extrapolated in way to obtain continuous output, with accuracy and computation methods configured by the user.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/precomputed/Ephemeris.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EphemerisPvLagrange&#039;&#039;&#039;&lt;br /&gt;
|This class handles tabulated spacecraft states entries and implements PVCoordinatesProvider interface. Tabulated entries are chronologically classified. A Lagrange interpolation is perfomed to compute PV coordinates at a given date. The class is an extension is based on a common Lagrange-Hermite approch provided by class &amp;lt;code&amp;gt;AbstractEphemerisPvHermiteLagrange&amp;lt;/code&amp;gt;.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/orbits/pvcoordinates/EphemerisPvLagrange.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EphemerisPvHermite&#039;&#039;&#039;&lt;br /&gt;
|This class handles tabulated spacecraft states entries and implements PVCoordinatesProvider interface. Tabulated entries are chronologically classified. A Hermite interpolation is perfomed to compute PV coordinates at a given date. The class is an extension is based on a common Lagrange-Hermite approch provided by class &amp;lt;code&amp;gt;AbstractEphemerisPvHermiteLagrange&amp;lt;/code&amp;gt;.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/orbits/pvcoordinates/EphemerisPvHermite.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;PVCoordinatesPropagator&#039;&#039;&#039;&lt;br /&gt;
|This class extends AbstractPropagator. It simply implements propagate orbit method using the getPVCoordinate from the PVCoordinate provider it handles. The propagator is initialized with given initial date, frame and mu to build a coherent initial spacecraftstate. This initialisation calls the PVCoordinateProvider getPVCoordinates method to the given date which can raise an error if the date is out of bound for exemple. This class will be basically used with &#039;&#039;&#039;EphemerisPvLagrange&#039;&#039;&#039; and &#039;&#039;&#039;EphemerisPvHermite&#039;&#039;&#039;. &lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/PVCoordinatesPropagator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SimpleAdditionalStateProvider&#039;&#039;&#039;&lt;br /&gt;
|This class implements AdditionalStateProvider interface. It simply handles a list of dates associated to additional state vectors. For a given date it returns the associated additional state vector or a propagation exception if this date is not found. This class will be basically used with &#039;&#039;&#039;PVCoordinatesPropagator&#039;&#039;&#039;. &lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/SimpleAdditionalStateProvider.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AlmanacPVCoordinates&#039;&#039;&#039;&lt;br /&gt;
|This class computes PV coordinates at any date from a GPS or Galileo Almanac. &lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/orbits/pvcoordinates/AlmanacPVCoordinates.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_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.17_Celestial_bodies&amp;diff=4094</id>
		<title>User Manual 4.17 Celestial bodies</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Celestial_bodies&amp;diff=4094"/>
		<updated>2025-11-27T09:34:46Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/bodies/mesh/GeodeticMeshLoader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_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.17_Events:_orbital&amp;diff=4093</id>
		<title>User Manual 4.17 Events: orbital</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Events:_orbital&amp;diff=4093"/>
		<updated>2025-11-27T09:24:38Z</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.17}}/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;
====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.17}}/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.17}}/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.17}}/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.17}}/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.17}}&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.17}}&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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/events/detectors/AnomalyDetector.html AnomalyDetector]&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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/events/EarthZoneDetector.html EarthZoneDetector]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
[[Category:User Manual 4.17 Mission]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Fichier:BodyPointSolarIncidenceDetector.png&amp;diff=4092</id>
		<title>Fichier:BodyPointSolarIncidenceDetector.png</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Fichier:BodyPointSolarIncidenceDetector.png&amp;diff=4092"/>
		<updated>2025-11-27T09:23:11Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;BodyPointSolarIncidenceDetector&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Events:_orbital&amp;diff=4091</id>
		<title>User Manual 4.17 Events: orbital</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Events:_orbital&amp;diff=4091"/>
		<updated>2025-11-27T09:19:57Z</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.17}}/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;
====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;
&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;
====SurfaceDistanceDetector====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;SurfaceDistanceDetector&amp;lt;/code&amp;gt; detects when the distance from the spacecraft to the surface of a given body reaches a predetermined value. The detector is constructed by providing the BodyShape whose distance is watched, the distance triggering the event and the distance type (CLOSEST or RADIAL). Other constructors are available to parametrize common detector attributes.&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.17}}/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.17}}/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.17}}/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.17}}/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.17}}&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.17}}&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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/events/detectors/AnomalyDetector.html AnomalyDetector]&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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/events/EarthZoneDetector.html EarthZoneDetector]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
[[Category:User Manual 4.17 Mission]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Root-Finding_Algorithms&amp;diff=4090</id>
		<title>User Manual 4.17 Root-Finding Algorithms</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Root-Finding_Algorithms&amp;diff=4090"/>
		<updated>2025-11-27T09:16:59Z</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;
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.17}}/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.17}}/fr/cnes/sirius/patrius/math/analysis/UnivariateFunction.html UnivariateFunction].&lt;br /&gt;
The root-finding algorithm is implemented through the [{{JavaDoc4.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Events:_sensors&amp;diff=4089</id>
		<title>User Manual 4.17 Events: sensors</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Events:_sensors&amp;diff=4089"/>
		<updated>2025-11-27T08:32:16Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;gallery&amp;gt;&lt;br /&gt;
Exemple.jpg|Description 1&lt;br /&gt;
Exemple.jpg|Description 2&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
Here are presented all the events detectors of the theme &amp;quot;sensors&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;
|Orekit &lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/events/package-summary.html Package fr.cnes.sirius.patrius.propagation.event]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/package-summary.html Package fr.cnes.sirius.patrius.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;
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;
=== g functions ===&lt;br /&gt;
This section describes the meaning of the g switching function for the &amp;quot;sensors&amp;quot; event detectors :&lt;br /&gt;
&lt;br /&gt;
==== CircularFieldOfViewDetector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function for the circular field of view is : &amp;lt;math&amp;gt;g=\alpha_{half aperture}-\alpha_{_{center-targetPosSat}}&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\vec {targetPosSat}&amp;lt;/math&amp;gt; is the satellite-target body vector in the satellite frame; &amp;lt;math&amp;gt;\alpha_{half aperture}&amp;lt;/math&amp;gt; is the fov half aperture angle and &amp;lt;math&amp;gt;\alpha_{center-targetPosSat}&amp;lt;/math&amp;gt; is the absolute value of the angle between target direction and field of view center.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g &amp;lt; 0 :&amp;lt;/math&amp;gt; the target body is outside the field of view:&lt;br /&gt;
[[File:circularfov1.png|555x336px]]&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g &amp;gt; 0 :&amp;lt;/math&amp;gt; the target body is inside the field of view:&lt;br /&gt;
[[File:circularfov2.png|547x311px]]&lt;br /&gt;
&lt;br /&gt;
==== CentralBodyMaskCircularFOVDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector is a combination of the previous circular field of view detector and the [MIS_ORB_Home#HPartialandTotaleclipsebyaspheroid eclipse detector] for an ellipsoid body.&amp;lt;br&amp;gt;&lt;br /&gt;
It detects the visibility only when the target is not eclipsed by the central body.&amp;lt;br&amp;gt;&lt;br /&gt;
The g switching function is : &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;g=min(circularFieldOfView, ellipsoidEclipse)&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== DihedralFieldOfViewDetector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function computes the distance between the target and the nearest boundary of the field of view. &amp;lt;br&amp;gt;&lt;br /&gt;
The double dihedral field of view is identified by the two following axes:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;axis_ {1}&amp;lt;/math&amp;gt; is the axis of the first dihedral (&amp;lt;math&amp;gt;\vec n_ {1}&amp;lt;/math&amp;gt; is its normal vector)&lt;br /&gt;
* &amp;lt;math&amp;gt;axis_ {2}&amp;lt;/math&amp;gt; is the axis of the second dihedral (&amp;lt;math&amp;gt;\vec n_ {2}&amp;lt;/math&amp;gt; is its normal vector)&lt;br /&gt;
If these 2 axes are orthogonal, we have a rectangular field of view. Otherwise, we have a trapezoidal field of view.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;center&amp;lt;/math&amp;gt; is the vector representing the fov center (intersection between the two dihedrals central planes).&amp;lt;br&amp;gt;&lt;br /&gt;
This axis must be obviously orthogonal to the 2 previous axis, but not necessarily in direct order.&lt;br /&gt;
&lt;br /&gt;
The value of the g function is computed in two steps:&lt;br /&gt;
&lt;br /&gt;
#computing the angular distance between the target body and the first dihedral, and then subtracting it from the fov first half-aperture angle; [[File:dihedralfov1.png]]&lt;br /&gt;
#computing the angular distance between the target body and the second dihedral, and then subtracting it from the fov second half-aperture angle; [[File:Bidihedral2.png]]&lt;br /&gt;
&lt;br /&gt;
The lowest distance is then chosen to compute the g function.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt; the target body is ouside the field of view;&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt; the target body is inside the field of view.&lt;br /&gt;
&lt;br /&gt;
==== TargetInFieldOfViewDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector is defined from a sensor of an assembly part (see the Spacecraft user manual for details on sensor models).&amp;lt;br&amp;gt;&lt;br /&gt;
A sensor can contain a spherical main target (PVCoordinatesProvider + radius) and a field of view (IFieldOfView) defined in the local frame of the sensor.&amp;lt;br&amp;gt;&lt;br /&gt;
The g function of this sensor is positive when AT LEAST A PART this target is in the field, negative otherwise. So it detects the times when the target first enters and totaly leaves the field.&amp;lt;br&amp;gt;&lt;br /&gt;
In order to proceed to this computation, the MAIN frame (and so all of the part&#039;s frames) is updated from the current SpacecraftState.&lt;br /&gt;
&lt;br /&gt;
==== SensorInhibitionDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector is defined from a sensor of an assembly part (see the Spacecraft user manual for details on sensor models).&amp;lt;br&amp;gt;&lt;br /&gt;
A sensor can contain an array of couples &amp;quot;inhibition target point&amp;quot; (PVCoordinatesProvider) / &amp;quot;inhibition field&amp;quot; (IFieldOfView) defined in the local frame of the sensor.&amp;lt;br&amp;gt;&lt;br /&gt;
The g function of this detector is positive when AT LEAST ONE of the inhibition target is AT LEAST PARTIALLY in its associated inhibition field. So it detects the first and last times of inhibition.&amp;lt;br&amp;gt;&lt;br /&gt;
In order to proceed to this computation, the MAIN frame (and so all of the part&#039;s frames) is updated from the current SpacecraftState.&lt;br /&gt;
&lt;br /&gt;
==== MaskingDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector is defined from a sensor of an assembly part (see the Spacecraft user manual for details on sensor models).&amp;lt;br&amp;gt;&lt;br /&gt;
A sensor model can have a list of masking objects. Those objects are :&lt;br /&gt;
&lt;br /&gt;
* Parts of the same spacecraft (that must have A GEOMETRY property)&lt;br /&gt;
* Parts of others spacecrafts, built as [MIS_SENSORS_SecondSpc SecondarySpacecraft] objects (that must have A GEOMETRY property)&lt;br /&gt;
* Celestial bodies, built as a [MIS_SENSORS_PatriusBodySpheroid BodyShape] objects. &amp;lt;br&amp;gt;The g function of this detector is positive when AT LEAST ONE of the potentially masking bodies masks the target, negative otherwise. &amp;lt;br&amp;gt;The masking happens when the line&lt;br /&gt;
segment between the sensor and the target&#039;s center is cut between them by the shape of the masking object. &amp;lt;br&amp;gt;The &amp;quot;getMaskingObjectName&amp;quot; method allows the user to know wich one of the masking objects realises the masking event when occuring.&lt;br /&gt;
&lt;br /&gt;
==== SensorVisibilityDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector is defined from a sensor of an assembly part (see the Spacecraft user manual for details on sensor models).&amp;lt;br&amp;gt;&lt;br /&gt;
It is based on the three previous ones : the g function is positive when the main target is IN the field of view AND ALL of the inhibition targets are OUT of their associated inhibition field, AND NO masking object cuts the sensor / target center line segment. When used with earth ellipsoid, the computation of sight axis local elevation on earth uses a rapid algorithm with limited accuracy : typically 1.3e-4 degrees (worst case, satellite altitude 250 Km, latitude 45 deg., East sight direction) if sight axis is 25 degrees above horizon, and 1.4e-6 degrees (worst case) if sight axis is 0,25 degrees above horizon.&lt;br /&gt;
The target’s sensor can either be defined as the signal emitter or receiver in the appropriated constructor.&lt;br /&gt;
&lt;br /&gt;
==== ExtremaSightAxisDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector detects local extrema angle between the sight axis of a part having the SENSOR property and a given target. The target is a PVCoordinatesProvder, it means that it can be a point on the central body (TopocentricFrame) or another vehicle (Propagator).&lt;br /&gt;
&lt;br /&gt;
This detector doesn&#039;t take into account masking by the earth.&lt;br /&gt;
&lt;br /&gt;
This detector has also been design to work without assembly and part. In this case, the sight axis is given as a Vector3D and is apply to the origin of the orbital local frame taking attitude into account.&lt;br /&gt;
&lt;br /&gt;
The switching function is based on the extrema three body angle detector where P1 is the target, P2 is the origin of the frame (sensor part frame, or orbital local frame) and P3 is the sight axis.&lt;br /&gt;
&lt;br /&gt;
See the [SPC_Home Spacecraft] user manual for details about sensor models and the [MIS_ORB_Home Orbit determination detectors] user manual for details about extrema three bodies angle detector.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039;: for the detection of events linked to the sight axis of an instrument, see also &amp;lt;code&amp;gt;CircularFieldOfViewDetector&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;CentralBodyMaskCircularFOVDetector&amp;lt;/code&amp;gt;; they detect the passing of the sight axis close to a target (on ground, fixed or moving target, satellite, celestial body) taking account of the masking by the Earth. Events of the &amp;lt;code&amp;gt;ExtremaSigthAxisDetector&amp;lt;/code&amp;gt; can also be filtered with phenomena detected with &amp;lt;code&amp;gt;CentralBodyMaskCircularFOVDetector&amp;lt;/code&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;
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;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector ]&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;
| CircularFieldOfViewDetector&lt;br /&gt;
|This class handles target entry/exit events with respect to a satellite sensor circular field of view.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/events/CircularFieldOfViewDetector.html CircularFieldOfViewDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CentralBodyMaskCircularFOVDetector&lt;br /&gt;
|This class handles target entry/exit events with respect to a satellite sensor circular field of view taking central body masking into account.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/CentralBodyMaskCircularFOVDetector.html CentralBodyMaskCircularFOVDetector]&lt;br /&gt;
|-&lt;br /&gt;
| DihedralFieldOfViewDetector&lt;br /&gt;
|This class handles target entry/exit events with respect to a satellite sensor dihedral field of view.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/events/DihedralFieldOfViewDetector.html DihedralFieldOfViewDetector]&lt;br /&gt;
|-&lt;br /&gt;
| TargetInFieldOfViewDetector &lt;br /&gt;
|This class handles events representing the time when the main target of a sensor enters the field of view.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/sensor/TargetInFieldOfViewDetector.html TargetInFieldOfViewDetector]&lt;br /&gt;
|-&lt;br /&gt;
| SensorInhibitionDetector &lt;br /&gt;
|This class handles events representing the time when at least one of the the inhibition target of a sensor enters the field of view.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/sensor/SensorInhibitionDetector.html SensorInhibitionDetector ]&lt;br /&gt;
|-&lt;br /&gt;
| MaskingDetector &lt;br /&gt;
|This class handles events representing the time when at least one of the potentially masking objects that have been set to the sensor model is cutting the sensor / target center line segment.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/sensor/MaskingDetector.html MaskingDetector]&lt;br /&gt;
|-&lt;br /&gt;
| SensorVisibilityDetector &lt;br /&gt;
|This class handles events representing the time when, at the same time, 1) the main target of a sensor enters the field of view, 2) masking objects that have been set to the sensor model are not cutting the sensor/target center line segment and 3) no inhibition target is in its inhibition field.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/sensor/SensorVisibilityDetector.html SensorVisibilityDetector ]&lt;br /&gt;
|-&lt;br /&gt;
| ExtremaSightAxisDetector &lt;br /&gt;
|This class handles events representing extrema of the angular angle between a sight axis on a vehicle and a target. This doesn&#039;t take into account eventual masking from any occulting body even from central body. &lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/sensor/ExtremaSightAxisDetector.html ExtremaSightAxisDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Data_management_system&amp;diff=4088</id>
		<title>User Manual 4.17 Data management system</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Data_management_system&amp;diff=4088"/>
		<updated>2025-11-27T08:30:21Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec «  == Introduction == === Scope === The scope of this chapter is to present data management. This section presents the three modules of the data management system originally provided by Orekit :  * how does the data management system work? * how to set it up? * how to use it? * how to add data to what already exists? * what are the pros and cons of this system?  === Javadoc === The data objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.data&amp;lt;/code&amp;gt;.... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
The scope of this chapter is to present data management. This section presents the three modules of the data management system originally provided by Orekit :&lt;br /&gt;
&lt;br /&gt;
* how does the data management system work?&lt;br /&gt;
* how to set it up?&lt;br /&gt;
* how to use it?&lt;br /&gt;
* how to add data to what already exists?&lt;br /&gt;
* what are the pros and cons of this system?&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The data objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.data&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;
| Orekit&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/package-summary.html Package fr.cnes.sirius.patrius.data]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
{{specialInclusion prefix=$theme_sub section=&amp;quot;Links&amp;quot;/}}&lt;br /&gt;
&lt;br /&gt;
=== Useful Documents ===&lt;br /&gt;
{{specialInclusion prefix=$theme_sub section=&amp;quot;UsefulDocs&amp;quot;/}}&lt;br /&gt;
&lt;br /&gt;
=== Package Overview ===&lt;br /&gt;
The data loading process is organized through three main objects.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;DataProvider&amp;lt;/code&amp;gt; classes handle data sources. Each one of them has a particular type of source it can browse. The &amp;lt;code&amp;gt;DirectoryCrawler&amp;lt;/code&amp;gt; performs a bottom-first search in a directory tree. The &amp;lt;code&amp;gt;ZipJarCrawler&amp;lt;/code&amp;gt; works alike, but inside a compressed file. The &amp;lt;code&amp;gt;ClassPathCrawler&amp;lt;/code&amp;gt; handles a list of data files and/or compressed files that are in the classpath (it can not search recursively like the &amp;lt;code&amp;gt;DirectoryCrawler&amp;lt;/code&amp;gt; though). Finally, the &amp;lt;code&amp;gt;NetworkCrawler&amp;lt;/code&amp;gt; works like the &amp;lt;code&amp;gt;ClassPathCrawler&amp;lt;/code&amp;gt;, although in its case, it has a list of URLs instead of files. There is no limit to the number of DataProviders a program can use at once.&lt;br /&gt;
&lt;br /&gt;
The Providers are listed and put to work through the &amp;lt;code&amp;gt;DataProvidersManager&amp;lt;/code&amp;gt; singleton. This is the single point of access to the data management system. It contains a list of Providers that are queried every time a user needs data.&lt;br /&gt;
&lt;br /&gt;
The various crawlers provide streams to the &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt;. From these streams, the DataLoaders can reconstruct data that was stored in files (either compressed or not), even if some files come from different sources. These streams effectively separate the machine world from the program world, because they hide the former to the latter. Therefore, parsing data from a new format only means creating a loader, and being able to read another kind of file means creating a &amp;lt;code&amp;gt;DataProvider&amp;lt;/code&amp;gt;. Note that the DataLoaders usually serve as a facade for the higher layers of the program.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
&lt;br /&gt;
=== Data providers ===&lt;br /&gt;
&lt;br /&gt;
==== Default provider ====&lt;br /&gt;
The data management system can use a system-wide property, &amp;lt;code&amp;gt;orekit.data.path&amp;lt;/code&amp;gt;, as an entry point for default data. This default data must be file-based (either a file system entry point or a java resource) and either a directory or a zip/jar file.&lt;br /&gt;
Setting a default provider is not mandatory, and must be done explicitly by :&lt;br /&gt;
&lt;br /&gt;
* setting a value to &amp;lt;code&amp;gt;orekit.data.path&amp;lt;/code&amp;gt;,&lt;br /&gt;
* calling &amp;lt;code&amp;gt;addDefaultProviders&amp;lt;/code&amp;gt; on the data provider manager.&lt;br /&gt;
&lt;br /&gt;
==== Adding a provider ====&lt;br /&gt;
{{specialInclusion prefix=$theme_sub section=&amp;quot;Provider&amp;quot;/}}&lt;br /&gt;
&lt;br /&gt;
==== Using the data management system ====&lt;br /&gt;
The data management system main operation is through the &amp;lt;code&amp;gt;feed&amp;lt;/code&amp;gt; method. This method takes a &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt;, and a regexp string matching the name of files the &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt; is able to process. In this method call :&lt;br /&gt;
&lt;br /&gt;
* the &amp;lt;code&amp;gt;DataProviders&amp;lt;/code&amp;gt; list is traversed in the priority order.&lt;br /&gt;
* the first &amp;lt;code&amp;gt;DataProvider&amp;lt;/code&amp;gt; providing a file matching the regexp is the one (and only) used to feed the &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==== Adding new data ====&lt;br /&gt;
{{specialInclusion prefix=$theme_sub section=&amp;quot;Adding&amp;quot;/}}&lt;br /&gt;
&lt;br /&gt;
=== File formats ===&lt;br /&gt;
Patrius can read a variety of files:&lt;br /&gt;
* &#039;&#039;&#039;Static potential files&#039;&#039;&#039;&lt;br /&gt;
These files contains static potential coefficients up to a certain order and degree and are used to compute Earth (or any other body) static potential perturbation.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Variable potential files&#039;&#039;&#039;&lt;br /&gt;
Theses files contains variable potential coefficients up to a certain order and degree and are used to compute Earth (or any other body) variable potential perturbation.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Geomagnetic coefficients files&#039;&#039;&#039;&lt;br /&gt;
These files contains geomagnetic coefficients and are used to compute Earth (or any other body) geomagnetic field.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Ionospheric coefficients files&#039;&#039;&#039;&lt;br /&gt;
These files contains ionospheric data and are used to compute Earth ionospheric correction.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Solar activity files&#039;&#039;&#039;&lt;br /&gt;
These files contains solar flux and geomagnetic coefficients are used to get solar activity in order to compute drag perturbation.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Earth Orientation Parameters files&#039;&#039;&#039;&lt;br /&gt;
These files contains earth orientation parameters (polar motion, LOD, etc.) used in frames transformation.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;TAI-UTC shift files&#039;&#039;&#039;&lt;br /&gt;
These files contains TAI-TUC shift.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Orbital data files&#039;&#039;&#039;&lt;br /&gt;
These files are used to store orbital ephemeris&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Third body ephemeris files&#039;&#039;&#039;&lt;br /&gt;
These files are used to store third-body orbital ephemeris (Sun, Moon, etc.)&lt;br /&gt;
&lt;br /&gt;
The following sections describe all file readable in PATRIUS. When the file format is not described anywhere, a short description is detailed below the tab.&lt;br /&gt;
&lt;br /&gt;
==== Static Potential ====&lt;br /&gt;
&lt;br /&gt;
Static potential coefficients files contains potential coefficients up to a certain order and degree.&amp;lt;br&amp;gt;&lt;br /&gt;
Warning: at very high order and degree (&amp;gt; 100), some numerical quality issues can appear and results may be degraded.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GRGS&#039;&#039;&#039;&lt;br /&gt;
|Not direct link. This link provides GRGC potential coefficients [http://grgs.obs-mip.fr/grace/variable-models-grace-lageos/interactive-tools/Check-individual-solutions]&lt;br /&gt;
|[http://grgs.obs-mip.fr/grace/variable-models-grace-lageos/formats]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/potential/GRGSFormatReader.html GRGSFormatReader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EGM&#039;&#039;&#039;&lt;br /&gt;
|[http://earth-info.nga.mil/GandG/wgs84/gravitymod/egm2008/first_release.html]&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/potential/EGMFormatReader.html EGMFormatReader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ICGEM&#039;&#039;&#039;&lt;br /&gt;
|[http://icgem.gfz-potsdam.de/tom_longtime]&lt;br /&gt;
|[http://icgem.gfz-potsdam.de/ICGEM-Format-2011.pdf]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/potential/ICGEMFormatReader.html ICGEMFormatReader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SHM&#039;&#039;&#039;&lt;br /&gt;
|Not provided (not used any more, replaced by ICGEM format)&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/potential/SHMFormatReader.html SHMFormatReader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EGM file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Degree of coefficients&amp;lt;br&amp;gt;&lt;br /&gt;
2:Order of coefficients&amp;lt;br&amp;gt;&lt;br /&gt;
3:Tesseral-sectorial cosinus coefficient&amp;lt;br&amp;gt;&lt;br /&gt;
4:Tesseral-sectorial sinus coefficient&amp;lt;br&amp;gt;&lt;br /&gt;
5:Sigma applied to the cosinus&amp;lt;br&amp;gt;&lt;br /&gt;
6:Sigma applied to the sinus&lt;br /&gt;
&lt;br /&gt;
[[File:EGM.png|center]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SHM file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
2:Degree of coefficients&amp;lt;br&amp;gt;&lt;br /&gt;
3:Order of coefficients&amp;lt;br&amp;gt;&lt;br /&gt;
4:Tesseral-sectorial cosinus coefficient&amp;lt;br&amp;gt;&lt;br /&gt;
5:Tesseral-sectorial sinus coefficient&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:SHM.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== Variable Potential ====&lt;br /&gt;
&lt;br /&gt;
Variable potential coefficients files contains potential coefficients up to a certain order and degree.&amp;lt;br&amp;gt;&lt;br /&gt;
Warning: at very high order and degree (&amp;gt; 100), some numerical quality issues can appear and results may be degraded.&lt;br /&gt;
&lt;br /&gt;
FES2004 is used to model oceanic tides.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GRGSRL02&#039;&#039;&#039;&lt;br /&gt;
|[http://grgs.obs-mip.fr/grace/variable-models-grace-lageos/interactive-tools/Check-individual-solutions]&lt;br /&gt;
|[http://grgs.obs-mip.fr/grace/variable-models-grace-lageos/formats]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/variations/coefficients/GRGSRL02FormatReader.html GRGSRL02FormatReader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;FES2004&#039;&#039;&#039;&lt;br /&gt;
|[https://www.aviso.altimetry.fr/en/data/products/auxiliary-products/global-tide-fes.html]&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/gravity/tides/coefficients/FES2004FormatReader.html FES2004FormatReader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;FES2004 file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Doodson number&amp;lt;br&amp;gt;&lt;br /&gt;
2:Darwin number&amp;lt;br&amp;gt;&lt;br /&gt;
3:Degree of coefficients &amp;lt;br&amp;gt;&lt;br /&gt;
4:Order of coefficients&amp;lt;br&amp;gt;&lt;br /&gt;
5:Sinus coefficient positif&amp;lt;br&amp;gt;&lt;br /&gt;
6:Cosinus coefficient positif&amp;lt;br&amp;gt;&lt;br /&gt;
7:Sinus coefficient negatif&amp;lt;br&amp;gt;&lt;br /&gt;
8:Cosinus coefficient negatif&amp;lt;br&amp;gt;&lt;br /&gt;
9:Positif coefficient&amp;lt;br&amp;gt;&lt;br /&gt;
10:Epsilon positif&amp;lt;br&amp;gt;&lt;br /&gt;
11:Negatif coefficient&amp;lt;br&amp;gt;&lt;br /&gt;
12:Negatif epsilon&lt;br /&gt;
&lt;br /&gt;
[[File:FES2004.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== Geomagnetic coefficients ====&lt;br /&gt;
&lt;br /&gt;
Geomagnetic coefficients fiels contains geomagnetic coefficients up to a certain order and degree.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;COF&#039;&#039;&#039;&lt;br /&gt;
|IGCRF data: [https://www.ngdc.noaa.gov/IAGA/vmod/igrf.html] WMM data: [https://www.ngdc.noaa.gov/geomag/WMM/soft.shtml]&lt;br /&gt;
|See below &lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/models/earth/COFFileFormatReader.html COFFileFormatReader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;COF file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Degree of coefficients &amp;lt;br&amp;gt;&lt;br /&gt;
2:Order of coefficients&amp;lt;br&amp;gt;&lt;br /&gt;
3:g coefficient at position n,m&amp;lt;br&amp;gt;&lt;br /&gt;
4:h coefficient at position n,m&amp;lt;br&amp;gt;&lt;br /&gt;
5:dg coefficient at position n,m&amp;lt;br&amp;gt;&lt;br /&gt;
6:dh coefficient at position n,m&amp;lt;br&amp;gt;&lt;br /&gt;
g and h are the Gauss coefficients of main geomagnetic model (nT)&amp;lt;br&amp;gt;&lt;br /&gt;
dg and dh are the Gauss coefficients of secular geomagnetic model (nT/years)&lt;br /&gt;
&lt;br /&gt;
[[File:COF.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== Ionospheric coefficients ====&lt;br /&gt;
&lt;br /&gt;
Ionospheric coefficients files contains ionospheric coefficient to model the state of the ionosphere.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CCIR12&#039;&#039;&#039;&lt;br /&gt;
|N/A&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/signalpropagation/iono/R12Loader.html R12Loader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;USK(NEWUSK)&#039;&#039;&#039;&lt;br /&gt;
|N/A&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/signalpropagation/iono/USKLoader.html USKLoader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CCIR12 file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Year &amp;lt;br&amp;gt;&lt;br /&gt;
2:Month&amp;lt;br&amp;gt;&lt;br /&gt;
3:Unused&amp;lt;br&amp;gt;&lt;br /&gt;
4:Midval&amp;lt;br&amp;gt;&lt;br /&gt;
5:Unused&amp;lt;br&amp;gt;&lt;br /&gt;
6:Midday&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:CCIR12.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;USK file format&#039;&#039;&#039; (&#039;&#039;Line text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
[[File:NEWUSK.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== Solar activity ====&lt;br /&gt;
&lt;br /&gt;
Solar activity contains solar flux and geomagnetic coefficients for a given timespan. ACSOL and NOAA files usually provide data for several years.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ACSOL&#039;&#039;&#039;&lt;br /&gt;
|N/A&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/ACSOLFormatReader.html ACSOLFormatReader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NOAA&#039;&#039;&#039;&lt;br /&gt;
|N/A&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/forces/atmospheres/solarActivity/NOAAFormatReader.html NOAAFormatReader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ACSOL file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Julian day since 1950&amp;lt;br&amp;gt;&lt;br /&gt;
2:Seconds of the day (UTC)&amp;lt;br&amp;gt;&lt;br /&gt;
3:Flux at JD + seconds&amp;lt;br&amp;gt;&lt;br /&gt;
4-11 are the three-hours AP of the intervals &lt;br /&gt;
&lt;br /&gt;
[[File:ACSOL.png|center]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOAA file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Day&amp;lt;br&amp;gt;&lt;br /&gt;
2:Flux at the day&amp;lt;br&amp;gt;&lt;br /&gt;
3:The background flux &amp;lt;br&amp;gt;&lt;br /&gt;
4-11:the three-hours AP of the intervals &amp;lt;br&amp;gt;&lt;br /&gt;
12:Year&amp;lt;br&amp;gt;&lt;br /&gt;
13:Unused character flag&lt;br /&gt;
&lt;br /&gt;
==== Pole data ====&lt;br /&gt;
&lt;br /&gt;
These files contains earth orientation parameters (polar motion, LOD, etc.) used in frames transformation.&amp;lt;br&amp;gt;&lt;br /&gt;
These data are usually valid of a timespan of several days/months, although there is no theoretical limit.&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;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Bulletin B&#039;&#039;&#039;&lt;br /&gt;
|[ftp://hpiers.obspm.fr/iers/bul/bulb_new]&lt;br /&gt;
|[ftp://hpiers.obspm.fr/iers/bul/bulb_new/bulletinb.pdf]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/frames/configuration/eop/BulletinBFilesLoader.html BulletinBFilesLoader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EOP 05 C04&#039;&#039;&#039;&lt;br /&gt;
|[ftp://hpiers.obspm.fr/iers/eop/eopc04_05]&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOP05C04FilesLoader.html EOP05C04FilesLoader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;EOP 08 C04&#039;&#039;&#039;&lt;br /&gt;
|[https://datacenter.iers.org/web/guest/eop/-/somos/5Rgv/version/212]&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOP08C04FilesLoader.html EOP08C04FilesLoader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Datas &amp;quot;Rapid and Prediction&amp;quot; (TXT)&#039;&#039;&#039;&lt;br /&gt;
|[http://maia.usno.navy.mil/ser7]&lt;br /&gt;
|[http://maia.usno.navy.mil/ser7/readme.finals]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/frames/configuration/eop/RapidDataAndPredictionColumnsLoader.html RapidDataAndPredictionColumnsLoader]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Datas &amp;quot;Rapid and Prediction&amp;quot; (XML)&#039;&#039;&#039;&lt;br /&gt;
|[https://datacenter.iers.org/eop/-/somos/5Rgv/eop?]&lt;br /&gt;
|Same datas than the column file but write in the xml format&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/frames/configuration/eop/RapidDataAndPredictionXMLLoader.html RapidDataAndPredictionXMLLoader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;EOP 05 C04 and EOP 08 C04 files format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Date at 0h(UTC)&amp;lt;br&amp;gt;&lt;br /&gt;
2:Modified Julian Day&amp;lt;br&amp;gt;&lt;br /&gt;
3:x(&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
4:y(&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
5:UT1-UTC(s)&amp;lt;br&amp;gt;&lt;br /&gt;
6:LOD(s)&amp;lt;br&amp;gt;&lt;br /&gt;
7:DPsi(&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
8:DEps(&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
9:x error (&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
10:y error (&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
11:UT1-UTC error (s)&amp;lt;br&amp;gt;&lt;br /&gt;
12:LOD error(s)&amp;lt;br&amp;gt;&lt;br /&gt;
13:Dpsi error(&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
14:DEpsilon error(&amp;quot;)&amp;lt;br&amp;gt;&lt;br /&gt;
x and y are the coordinales of the Celestial Ephemeris Pole.&amp;lt;br&amp;gt;&lt;br /&gt;
UT1: Universal time, the time of the earth clock&amp;lt;br&amp;gt;&lt;br /&gt;
LOD: Length Of Day is the excess of revolution time&lt;br /&gt;
&lt;br /&gt;
[[File:EOP08C04.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== TAI-UTC shift====&lt;br /&gt;
&lt;br /&gt;
These files contains TAI-TUC shift. Official data contains shift since the beginning of space era (1961).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Gap TAI-UTC&#039;&#039;&#039;&lt;br /&gt;
|[ftp://hpiers.obspm.fr/iers/bul/bulc/UTC-TAI.history]&lt;br /&gt;
|See below&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/time/UTCTAIHistoryFilesLoader.html UTCTAIHistoryFilesLoader]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TAI-UTC file format&#039;&#039;&#039; (&#039;&#039;Column text file&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Column index:&amp;lt;br&amp;gt;&lt;br /&gt;
1:Begining date-Ending date&amp;lt;br&amp;gt;&lt;br /&gt;
2:Difference TAI-UTC between the begining date and the ending date&lt;br /&gt;
&lt;br /&gt;
[[File:TAI-TUC.png|center]]&lt;br /&gt;
&lt;br /&gt;
==== Orbital data ====&lt;br /&gt;
&lt;br /&gt;
These files are used to store orbital ephemeris.&amp;lt;br&amp;gt;&lt;br /&gt;
TLE provides orbit at one date. Ephemeris is then retrieved thanks to SGP4/SDP4 propagation model.&amp;lt;br&amp;gt;&lt;br /&gt;
SP3 files provide orbit over an extended time span (ex: 1 day).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TLE&#039;&#039;&#039;&lt;br /&gt;
|[https://www.projectpluto.com/pluto/mpecs/pseudo.htm]&lt;br /&gt;
|[https://www.mmto.org/obscats/tle.html]&lt;br /&gt;
[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/propagation/analytical/tle/TLESeries.html TLESeries]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;SP3&#039;&#039;&#039;&lt;br /&gt;
|GPS and GLONASS only [ftp://cddis.gsfc.nasa.gov/gnss/products]&lt;br /&gt;
|[ftp://igs.org/pub/data/format/sp3_docu.txt]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/files/sp3/SP3File.html SP3File]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: * SP3 files can be written by anyone. They are however mainly used ton provide GPS and GLONASS ephemeris.&lt;br /&gt;
&lt;br /&gt;
Note2: * If the accuracy is not present in the SP3 file, a value of 0 automatically given. This allows the parsing of the SP3 to continue while giving the user the information that the accuracy field was not read (0 is an impossible value since the accuracy is given as 2^n). &lt;br /&gt;
&lt;br /&gt;
==== Third body ephemeris ====&lt;br /&gt;
&lt;br /&gt;
Third body ephemeris files contains ephemeris for third bodies (Moon, Sun, Jupiter) over an extended time span (ex: 1 or several days).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Data provider&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Format&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Reader&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;JPL&#039;&#039;&#039;&lt;br /&gt;
|[https://ssd.jpl.nasa.gov/pub/eph/planets/SunOS]&lt;br /&gt;
|[https://ssd.jpl.nasa.gov/pub/eph/planets/Linux]&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/bodies/JPLCelestialBodyLoader.html JPLCelestialBodyLoader]&lt;br /&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 data package includes the following interfaces :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data&#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;DataLoader&#039;&#039;&#039;&lt;br /&gt;
|Interface for loading data files from DataProvider data providers.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/DataLoader.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DataProvider&#039;&#039;&#039;&lt;br /&gt;
|Interface for providing data files to DataLoader file loaders.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/DataProvider.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
The data package includes the following classes :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Data&#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;DataProvidersManager&#039;&#039;&#039;&lt;br /&gt;
|This class is the single point of access for all data loading features.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/DataProvidersManager.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;DirectoryCrawler&#039;&#039;&#039;&lt;br /&gt;
|This class handles data files recursively starting from a root directories.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/DirectoryCrawler.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;NetworkCrawler&#039;&#039;&#039;&lt;br /&gt;
|This class handles a list of URLs pointing to data files or zip/jar on the net.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/NetworkCrawler.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ZipJarCrawler&#039;&#039;&#039;&lt;br /&gt;
|This class browses all entries in a zip/jar archive in filesystem or in classpath.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/data/ZipJarCrawler.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== [[File:lightBulb.png]] Tips &amp;amp;amp; Tricks ==&lt;br /&gt;
=== Strengths ===&lt;br /&gt;
&lt;br /&gt;
* Lightweight implementation. The providers never load data, they merely provide streams on demand to the loaders.&lt;br /&gt;
* Scalable for using data from several heterogeneous sources.&lt;br /&gt;
* Scalable for new data types : the user only needs to create a new &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt; implementation to use a new data type in this system.&lt;br /&gt;
&lt;br /&gt;
=== Weaknesses ===&lt;br /&gt;
&lt;br /&gt;
* The user must be aware the data loading overhead happens any time a &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt; is fed, so the user must manage its loaders so that they are fed only once.&lt;br /&gt;
* Several sources for the same type of data cannot be used, since only the last provider added is used to feed data to a loader - unless the user manages the providers list accordingly, knowing one can only add elements or reset the whole list.&lt;br /&gt;
* The regexp is the only way to match a data file and a &amp;lt;code&amp;gt;DataLoader&amp;lt;/code&amp;gt;.&lt;br /&gt;
* As of today, the data management system is a thread-hostile singleton : a multithreaded application shares the same providers list for all threads, and it may deadlock on a concurrent access!&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Accueil&amp;diff=4087</id>
		<title>Accueil</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Accueil&amp;diff=4087"/>
		<updated>2025-11-26T14:01:08Z</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.17 ==&lt;br /&gt;
&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; V4.17 is a release adding a few features as well as correcting some bugs (see [[Main_differences_between_V4.15_and_V4.14|here]]).&lt;br /&gt;
&lt;br /&gt;
== PREVIOUS VERSIONS (available on the Web site) ==&lt;br /&gt;
&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.17 Current Java Doc]&lt;br /&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=Cat%C3%A9gorie:User_Manual_4.17&amp;diff=4086</id>
		<title>Catégorie:User Manual 4.17</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.17&amp;diff=4086"/>
		<updated>2025-11-26T13:58:20Z</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.17_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.17_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.17_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.17_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.17_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.17_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.17_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.17_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.17|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.17|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.17&amp;diff=4085</id>
		<title>Catégorie:Patrius Backward Compatibility 4.17</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Patrius_Backward_Compatibility_4.17&amp;diff=4085"/>
		<updated>2025-11-26T13:58:03Z</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.17]]&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.17&amp;diff=4084</id>
		<title>Catégorie:Thread Safety 4.17</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Thread_Safety_4.17&amp;diff=4084"/>
		<updated>2025-11-26T13:57:41Z</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.17]]&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.17_Attitude&amp;diff=4083</id>
		<title>Catégorie:User Manual 4.17 Attitude</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.17_Attitude&amp;diff=4083"/>
		<updated>2025-11-26T13:56:48Z</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.17]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Slew&amp;diff=4082</id>
		<title>User Manual 4.17 Slew</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Slew&amp;diff=4082"/>
		<updated>2025-11-26T13:56: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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/attitudes/slew/IsisSpinBiasSlewComputer.html IsisSpinBiasSlewComputer]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Rotation,_AngularCoordinates,_Tranform_and_Attitude_:_how_to_use_them&amp;diff=4081</id>
		<title>User Manual 4.17 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.17_Rotation,_AngularCoordinates,_Tranform_and_Attitude_:_how_to_use_them&amp;diff=4081"/>
		<updated>2025-11-26T13:56:20Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Attitude_law&amp;diff=4080</id>
		<title>User Manual 4.17 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Attitude_law&amp;diff=4080"/>
		<updated>2025-11-26T13:56:05Z</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.17}}/fr/cnes/sirius/patrius/attitudes/package-summary.html Package fr.cnes.sirius.patrius.attitudes] |- |Patrius |[{{JavaDoc4.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Attitude_leg&amp;diff=4079</id>
		<title>User Manual 4.17 Attitude leg</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Attitude_leg&amp;diff=4079"/>
		<updated>2025-11-26T13:55: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 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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/attitudes/RelativeTabulatedAttitudeLeg.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Attitude_Profile&amp;diff=4078</id>
		<title>User Manual 4.17 Attitude Profile</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Attitude_Profile&amp;diff=4078"/>
		<updated>2025-11-26T13:55:33Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/guidance/AngularVelocitiesPolynomialProfileLeg.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Directions&amp;diff=4077</id>
		<title>User Manual 4.17 Directions</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Directions&amp;diff=4077"/>
		<updated>2025-11-26T13:55:18Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/attitudes/directions/EarthToCelestialBodyCenterDirection.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Kinematics&amp;diff=4076</id>
		<title>User Manual 4.17 Kinematics</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Kinematics&amp;diff=4076"/>
		<updated>2025-11-26T13:54:50Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/attitudes/kinematics/AbstractVector3DFunction.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Orientation&amp;diff=4075</id>
		<title>User Manual 4.17 Orientation</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Orientation&amp;diff=4075"/>
		<updated>2025-11-26T13:54:10Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/attitudes/OrientationAngleProfileSequence.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_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.17_Flight_Dynamics&amp;diff=4074</id>
		<title>Catégorie:User Manual 4.17 Flight Dynamics</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.17_Flight_Dynamics&amp;diff=4074"/>
		<updated>2025-11-26T13:52:03Z</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.17]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Orbits&amp;diff=4073</id>
		<title>User Manual 4.17 Orbits</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Orbits&amp;diff=4073"/>
		<updated>2025-11-26T13:51:42Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/orbits/ApsisOrbit.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_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.17_SpacecraftState&amp;diff=4072</id>
		<title>User Manual 4.17 SpacecraftState</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_SpacecraftState&amp;diff=4072"/>
		<updated>2025-11-26T13:51:23Z</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.17}}//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.17}}//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.17}}/fr/cnes/sirius/patrius/propagation/SpacecraftState.html SpacecraftState] is composed of :&amp;lt;br&amp;gt;&lt;br /&gt;
- an [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/orbits/Orbit.html orbit]&amp;lt;br&amp;gt;&lt;br /&gt;
- an [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/attitudes/Attitude.html attitude for forces computation] &amp;lt;br&amp;gt;&lt;br /&gt;
- an [{{JavaDoc4.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/propagation/SpacecraftState.html SpacecraftState] is composed of one [{{JavaDoc4.17}}/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.17}}/fr/cnes/sirius/patrius/attitudes/Attitude.html Attitude] or two different [{{JavaDoc4.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/frames/Frame.html Frame] to local orbital frame ([{{JavaDoc4.17}}/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.17}}//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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/attitudes/Attitude.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_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.17_Time&amp;diff=4071</id>
		<title>User Manual 4.17 Time</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Time&amp;diff=4071"/>
		<updated>2025-11-26T13:51:09Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17_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.17_Celestial_bodies&amp;diff=4070</id>
		<title>User Manual 4.17 Celestial bodies</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Celestial_bodies&amp;diff=4070"/>
		<updated>2025-11-26T13:50:47Z</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.17}}/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.17}}/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.17}}/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;
=== Body shapes ===&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;
==== 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;
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;
==== BodyShape and OneAxisEllipsoid ====&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.&lt;br /&gt;
See the [MIS_SENSORS_PatriusBodySpheroid specific page] for more details.&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; methods which provides the local radius from an object and an occulted body using an approximate iterative algorithm. This method is to be used only by &amp;lt;code&amp;gt;EclipseDetector&amp;lt;/code&amp;gt;.&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;BodyShape&#039;&#039;&#039;&lt;br /&gt;
|Interface representing the rigid surface shape of a natural body.&lt;br /&gt;
|[{{JavaDoc4.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/bodies/OneAxisEllipsoid.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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/bodies/mesh/GeodeticMeshLoader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_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.17_Frames&amp;diff=4069</id>
		<title>User Manual 4.17 Frames</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Frames&amp;diff=4069"/>
		<updated>2025-11-26T13:50:32Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17_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.17_Frames_configuration&amp;diff=4068</id>
		<title>User Manual 4.17 Frames configuration</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Frames_configuration&amp;diff=4068"/>
		<updated>2025-11-26T13:50:17Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOPHistory.html EOPHistory] interface represents EOP data. It has two implementations : [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOP1980History.html EOP1980History] and [{{JavaDoc4.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOPC04FilesLoader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_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.17_Orbital_parameters&amp;diff=4067</id>
		<title>User Manual 4.17 Orbital parameters</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Orbital_parameters&amp;diff=4067"/>
		<updated>2025-11-26T13:49:56Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/orbits/orbitalparameters/ReentryParameters.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_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.17_Mathematics&amp;diff=4066</id>
		<title>Catégorie:User Manual 4.17 Mathematics</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.17_Mathematics&amp;diff=4066"/>
		<updated>2025-11-26T13:48:02Z</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, making 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.17]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Trigonometric_Polynomials_and_Fourier_Series&amp;diff=4065</id>
		<title>User Manual 4.17 Trigonometric Polynomials and Fourier Series</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Trigonometric_Polynomials_and_Fourier_Series&amp;diff=4065"/>
		<updated>2025-11-26T13:47:39Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/math/transform/FastFourierTransformer.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Matrices&amp;diff=4064</id>
		<title>User Manual 4.17 Matrices</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Matrices&amp;diff=4064"/>
		<updated>2025-11-26T13:47:20Z</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.17}}/fr/cnes/sirius/patrius/math/linear/package-summary.html Package fr.cnes.sirius.patrius.math.linear] |- | Patrius |[{{JavaDoc4.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/math/linear/SingularValueDecomposition.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Interpolation_Methods&amp;diff=4063</id>
		<title>User Manual 4.17 Interpolation Methods</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Interpolation_Methods&amp;diff=4063"/>
		<updated>2025-11-26T13:47:04Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}&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.17}}&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.17}}&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.17 Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Angles_and_Intervals&amp;diff=4062</id>
		<title>User Manual 4.17 Angles and Intervals</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Angles_and_Intervals&amp;diff=4062"/>
		<updated>2025-11-26T13:46:48Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__  == Introduction == === Scope === This section describes how angles, intervals and angle intervals are defined and used in the PATRIUS library.  === Javadoc === The angle-related objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.interval&amp;lt;/code&amp;gt; in the PATRIUS library. The class defining an interval end point, though, is in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.utils&amp;lt;/code&amp;gt;.  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ &lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes how angles, intervals and angle intervals are defined and used in the PATRIUS library.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The angle-related objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.interval&amp;lt;/code&amp;gt; in the PATRIUS library. The class defining an interval end point, though, is in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.utils&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.17}}/fr/cnes/sirius/patrius/math/interval/package-summary.html Package fr.cnes.sirius.patrius.math.interval]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.17}}/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;
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.utils&amp;lt;/code&amp;gt; contains the class IntervalEndPoint that defines the type of boundary (CLOSED, OPEN) of an interval end.&lt;br /&gt;
&lt;br /&gt;
The package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.utils&amp;lt;/code&amp;gt; contains the actual angle-related classes.&lt;br /&gt;
&lt;br /&gt;
[[File:PATRIMOINESIRIUSSUMDiagAngles.png]]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Generic intervals ===&lt;br /&gt;
An interval is made of two endpoints, and each endpoint may be closed or opened.&lt;br /&gt;
&lt;br /&gt;
This is the most generic implementation of intervals : the class &amp;lt;code&amp;gt;GenericInterval&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt;. The enumeration provides the endpoint types : CLOSED and OPEN.&lt;br /&gt;
&lt;br /&gt;
This class is meant to be used as a parent class for all intervals implementations.&lt;br /&gt;
&lt;br /&gt;
This class makes no assumption on the nature of the parameter class T, so it may create intervals of anything- but the functionality for this class is limited (we only have getters for the endpoints values, and their type). That&#039;s why it&#039;s meant to be used as a parent class.&lt;br /&gt;
&lt;br /&gt;
The class is immutable, in the sense that the endpoints objects are set at the interval creation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mutable types should not be used as endpoint value types!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Examples :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
       final IntervalEndpointType lowType = IntervalEndpointType.OPEN;&lt;br /&gt;
        final Double lowValue = new Double(34.136);&lt;br /&gt;
        final IntervalEndpointType upType = IntervalEndpointType.CLOSED;&lt;br /&gt;
        final Double upValue = new Double(-2.3e34);&lt;br /&gt;
        // Note the order of values is off : this class cannot enforce an order&lt;br /&gt;
        final GenericInterval&amp;lt;Double&amp;gt; tgi = new GenericInterval&amp;lt;Double&amp;gt;(lowType, lowValue, upValue, upType);&lt;br /&gt;
        final Double gLow = tgi.getLowerData();&lt;br /&gt;
        assertTrue(gLow.equals(lowValue));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please see the Javadoc for more information.&lt;br /&gt;
&lt;br /&gt;
Example with doubles: interval [1.0, 2.0[ :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
GenericInterval&amp;lt;Double&amp;gt; interval = new GenericInterval&amp;lt;Double&amp;gt;(IntervalEndpointType.CLOSED, 1.0, 2.0, IntervalEndpointType.OPEN);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Comparable intervals ===&lt;br /&gt;
This implementation of intervals, &amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;ComparableInterval&amp;lt;T extends Comparable&amp;lt;T&amp;gt;&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;, is for types implementing the Comparable interface ( for instance : &amp;lt;code&amp;gt;Integer&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Double&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
This implementation inherits from &amp;lt;code&amp;gt;GenericInterval&amp;lt;T&amp;gt;&amp;lt;/code&amp;gt;; in addition to inherited capabilities, it enforces a proper order on the lower and upper endpoints. A &amp;lt;code&amp;gt;ComparableInterval&amp;lt;/code&amp;gt; can also :&lt;br /&gt;
&lt;br /&gt;
* tell if a given value is inside an interval&lt;br /&gt;
* tell if an interval is inside another&lt;br /&gt;
* tell if two intervals overlap&lt;br /&gt;
* merge two intervals&lt;br /&gt;
* ...&lt;br /&gt;
&lt;br /&gt;
Please see the Javadoc for more information.&lt;br /&gt;
&lt;br /&gt;
=== Angle intervals ===&lt;br /&gt;
The AngleInterval class represents an interval of doubles that shall be used to deal with angles. It contains the end points values and types (enum OPENED and CLOSED, class IntervalEndPointType), the mid value (“reference”) and the interval length.&lt;br /&gt;
&lt;br /&gt;
=== Angle tools ===&lt;br /&gt;
This class is a toolbox containing static methods to perform operations on angles, for instance :&lt;br /&gt;
&lt;br /&gt;
* angleInInterval : sets an angle in an interval modulo 2Pi&lt;br /&gt;
&lt;br /&gt;
Due to numerical quality issues, the algorithm is the following :&lt;br /&gt;
&lt;br /&gt;
 - If the interval is of the form [a, a + 2Pi[, then&lt;br /&gt;
     if x &amp;lt; a and x + 2Pi &amp;gt;= a + 2Pi, the angle is set to a (numerical quality issue due to the non-iqual repartition of real values around lower and upper boundaries)&lt;br /&gt;
     if x = 2Pi, the angle is set to a&lt;br /&gt;
 - If the interval is of the form ]a, a + 2Pi], then&lt;br /&gt;
     if x &amp;gt; a + 2Pi and x – 2Pi &amp;lt;= a, the angle is set to a + 2Pi (numerical quality issue due to the non-iqual repartition of real values around lower and upper boundaries)&lt;br /&gt;
     if x = a, the angle is set to a + 2Pi&lt;br /&gt;
 - Else&lt;br /&gt;
     if x &amp;lt; a, the angle is set to x + 2Pi&lt;br /&gt;
     if x &amp;gt; a + 2Pi, the angle is set to x- 2Pi&lt;br /&gt;
     else the angle is x&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* angle comparisons&lt;br /&gt;
* supplementary, complementary angles computation&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Comparable intervals ===&lt;br /&gt;
Hereunder is given a code example illustrating how the &amp;lt;code&amp;gt;ComparableInterval&amp;lt;/code&amp;gt; object behaves:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
        final Double d1 = new Double(-4.44);&lt;br /&gt;
        final Double d2 = new Double(2.22);&lt;br /&gt;
        final Double d3 = new Double(6.23);&lt;br /&gt;
        final Double d4 = new Double(8.72);&lt;br /&gt;
        final IntervalEndpointType open = IntervalEndpointType.OPEN;&lt;br /&gt;
        final IntervalEndpointType closed = IntervalEndpointType.CLOSED;&lt;br /&gt;
        // Interval : [ -4.44 ; 2.22 [&lt;br /&gt;
        final ComparableInterval&amp;lt;Double&amp;gt; ti1 = new ComparableInterval&amp;lt;Double&amp;gt;(closed, d1, d2, open);&lt;br /&gt;
        final Double inside1 = new Double(-4.44);&lt;br /&gt;
        final Double inside2 = new Double(-2.24);&lt;br /&gt;
        final Double outside1 = new Double(-0.2313E96);&lt;br /&gt;
        final Double outside2 = new Double(-4.45);&lt;br /&gt;
        assertTrue(ti1.contains(inside1));&lt;br /&gt;
        assertTrue(ti1.contains(inside2));&lt;br /&gt;
        assertTrue(!ti1.contains(outside1));&lt;br /&gt;
        assertTrue(!ti1.contains(outside2));&lt;br /&gt;
        // Two open overlapping intervals&lt;br /&gt;
        // ] d1 ; d3 [&lt;br /&gt;
        // ...] d2 ; d4 [&lt;br /&gt;
        final ComparableInterval&amp;lt;Double&amp;gt; ovo1 = new ComparableInterval&amp;lt;Double&amp;gt;(open, d1, d3, open);&lt;br /&gt;
        final ComparableInterval&amp;lt;Double&amp;gt; ovo2 = new ComparableInterval&amp;lt;Double&amp;gt;(open, d2, d4, open);&lt;br /&gt;
        assertTrue(ovo1.overlaps(ovo2));&lt;br /&gt;
        assertTrue(ovo2.overlaps(ovo1));&lt;br /&gt;
        // Two closed intervals, first includes second&lt;br /&gt;
        // [ d1 .....;..... d4 ]&lt;br /&gt;
        // .....[ d2 ; d3 ]&lt;br /&gt;
        final ComparableInterval&amp;lt;Double&amp;gt; clos1 = new ComparableInterval&amp;lt;Double&amp;gt;(closed, d1, d4, closed);&lt;br /&gt;
        final ComparableInterval&amp;lt;Double&amp;gt; clos2 = new ComparableInterval&amp;lt;Double&amp;gt;(closed, d2, d3, closed);&lt;br /&gt;
        assertTrue(clos1.includes(clos2));&lt;br /&gt;
        assertTrue(!clos2.includes(clos1));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Angle intervals ===&lt;br /&gt;
Two constructors are available for an AngleInterval instance :&lt;br /&gt;
&lt;br /&gt;
* One needing directly the end points values and types. Its signature is in the writing order. For example, to create [0.0, 2PI[ :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
AngleInterval angleInterval1 = new AngleInterval(IntervalEndpointType.CLOSED, 0.0,&lt;br /&gt;
   MathUtils.TWO_PI, IntervalEndpointType.OPEN);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* One needing the reference and length values, and the end points nature. Here, the signature is : “reference”, “length”, “lower end point type”, “upper end point type”. To create [-PI, PI[ :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
AngleInterval angleInterval1 = new AngleInterval(0.0, MathUtils.TWO_PI,&lt;br /&gt;
   IntervalEndpointType.CLOSED, IntervalEndpointType.OPEN); &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Those constructors throw an exception « MathIllegalArgumentException » if the interval is not valid. It is considered not valid if :&lt;br /&gt;
&lt;br /&gt;
* The length is strictly greater than 2PI&lt;br /&gt;
* The length is equal to 2PI and both end points are “closed”&lt;br /&gt;
* The length is negative&lt;br /&gt;
* The length is zero and at least one end point is opened (an interval with only one double in it is accepted)&lt;br /&gt;
&lt;br /&gt;
Those intervals are impossible to modify once created : they have no setters. To get an interval with different values, a new one shall be constructed.&lt;br /&gt;
&lt;br /&gt;
=== Angle tools ===&lt;br /&gt;
==== The method &amp;quot;angleInInterval&amp;quot; ====&lt;br /&gt;
&lt;br /&gt;
The method « angleInInterval » computes the (2PI)  modulus of an angle (given as a double) in an angle interval (AngleInterval object) :&lt;br /&gt;
&lt;br /&gt;
* If a (2PI) modulus of the input angle exists in the interval, its value is returned. Because the angles have a maximum length of 2PI with at least an open end point, there can be only one solution.&lt;br /&gt;
* If no value in the interval is a solution, it means the operation is impossible with the given inputs, and a « MathIllegalArgumentException » is thrown.&lt;br /&gt;
&lt;br /&gt;
Use example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try {&lt;br /&gt;
// Angle&lt;br /&gt;
double angle = 6*FastMath.PI;&lt;br /&gt;
 &lt;br /&gt;
// Interval creation &lt;br /&gt;
AngleInterval angleInterval = new AngleInterval(IntervalEndpointType.OPEN, &lt;br /&gt;
- MathUtils.HALF_PI, MathUtils.HALF_PI, IntervalEndpointType.OPEN);&lt;br /&gt;
&lt;br /&gt;
// angle in interval&lt;br /&gt;
double result = AngleTools.angleInInterval(angle, angleInterval);&lt;br /&gt;
}&lt;br /&gt;
catch (MathIllegalArgumentException e) {&lt;br /&gt;
 // correct catch!&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
« result » value is here 0.0 : the modulus of 6PI in ]-PI/2,-PI/2[&lt;br /&gt;
&lt;br /&gt;
==== Comparisons methods ====&lt;br /&gt;
&lt;br /&gt;
The comparison methods available in the AngleTools class are the same as the one for doubles in the « Comparators » class : relative comparisons using a default epsilon. Input angles are only expressed in the input interval before the comparison.&lt;br /&gt;
&lt;br /&gt;
If the computation in the interval of one of the input angles is not possible, a « MathIllegalArgumentException » is thrown.&lt;br /&gt;
&lt;br /&gt;
Use example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try {&lt;br /&gt;
// Angle&lt;br /&gt;
double angle1 = 6*FastMath.PI;&lt;br /&gt;
double angle2 = 4*FastMath.PI + 0.1;&lt;br /&gt;
&lt;br /&gt;
// Interval creation &lt;br /&gt;
AngleInterval angleInterval = new AngleInterval(IntervalEndpointType.OPEN, &lt;br /&gt;
- MathUtils.HALF_PI, MathUtils.HALF_PI, IntervalEndpointType.OPEN);&lt;br /&gt;
&lt;br /&gt;
// angle in interval&lt;br /&gt;
boolean isLowerOrEqual = AngleTools.lowerOrEqual(angle1, angle2, angleInterval);&lt;br /&gt;
}&lt;br /&gt;
catch (MathIllegalArgumentException e) {&lt;br /&gt;
 // correct catch !&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Both angles are here computable in the given interval. The first one is lower than the second once in the interval : the returned result is “true”&lt;br /&gt;
&lt;br /&gt;
==== Supplementary, complementary and opposite angles ====&lt;br /&gt;
&lt;br /&gt;
The tools box AngleTools proposes the methods to compute supplementary (method supplementaryAngle), complementary (method complementaryAngle) and opposite (method oppositeAngle) angles, taking into account an angle interval (of the type AngleInterval previously described)&lt;br /&gt;
&lt;br /&gt;
Those methods first compute a common supplementary, complementary or opposite angle, and then try to express the result in the given interval. If this last operation is not possible, an exception is thrown (MathIllegalArgumentException).&lt;br /&gt;
&lt;br /&gt;
Use example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
try {&lt;br /&gt;
 // Interval creation&lt;br /&gt;
 AngleInterval angleInterval = new AngleInterval(IntervalEndpointType.OPEN, &lt;br /&gt;
- MathUtils.HALF_PI, MathUtils.HALF_PI, IntervalEndpointType.OPEN);&lt;br /&gt;
   &lt;br /&gt;
 // computation&lt;br /&gt;
 double angle = 3.0/4.0*FastMath.PI + 6.0*FastMath.PI;&lt;br /&gt;
 double res = AngleTools.supplementaryAngle(angle, angleInterval);&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
catch (MathIllegalArgumentException e) {&lt;br /&gt;
 // correct catch !&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The result is here computable, its value is PI/4.&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;
Here is a summary of the most important 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;IntervalEndpointType&#039;&#039;&#039;&lt;br /&gt;
|Defines an interval end point as OPEN or CLOSED.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/interval/IntervalEndpointType.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AngleInterval&#039;&#039;&#039;&lt;br /&gt;
|Implements an interval of angles, taking angles&#039; modulus into account.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/interval/AngleInterval.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AngleTools&#039;&#039;&#039;&lt;br /&gt;
|Provides several angle-related utility methods.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/interval/AngleTools.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GenericInterval&#039;&#039;&#039;&lt;br /&gt;
|Implements a generic interval.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/interval/GenericInterval.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 using the ComparableInterval class.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/time/AbsoluteDateInterval.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;AbsoluteDateIntervalsList&#039;&#039;&#039;&lt;br /&gt;
|The class describe a list of AbsoluteDateInterval.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/time/AbsoluteDateIntervalList.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ComparableInterval&#039;&#039;&#039;&lt;br /&gt;
|The class describe an interval of Comparable data.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/interval/ComparableInterval.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ComparableIntervalsList&#039;&#039;&#039;&lt;br /&gt;
|The class describe a list of ComparableInterval.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/interval/ComparableIntervalsList.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Geometry&amp;diff=4061</id>
		<title>User Manual 4.17 Geometry</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Geometry&amp;diff=4061"/>
		<updated>2025-11-26T13:46:32Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/SphericalCoordinates.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Dispersions&amp;diff=4060</id>
		<title>User Manual 4.17 Dispersions</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Dispersions&amp;diff=4060"/>
		<updated>2025-11-26T13:46:14Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « __NOTOC__ == Introduction == === Scope === This section describes how dispersions are defined and used in the PATRIUS library. Dispersions are not to be mixed up with random generation (not detailed in this page). Dispersions always rely on a random generator.  === Javadoc === The dispersions objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.random&amp;lt;/code&amp;gt;. This package also handles random generation.  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Li... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes how dispersions are defined and used in the PATRIUS library.&lt;br /&gt;
Dispersions are not to be mixed up with random generation (not detailed in this page). Dispersions always rely on a random generator.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The dispersions objects are available in the package &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.random&amp;lt;/code&amp;gt;. This package also handles random generation.&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.17}}/fr/cnes/sirius/patrius/math/random/package-summary.html Package fr.cnes.sirius.patrius.math.random]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/random/package-summary.html Package fr.cnes.sirius.patrius.math.random]&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;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Random number generation ===&lt;br /&gt;
Distributed random number generation is based on using implementations of interface &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.random.NormalizedRandomGenerator&amp;lt;/code&amp;gt;.&lt;br /&gt;
Each implementation of this interface provides a specific dispersion scheme. For instance, the following code will generate random numbers with Gaussian distribution of mean 0 and unit standard deviation:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final RandomGenerator g = new JDKRandomGenerator();&lt;br /&gt;
final NormalizedRandomGenerator generator = new GaussianRandomGenerator(g);&lt;br /&gt;
final double value = generator.nextNormalizedDouble();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As shown in the above example, building a dispersion object requires a random generator implementing &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.random.RandomGenerator&amp;lt;/code&amp;gt; interface.&lt;br /&gt;
&lt;br /&gt;
=== Random vector generation ===&lt;br /&gt;
Correlated random vector generation is based on using implementations of interface &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.random.RandomVectorGenerator&amp;lt;/code&amp;gt;.&lt;br /&gt;
Each implementation of this interface provides a specific dispersion scheme. For instance, the following code will generate uniformly correlated random vectors according to provided covariance matrix:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final RandomGenerator g = new JDKRandomGenerator();&lt;br /&gt;
final RandomVectorGenerator generator = new UniformlyCorrelatedRandomVectorGenerator(mean, covariance, 0, g);&lt;br /&gt;
final double[] value = generator.nextVector();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As shown in the above example, building a dispersion object requires a random generator implementing &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.random.RandomGenerator&amp;lt;/code&amp;gt; interface.&lt;br /&gt;
&lt;br /&gt;
=== Correlated random vector generator ===&lt;br /&gt;
The user provides a covariance matrix and a random generator.&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;When using Gaussian correlated random vector generator&#039;&#039;&#039;:&lt;br /&gt;
* The covariance matrix root is extracted using a Cholesky decomposition. The number of columns of the root matrix corresponds to the rank of the provided covariance matrix.&lt;br /&gt;
* An uncorrelated vector of size the rank of the covariance matrix is generated using the provided random generator&lt;br /&gt;
* The final correlated vector is obtained by multiplying the covariance root matrix by this generated vector.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;When using uniformly correlated random vector generator&#039;&#039;&#039;, the process is more complex:&lt;br /&gt;
* The covariance matrix is converted into a correlation matrix. Standard deviation vector is extracted from the process. Obtained correlation matrix must be positive semi-definite (all eigenvalues must be non negative).&lt;br /&gt;
* Spearman correction is applied to the correlation matrix. If corrected correlation matrix is not positive semi-definite, correction is not applied.&lt;br /&gt;
[[File:spearmanCorrection.png|center]]&lt;br /&gt;
* The correlation matrix root is extracted using a Cholesky decomposition. The number of columns of the root matrix corresponds to the rank of the correlation matrix.&lt;br /&gt;
* A uncorrelated vector of size the rank of the covariance matrix is generated using the provided random generator&lt;br /&gt;
* The product of correlation matrix root L and uncorrelated vector T is then transformed to get a uniform law:&lt;br /&gt;
[[File:uniformCorrection.png|center]]&lt;br /&gt;
* The final correlated vector is obtained by linearly multiplying z by the standard deviation vector.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
{{specialInclusion prefix=$theme 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 dispersions:&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;NormalizedRandomGenerator&#039;&#039;&#039;&lt;br /&gt;
|Interface for normalized random generators&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/random/NormalizedRandomGenerator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;RandomVectorGenerator&#039;&#039;&#039;&lt;br /&gt;
|Interface for random vector generators&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/random/RandomVectorGenerator.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: interface for random number generators is &amp;lt;code&amp;gt;fr.cnes.sirius.patrius.math.random.RandomGenerator&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
The library defines the following classes related to dispersions:&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;GaussianRandomGenerator&#039;&#039;&#039;&lt;br /&gt;
|Generator following Gaussian distribution&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/random/GaussianRandomGenerator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UniformRandomGenerator&#039;&#039;&#039;&lt;br /&gt;
|Generator following uniform distribution&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/random/UniformRandomGenerator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UncorrelatedRandomVectorGenerator&#039;&#039;&#039;&lt;br /&gt;
|Generator for Gaussian uncorrelated vectors&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/random/UncorrelatedRandomVectorGenerator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;CorrelatedRandomVectorGenerator&#039;&#039;&#039;&lt;br /&gt;
|Generator for Gaussian correlated vectors&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/random/CorrelatedRandomVectorGenerator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UniformlyCorrelatedRandomVectorGenerator&#039;&#039;&#039;&lt;br /&gt;
|Generator for uniformly correlated vectors&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/random/UniformlyCorrelatedRandomVectorGenerator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;UnitSphereRandomVectorGenerator&#039;&#039;&#039;&lt;br /&gt;
|Generator for vectors isotropically located on a sphere&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/math/random/UnitSphereRandomVectorGenerator.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Double_Comparisons&amp;diff=4059</id>
		<title>User Manual 4.17 Double Comparisons</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Double_Comparisons&amp;diff=4059"/>
		<updated>2025-11-26T13:45:57Z</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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/math/Comparators.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Math_frameworks&amp;diff=4058</id>
		<title>User Manual 4.17 Math frameworks</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Math_frameworks&amp;diff=4058"/>
		<updated>2025-11-26T13:45:32Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/math/FastMath.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Numerical_differentiation_and_integration&amp;diff=4057</id>
		<title>User Manual 4.17 Numerical differentiation and integration</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Numerical_differentiation_and_integration&amp;diff=4057"/>
		<updated>2025-11-26T13:45:12Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/math/analysis/integration/SimpsonIntegrator.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Numerical_ordinary_differential_equations&amp;diff=4056</id>
		<title>User Manual 4.17 Numerical ordinary differential equations</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Numerical_ordinary_differential_equations&amp;diff=4056"/>
		<updated>2025-11-26T13:44:39Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/math/ode/events/EventState.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Optimization&amp;diff=4055</id>
		<title>User Manual 4.17 Optimization</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Optimization&amp;diff=4055"/>
		<updated>2025-11-26T13:44:23Z</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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/math/optim/joptimizer/util/Utils.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Rotations_and_quaternions&amp;diff=4054</id>
		<title>User Manual 4.17 Rotations and quaternions</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Rotations_and_quaternions&amp;diff=4054"/>
		<updated>2025-11-26T13:44:02Z</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.17}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/package-summary.html Package fr.cnes.sirius.patrius.math.geometry.euclidean.threed] |- | Patrius |[{{JavaDoc4.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}//fr/cnes/sirius/patrius/math/geometry/euclidean/threed/Vector3D.html vectors] into other three dimensional [{{JavaDoc4.17}}//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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/math/geometry/euclidean/threed/RotationOrder.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Root-Finding_Algorithms&amp;diff=4053</id>
		<title>User Manual 4.17 Root-Finding Algorithms</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Root-Finding_Algorithms&amp;diff=4053"/>
		<updated>2025-11-26T13:43:33Z</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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/math/analysis/UnivariateFunction.html UnivariateFunction].&lt;br /&gt;
The root-finding algorithm is implemented through the [{{JavaDoc4.17}}/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;
&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;
&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, 2, 3);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result : NoBracketingException exception&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 MullerSolver();&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 : NoBracketingException exception&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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/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.17}}/fr/cnes/sirius/patrius/math/analysis/solver/MullerSolver.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.17_Mathematics]]&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.17_Mission&amp;diff=4052</id>
		<title>Catégorie:User Manual 4.17 Mission</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_4.17_Mission&amp;diff=4052"/>
		<updated>2025-11-26T13:40:33Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec «  == Introduction == This section presents the events and visibility aspects of the PATRIUS library. First of all, it is necessary to manage the event detection during the propagation, to that purpose, a smart mechanism has been developped in the math package and repeated in Patrius when it comes to propagate with an AbstractPropagator. In Patrius, it is possible to register during the propagation the detected events. A new conception has been developped on this b... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
== Introduction ==&lt;br /&gt;
This section presents the events and visibility aspects of the PATRIUS library. First of all, it is necessary to manage the event detection during the propagation, to that purpose, a smart mechanism has been developped in the math package and repeated in Patrius when it comes to propagate with an AbstractPropagator. In Patrius, it is possible to register during the propagation the detected events. A new conception has been developped on this basis in order to create a list of CodedEvent (code + comment + date) during the propagation as well as a list of Phenomenon. Then, the user can perform a post processing on the generated events list and phenomena list thanks to several filters.&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;
&#039;&#039;&#039;[R1]&#039;&#039;&#039;    &#039;&#039;Apache License&#039;&#039;, Version 2.0, January 2004, [http://www.apache.org/licenses/LICENSE-2.0.txt].&lt;br /&gt;
&lt;br /&gt;
== Glossary ==&lt;br /&gt;
None applicable.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
The following themes are discussed in this section:&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Events detection&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Post processing on events and phenomena&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Maneuvers&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*&#039;&#039;&#039;Projections&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Catégorie:User Manual 4.17]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Projections&amp;diff=4051</id>
		<title>User Manual 4.17 Projections</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Projections&amp;diff=4051"/>
		<updated>2025-11-26T13:40:16Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec « == Introduction == === Scope === The scope of this section is to present the projections features available in Patrius library. Patrius provides classes to perform projections on an ellipsoid as well as various computation on the surface of an ellipsoid. Common available projections are: * Mercator * Flamsteed-Samson * Identity projection  === Javadoc === All the classes related to projections are in the following packages:  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;|... »&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 projections features available in Patrius library.&lt;br /&gt;
Patrius provides classes to perform projections on an ellipsoid as well as various computation on the surface of an ellipsoid. Common available projections are:&lt;br /&gt;
* Mercator&lt;br /&gt;
* Flamsteed-Samson&lt;br /&gt;
* Identity projection&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
All the classes related to projections are 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.17}}/fr/cnes/sirius/patrius/projections/package-summary.html Package fr.cnes.sirius.patrius.projections]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
More information about specific projections can be found using the following links:&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Mercator_projection Mercator projection]&lt;br /&gt;
* [https://en.wikipedia.org/wiki/Sinusoidal_projection Flamsteed-Samson projection]&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 projections package gathers:&lt;br /&gt;
* An interface for all projections: &amp;lt;code&amp;gt;IProjection&amp;lt;/code&amp;gt;&lt;br /&gt;
* Some available projections : &amp;lt;code&amp;gt;Mercator&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;GeneralizedFlamsteedSamson&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;IdentityProjection&amp;lt;/code&amp;gt;&lt;br /&gt;
* A ellipsoid with extended features: &amp;lt;code&amp;gt;ProjectionEllipsoid&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The projection package can be summarized with the following UML diagram.&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:Projections.png|center]]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
Projections provide three main features:&lt;br /&gt;
* Projection on an ellipsoid (and its inverse application)&lt;br /&gt;
* Discretisation between points on the surface of an ellipsoid&lt;br /&gt;
* Geometric computation on the surface of an ellipsoid using class ProjectionEllipsoid&lt;br /&gt;
&lt;br /&gt;
=== Projection on an ellipsoid ===&lt;br /&gt;
&lt;br /&gt;
Projection on an ellipsoid is a transformation taking geodetic coordinates (latitude, longitude, altitude) as input and returning 2D map coordinates (X, Y) as output.&lt;br /&gt;
Inverse transformation takes 2D map coordinates (X, Y) as input and returns geodetic coordinates (latitude, longitude, altitude) as output.&lt;br /&gt;
&lt;br /&gt;
Projection classes inherit projection interface &amp;lt;code&amp;gt;IProjection&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Available projections are:&lt;br /&gt;
* Mercator projection: &amp;lt;code&amp;gt;Mercator&amp;lt;/code&amp;gt;. The Mercator projection is a cylindrical map projection which became the standard map projection for nautical purposes because of its ability to represent lines of constant course, known loxodromes, as straight segments. Mercator projection is conformal (angles are preserved) but not equivalent (areas are not preserved).&lt;br /&gt;
&lt;br /&gt;
[[File:MercatorProjection.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
* Flamsteed-Samson projection: &amp;lt;code&amp;gt;GeneralizedFlamsteedSamson&amp;lt;/code&amp;gt;. This projection is also known as the sinusoidal projection. The sinusoidal projection is equal-area and preserves distances along the horizontals but is not conformal (angles are not preserved).&lt;br /&gt;
&lt;br /&gt;
[[File:SinusoidalProjection.jpg|center]]&lt;br /&gt;
&lt;br /&gt;
* Identity projection: &amp;lt;code&amp;gt;IdentityProjection&amp;lt;/code&amp;gt;. Identity projection is the projection [latitude, longitude, altitude] =&amp;gt; [X = latitude, Y = longitude].&lt;br /&gt;
&lt;br /&gt;
All projections provide:&lt;br /&gt;
* direct transformation using method &amp;lt;code&amp;gt;applyTo()&amp;lt;/code&amp;gt;. It returns 2D map coordinates (X, Y) from geodetic coordinates (latitude, longitude, altitude).&lt;br /&gt;
* inverse transformation using method &amp;lt;code&amp;gt;applyInverseTo()&amp;lt;/code&amp;gt;. It returns geodetic coordinates (latitude, longitude, altitude) from 2D map coordinates (X, Y).&lt;br /&gt;
&lt;br /&gt;
=== Discretization ===&lt;br /&gt;
&lt;br /&gt;
All projection classes provide various discretization methods between geodetic points.&lt;br /&gt;
&lt;br /&gt;
* Discretization between two projected points using the method &amp;lt;code&amp;gt;discretize()&amp;lt;/code&amp;gt;. Maximum distance between discretized point has to be provided.&lt;br /&gt;
* Discretization along a polygon line of geodetic coordinates using the method &amp;lt;code&amp;gt;discretizeAndApplyTo()&amp;lt;/code&amp;gt;. Maximum distance between discretized point has to be provided as well as the discretization strategy.&lt;br /&gt;
&lt;br /&gt;
The discretization strategy is provided with the enumeration &amp;lt;code&amp;gt;EnumLineProperty&amp;lt;/code&amp;gt;. It offers the following possibilities:&lt;br /&gt;
* &amp;lt;code&amp;gt;STRAIGHT&amp;lt;/code&amp;gt;: straight line between two geodetic points.&lt;br /&gt;
* &amp;lt;code&amp;gt;GREAT_CIRCLE&amp;lt;/code&amp;gt;: arc being the shortest way to connect two geodetic points on an ellipsoid. The center of the ellipsis is the ellipsoid center.&lt;br /&gt;
* &amp;lt;code&amp;gt;STRAIGHT_RHUMB_LINE&amp;lt;/code&amp;gt;: arc between two geodetic points crossing all meridians of longitude at the same angle. It corresponds to a path of constant bearing as measured relative to true north. On Mercator projection, it is represented by a straight line.&lt;br /&gt;
&lt;br /&gt;
Other methods are available. For more information, refer to the javadoc of [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/projections/AbstractProjection.html AbstractProjection] class.&lt;br /&gt;
&lt;br /&gt;
=== Computation on the surface of an ellipsoid ===&lt;br /&gt;
&lt;br /&gt;
A specific ellipsoid class has been defined to handle projections: &amp;lt;code&amp;gt;ProjectionEllipsoid&amp;lt;/code&amp;gt;. This class inherits the class &amp;lt;code&amp;gt;OneAxisEllipsoid&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It provides many useful projection-related computations on the surface of an ellipsoid.&amp;lt;br&amp;gt;&lt;br /&gt;
Available features of &amp;lt;code&amp;gt;ProjectionEllipsoid&amp;lt;/code&amp;gt; are:&lt;br /&gt;
&lt;br /&gt;
* Distance computation:&lt;br /&gt;
&lt;br /&gt;
Orthodromic distance using method &amp;lt;code&amp;gt;computeOrthodromicDistance()&amp;lt;/code&amp;gt;. Orthodromic distance is the shortest path between two points.&amp;lt;br&amp;gt;&lt;br /&gt;
Loxodromic distance using method &amp;lt;code&amp;gt;computeLoxodromicDistance()&amp;lt;/code&amp;gt;. Loxodromic distance follows path of constant bearing: this is a straight line on Mercator projection.&amp;lt;br&amp;gt;&lt;br /&gt;
Meridional distance using method &amp;lt;code&amp;gt;computeMeridionalDistance()&amp;lt;/code&amp;gt;. Meridional distance is the shortest distance from one point to the equator (along a meridian).&lt;br /&gt;
&lt;br /&gt;
On next image, Loxodromic distance is in red, orthodromic distance in blue:&lt;br /&gt;
[[File:LoxodromieOrthodromie.png|center]]&lt;br /&gt;
&lt;br /&gt;
* Azimuth computation:&lt;br /&gt;
&lt;br /&gt;
Bearing using method &amp;lt;code&amp;gt;computeBearing()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Spherical azimuth using method &amp;lt;code&amp;gt;computeSphericalAzimuth()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* Other computations:&lt;br /&gt;
&lt;br /&gt;
Point along loxodrome, given a point, a distance from this point and an azimuth from this point, using method &amp;lt;code&amp;gt;computePointAlongLoxodrome()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Point along orthodrome, given a point, a distance from this point and an azimuth from this point, using method &amp;lt;code&amp;gt;computePointAlongOrthodrome()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Other methods are available. For more information, refer to the javadoc of [{{JavaDoc4.17}}/fr/cnes/sirius/patrius/projections/ProjectionEllipsoid.html ProjectionEllipsoid] class.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
Projections provide three main features:&lt;br /&gt;
* Projection on an ellipsoid (and its inverse application)&lt;br /&gt;
* Discretisation between points on the surface of an ellipsoid&lt;br /&gt;
* Geometric computation on the surface of an ellipsoid using class &amp;lt;code&amp;gt;ProjectionEllipsoid&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Projection on an ellipsoid ===&lt;br /&gt;
&lt;br /&gt;
First an ellipsoid and a projection have to be defined, here using a simple centered Mercator projection:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final EllipsoidBodyShape ellipsoid = new OneAxisEllipsoid(6378137.0, 1. / 298.257223563, FramesFactory.getITRF(), &amp;quot;earth&amp;quot;);&lt;br /&gt;
final Mercator projection = new Mercator(0., ellipsoid);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then the created projection can be used in different ways:&lt;br /&gt;
&lt;br /&gt;
* Projection of geodetic coordinates:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final EllipsoidPoint toulouse = new EllipsoidPoint(ellipsoid, LLHCoordinatesSystem.ELLIPSODETIC, 0.758011794, 0.026140528, 256., &amp;quot;toulouse&amp;quot;);&lt;br /&gt;
final Vector2D projectedPoint = projection.applyTo(toulouse);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Retrieve geodetic coordinates from Mercator 2D coordinates:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final EllipsoidPoint geodeticCoordinates = projection.applyInverseTo(projectedPoint.getX(), projectedPoint.getY());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Discretization ===&lt;br /&gt;
&lt;br /&gt;
First an ellipsoid and a projection have to be defined, here using a simple centered Mercator projection:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final EllipsoidBodyShape ellipsoid = new OneAxisEllipsoid(6378137.0, 1. / 298.257223563, FramesFactory.getITRF(), &amp;quot;earth&amp;quot;);&lt;br /&gt;
final Mercator projection = new Mercator(0., ellipsoid);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then the created projection can be used in different ways:&lt;br /&gt;
&lt;br /&gt;
* Discretization between two projected points with a maximum distance between points of 1km:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final EllipsoidPoint toulouse = new EllipsoidPoint(ellipsoid, LLHCoordinatesSystem.ELLIPSODETIC, 0.758011794, 0.026140528, 256., &amp;quot;toulouse&amp;quot;);&lt;br /&gt;
final EllipsoidPoint london = new EllipsoidPoint(ellipsoid, LLHCoordinatesSystem.ELLIPSODETIC, 0.898844565, 0.002268928, 25., &amp;quot;london&amp;quot;);&lt;br /&gt;
final Vector2D projectedToulouse = projection.applyTo(toulouse);&lt;br /&gt;
final Vector2D projectedLondon = projection.applyTo(london);&lt;br /&gt;
final List&amp;lt;Vector2D&amp;gt; points = projection.discretize(projectedToulouse, projectedLondon, 1000., true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Rhumb discretization along a polygon line with a maximum distance between points of 1km followed by projection:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final List&amp;lt;EllipsoidPoint &amp;gt; list = new ArrayList&amp;lt;&amp;gt;();&lt;br /&gt;
list.add(toulouse);&lt;br /&gt;
list.add(london);&lt;br /&gt;
final List&amp;lt;Vector2D&amp;gt; points = projection.discretizeAndApplyTo(list , EnumLineProperty.STRAIGHT_RHUMB_LINE, 1000.);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* etc. Other similar discretization features are available. See javadoc for more information.&lt;br /&gt;
&lt;br /&gt;
=== Computation on the surface of an ellipsoid ===&lt;br /&gt;
&lt;br /&gt;
First an ellipsoid has to be defined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final EllipsoidBodyShape ellipsoid = new OneAxisEllipsoid(6378137.0, 1. / 298.257223563, FramesFactory.getITRF(), &amp;quot;earth&amp;quot;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then this ellipsoid can be used to:&lt;br /&gt;
&lt;br /&gt;
* Compute distances on the surface of the ellipsoid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final double orthodromicDistance = ellipsoid.computeOrthodromicDistance(toulouse, london);&lt;br /&gt;
final double loxodromicDistance = ellipsoid.computeLoxodromicDistance(toulouse, london);&lt;br /&gt;
final double meridionalDistance = ellipsoid.computeMeridionalDistance(toulouse.getLatitude());&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Compute azimuth angles on the surface of the ellipsoid:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
final double bearing = ellipsoid.computeBearing(toulouse, london);&lt;br /&gt;
final double sphericalAzimuth = ellipsoid.computeSphericalAzimuth(toulouse, london);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* etc. Other similar features are available. See javadoc for more information.&lt;br /&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;IProjection&#039;&#039;&#039;&lt;br /&gt;
|Interface for projections on a 3D body.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/projections/IProjection.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;EnumLineProperty&#039;&#039;&#039;&lt;br /&gt;
|Enumeration of points connecting strategies on an ellipsoid.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/projections/EnumLineProperty.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;IdentityProjection&#039;&#039;&#039;&lt;br /&gt;
|Identity projection.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/projections/IdentityProjection.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;GeneralizedFlamsteedSamson&#039;&#039;&#039;&lt;br /&gt;
|Flamsteed-Samson projection.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/projections/GeneralizedFlamsteedSamson.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Mercator&#039;&#039;&#039;&lt;br /&gt;
|Mercator projection.&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/projections/Mercator.html ...]&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ProjectionEllipsoid&#039;&#039;&#039;&lt;br /&gt;
|Ellipsoid with extended features (features related to projections).&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/projections/ProjectionEllipsoid.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Postprocessing&amp;diff=4050</id>
		<title>User Manual 4.17 Postprocessing</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.17_Postprocessing&amp;diff=4050"/>
		<updated>2025-11-26T13:40:02Z</updated>

		<summary type="html">&lt;p&gt;Admin tsn : Page créée avec «   == Introduction == === Scope === This section describes all postprocessing actions available on events and phenomena  === Javadoc === All the classes are available in the following package:  {| class=&amp;quot;wikitable&amp;quot; |- ! scope=&amp;quot;col&amp;quot;| Library ! scope=&amp;quot;col&amp;quot;| Javadoc |- |Patrius  |[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/package-summary.html Package fr.cnes.sirius.patrius.events.postprocessing] |}  === Links === None as of now.  === Useful Documen... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes all postprocessing actions available on events and phenomena&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
All the classes are available 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.17}}/fr/cnes/sirius/patrius/events/postprocessing/package-summary.html Package fr.cnes.sirius.patrius.events.postprocessing]&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 conception of the post processing is presented hereafter.&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:PATRIMOINESIRIUSPostProcessing.png|center]]&lt;br /&gt;
&lt;br /&gt;
After the propagation, the logger (CodedEventsLogger) has registered all of the events and the phenomena detected during the propagation. Then, the associated timeline (Timeline) is created from this logger. This object contains all of the detected events and phenomena. On this timeline, different types of post processings can be performed.&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Phenomenon duration filter ===&lt;br /&gt;
This filter removes from the list the specified phenomena with a duration greater / lower than a given criterion.&amp;lt;br&amp;gt;&lt;br /&gt;
A boolean &amp;quot;isMinDuration&amp;quot; determines if the criterion is the minimum or maximum duration of the phenomena that will remain on the list.&amp;lt;br&amp;gt;&lt;br /&gt;
The comparison is made with the Comparators class &amp;quot;greaterOrEqual&amp;quot; or &amp;quot;lowerOrEqual&amp;quot; method with a e-14 relative &amp;quot;doubles comparison&amp;quot; epsilon. The phenomena with a duration equal to the criterion are so always kept in the list.&lt;br /&gt;
&lt;br /&gt;
=== Element type filter ===&lt;br /&gt;
This filter selects all the events and/or phenomena in the Timeline whose code correspond to one or more given codes and removes them from the Timeline (or it keeps them and removes all the other elements in the Timeline).&amp;lt;br&amp;gt;&lt;br /&gt;
The user sets the codes of the elements to keep/remove using an array of string.&amp;lt;br&amp;gt;&lt;br /&gt;
If the boolean removeAll is set to false at the filter construction, then the complementary filter is built i.e. a filter which preserves in the TimeLine only the given events or phenomena type. &lt;br /&gt;
&lt;br /&gt;
=== Occurrence filter ===&lt;br /&gt;
This filter removes all of the Nxk occurrences of a given event or phenomenon type. The type is defined by the code.&lt;br /&gt;
&lt;br /&gt;
If the boolean removeAll is set to false at the filter construction, then the complementary filter is built i.e. a filter which preserves in the Timeline only the Nxk occurrences of the given event or phenomenon type.&lt;br /&gt;
&lt;br /&gt;
For example, if N=3 then the third, sixth, ninth... occurrences will be kept or removed.&lt;br /&gt;
&lt;br /&gt;
=== Events during phenomena filter ===&lt;br /&gt;
This filter removes all of the specified types of events that occur during a given phenomenon type. A type is defined by the code.&lt;br /&gt;
&lt;br /&gt;
If the boolean removeAll is set to false at the filter construction, then the complementary filter is built i.e. a filter that erases the events of the given types which occur outside the given phenomenon type.&lt;br /&gt;
&lt;br /&gt;
=== Time filter ===&lt;br /&gt;
This filter removes all of the specified events and phenomena types which occur during a given time interval.&amp;lt;br&amp;gt;&lt;br /&gt;
If the boolean removeAll is set to false, the complementary filter is built i.e. a filter which preserves the specified events and the phenomena that occur during the given time interval.&lt;br /&gt;
&lt;br /&gt;
NB : if the phenomenon interval of validity overlaps the given time interval, the phenomenon is redefined with an undefined start or end event.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;AND&amp;quot; criterion on phenomena ===&lt;br /&gt;
This criterion adds to the phenomena list of a Timeline object the phenomena corresponding to time intervals when phenomena of particular types A AND B occur at the same time. &amp;lt;br&amp;gt;&lt;br /&gt;
The events defining the beginning and the end of those new phenomena are directly the ones of the original A and B phenomena.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;OR&amp;quot; criterion on phenomena ===&lt;br /&gt;
This criterion adds to the phenomena list of a Timeline object the phenomena corresponding to time intervals when phenomena of particular types A OR B occur.&amp;lt;br&amp;gt;&lt;br /&gt;
The events defining the beginning and the end of those new phenomena are directly the ones of the original A and B phenomena.&lt;br /&gt;
&lt;br /&gt;
=== &amp;quot;NOT&amp;quot; criterion on phenomena ===&lt;br /&gt;
This criterion returns the complementary interval of of phenomenon.&lt;br /&gt;
&lt;br /&gt;
=== Delayed events ===&lt;br /&gt;
This criterion adds delayed events for a given event type. The delay is given at the construction of the criterion, it is given in secondes, it can be either positive or negative.&lt;br /&gt;
&lt;br /&gt;
=== Merged phenomena ===&lt;br /&gt;
This criterion merges two phenomena of a same given type if the lapse between them is below a given value. This value is given at the criterion construction, it is given in secondes.&lt;br /&gt;
&lt;br /&gt;
=== Merged Timelines ===&lt;br /&gt;
This post-processing merges two Timelines adding all the events and phenomena of one Timeline to the other one.&amp;lt;br&amp;gt;&lt;br /&gt;
The merging operation is allowed only if the time interval of validity of the two Timelines is the same, otherwise the method &amp;lt;code&amp;gt;applyTo(Timeline list)&amp;lt;/code&amp;gt; throws an exception.&lt;br /&gt;
&lt;br /&gt;
=== Polarization single selection ===&lt;br /&gt;
This post-processing creation adds one phenomenon to the timeline; this new phenomenon represents a polarization single selection over two visibility phenomena timelines.&amp;lt;br&amp;gt;&lt;br /&gt;
If the chosen phenomenon is called for instance &amp;quot;VISI L&amp;quot;, the output phenomenon code will be &amp;quot;VISI L Selection&amp;quot;.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The selection of this polarization phenomenon is made through the following three steps:&lt;br /&gt;
&lt;br /&gt;
#phenomena L and R are filtered in order to remove the phenomena whose duration is shorter then dMin;&lt;br /&gt;
#the remaining phenomena are filtered again in order to merge two phenomena if the time between the end of one phenomenon and the beginning of the other is shorter than dMax;&lt;br /&gt;
#the longest phenomenon is selected among all the remaining L and R phenomena.&lt;br /&gt;
&lt;br /&gt;
The following image represents an example of the polarization single selection process on the timelines L and R:&lt;br /&gt;
&lt;br /&gt;
[[File:polarizationChoice.png|center]]&lt;br /&gt;
&lt;br /&gt;
=== Polarization switch ===&lt;br /&gt;
This post-processing creation possibly adds new events to the timeline; these new events represent polarization switches over two visibility phenomena timelines.&amp;lt;br&amp;gt;&lt;br /&gt;
If the phenomenon that triggers the polarization switch is called for instance &amp;quot;VISI L&amp;quot;, the output event code will be &amp;quot;VISI L Selection&amp;quot;; the date of the new polarization event will be the end date of the previous phenomenon (even if the next phenomenon has not already started).&lt;br /&gt;
&lt;br /&gt;
The first steps of the polarization switching algorithm are identical to the polarization single selection algorithm:&lt;br /&gt;
&lt;br /&gt;
#phenomena L and R are filtered in order to remove the phenomena whose duration is shorter then dMin;&lt;br /&gt;
#the remaining phenomena are filtered again in order to merge two phenomena if the time between the end of one phenomenon and the beginning of the other is shorter than dMax;&lt;br /&gt;
#all phenomena are kept.&lt;br /&gt;
&lt;br /&gt;
The following image represents an example of these steps on the timelines L and R:&lt;br /&gt;
&lt;br /&gt;
[[File:switchingPolarizationfirst.png|center]]&lt;br /&gt;
&lt;br /&gt;
After these first filtering steps the polarisation switches are computed as follows :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
  &lt;br /&gt;
&amp;lt;li&amp;gt;first choice: if both phenomena L and R are active at the beginning of the interval of validity, select the longest one; if only one phenomenon is active, select it; otherwise if both phenomena are not active, select the next active phenomenon. In any case, the output event date will coincide with the beginning of the interval of validity.&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;once the first phenomenon selected, move forward until the end of it (date Tf); a new event is triggered if one of the following conditions applies:&amp;lt;br&amp;gt;&lt;br /&gt;
- at Tf the other phenomenon is active, and its remaining duration is longer than dMin;&amp;lt;br&amp;gt;&lt;br /&gt;
- the next polarization phenomenon after Tf belongs to the other polarization group of phenomena(L if the current phenomenon is R and vice versa).&amp;lt;br&amp;gt;&lt;br /&gt;
If an event is triggered, its date will be Tf.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;apply 2. until the end of the interval of validity.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following image represents 6 examples of the expected switching polarization events for two polarization phenomena timelines, called L and R:&lt;br /&gt;
&lt;br /&gt;
[[File:switchingPolarization.png|center]]&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;
&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Interface&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Summary&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/PostProcessing.html PostProcessing]&lt;br /&gt;
|This interface represents a postprocessing action on a TimeLine object.&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;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/ElementTypeFilter.html ElementTypeFilter]&lt;br /&gt;
|Filter that removes or keeps only the items of a specific type (code or code + comment) in a given timeline.&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/TimeFilter.html TimeFilter]&lt;br /&gt;
|Filter that removes or keeps only all of the events and the phenomena that are inside a given time interval.&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/OccurrenceFilter.html OccurrenceFilter]&lt;br /&gt;
|Filter that removes or keeps only the N x k occurrences of a specific element type (code or code + comment) in a given timeline.&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/PhenomenonDurationFilter.html PhenomenonDurationFilter]&lt;br /&gt;
|This filter removes phenomena on a duration criterion.&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/EventsDuringPhenomenaFilter.html EventsDuringPhenomenaFilter]&lt;br /&gt;
|Filter that removes or keeps only a specified type of events during a specified type of phenomena.&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/DelayCriterion.html DelayCriterion]&lt;br /&gt;
|This class is a post processing criterion that delays a specified kind of events.&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/MergePhenomenaCriterion.html MergePhenomenaCriterion]&lt;br /&gt;
|This class is a post processing criterion that merges two successive phenomena if the time lapse is below a given value.&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/AndCriterion.html AndCriterion]&lt;br /&gt;
|Adds the phenomena corresponding to the occruences of phenomena of types A AND B at the same time.&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/OrCriterion.html OrCriterion]&lt;br /&gt;
|Adds the phenomena corresponding to the occruences of phenomena of types A OR B merged.&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/NotCriterion.html NotCriterion]&lt;br /&gt;
|Returns the complementary interval of of phenomenon.&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/MergeTimelines.html MergeTimelines]&lt;br /&gt;
|Merges two timelines when their intervals of validity are the same.&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/PolarizationSingleSelection.html PolarizationSingleSelection]&lt;br /&gt;
|Creates a new phenomenon representing the polarization single selection from two visibility phenomena.&lt;br /&gt;
|-&lt;br /&gt;
|[{{JavaDoc4.17}}/fr/cnes/sirius/patrius/events/postprocessing/PolarizationSwitch.html PolarizationSwitch]&lt;br /&gt;
|Adds new events to the timeline, each one representing a polarization switch.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.17_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin tsn</name></author>
	</entry>
</feed>