<?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</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"/>
	<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php/Sp%C3%A9cial:Contributions/Admin"/>
	<updated>2026-04-26T14:58:16Z</updated>
	<subtitle>Contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Mod%C3%A8le:JavaDoc4.15&amp;diff=3927</id>
		<title>Modèle:JavaDoc4.15</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Mod%C3%A8le:JavaDoc4.15&amp;diff=3927"/>
		<updated>2025-02-10T14:57:36Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;https://patrius.cnes.fr/images/upload/JavaDocs/V4.15&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.15&amp;diff=3913</id>
		<title>Catégorie:Tutorials 4.15</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.15&amp;diff=3913"/>
		<updated>2025-01-16T13:47:38Z</updated>

		<summary type="html">&lt;p&gt;Admin : Page créée avec « [https://github.com/CNES/patrius-tutorials/tree/patrius-4.15 Tutorials PATRIUS 4.15]   The tutorials for PATRIUS v4.15 can now be found on the [https://github.com/CNES/pat... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://github.com/CNES/patrius-tutorials/tree/patrius-4.15 Tutorials PATRIUS 4.15]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The tutorials for PATRIUS v4.15 can now be found on the [https://github.com/CNES/patrius-tutorials/tree/patrius-4.15 CNES&#039; GitHub page]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Patrius_Versions_and_Dependencies&amp;diff=3912</id>
		<title>Patrius Versions and Dependencies</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Patrius_Versions_and_Dependencies&amp;diff=3912"/>
		<updated>2025-01-15T14:54:57Z</updated>

		<summary type="html">&lt;p&gt;Admin : new&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Version&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.15&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.14&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.13&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.12&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.11&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.10&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.9&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.8&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.7&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.6.1&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.5.1&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.4&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.2&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.1.1&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.0&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|3.x&lt;br /&gt;
|-&lt;br /&gt;
|Disponibility&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 22/11/2024&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 23/08/2024&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 19/12/2023&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 23/05/2023&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 03/11/2022&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 30/05/2022&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 20/10/2021&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 04/06/2021&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 02/04/2021&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 13/08/2020&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 30/10/2019&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 15/06/2019&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 17/01/2019&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 16/10/2018&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 22/01/2018&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| -&lt;br /&gt;
|-&lt;br /&gt;
|Javadoc&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes            &lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|-&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|Dependencies &lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.7&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.7&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.6&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.6&amp;lt;br/&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Patrius_Versions_and_Dependencies&amp;diff=3911</id>
		<title>Patrius Versions and Dependencies</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Patrius_Versions_and_Dependencies&amp;diff=3911"/>
		<updated>2025-01-15T14:54:46Z</updated>

		<summary type="html">&lt;p&gt;Admin : new page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Accueil&amp;diff=3910</id>
		<title>Accueil</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Accueil&amp;diff=3910"/>
		<updated>2025-01-15T14:53:44Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.15 ==&lt;br /&gt;
&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; V4.15 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.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;
[{{PathCurrentJavaDoc}} Current Java Doc]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.15 Java Doc 4.15]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.14 Java Doc 4.14]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.13 Java Doc 4.13]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.12 Java Doc 4.12]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.11 Java Doc 4.11]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.10.2 Java Doc 4.10.2]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.9.1 Java Doc 4.9.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.8 Java Doc 4.8]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.7 Java Doc 4.7]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.6.1 Java Doc 4.6.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.5.1 Java Doc 4.5.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.4 Java Doc 4.4]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.3 Java Doc 4.3]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.2 Java Doc 4.2]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.1.1 Java Doc 4.1.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.1 Java Doc 4.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.0 Java Doc 4.0]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V3.4.1 Java Doc 3.4.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V3.3 Java Doc 3.3]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V3.2 Java Doc 3.2]&amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.14&amp;diff=3816</id>
		<title>Catégorie:Tutorials 4.14</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.14&amp;diff=3816"/>
		<updated>2024-11-05T09:25:18Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://github.com/CNES/patrius-tutorials/tree/patrius-4.14.1 Tutorials PATRIUS 4.14.1]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The tutorials for PATRIUS v4.14.1 can now be found on the [https://github.com/CNES/patrius-tutorials/tree/patrius-4.14.1 CNES&#039; GitHub page]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.14&amp;diff=3815</id>
		<title>Catégorie:Tutorials 4.14</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.14&amp;diff=3815"/>
		<updated>2024-11-05T09:24:56Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://github.com/CNES/patrius-tutorials/tree/patrius-v4.14.1 Tutorials PATRIUS 4.14.1]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The tutorials for PATRIUS v4.14.1 can now be found on the [https://github.com/CNES/patrius-tutorials/tree/patrius-4.14.1 CNES&#039; GitHub page]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.14&amp;diff=3814</id>
		<title>Catégorie:Tutorials 4.14</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.14&amp;diff=3814"/>
		<updated>2024-11-05T09:23:34Z</updated>

		<summary type="html">&lt;p&gt;Admin : Page créée avec « [https://github.com/CNES/patrius-tutorials/tree/patrius-v4.14.1 Tutorials PATRIUS 4.14.1]   The tutorials for PATRIUS v4.14.1 can now be found on the [https://github.com/C... »&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://github.com/CNES/patrius-tutorials/tree/patrius-v4.14.1 Tutorials PATRIUS 4.14.1]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The tutorials for PATRIUS v4.14.1 can now be found on the [https://github.com/CNES/patrius-tutorials/tree/patrius-v4.14.1 CNES&#039; GitHub page]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3813</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3813"/>
		<updated>2024-09-19T14:55:32Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3812</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3812"/>
		<updated>2024-09-19T14:49:59Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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|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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3811</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3811"/>
		<updated>2024-09-19T14:47:41Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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;[https://github.com/{{{owner|CNES}}}/{{{repo|patrius-tutorials}}}/{{{action|blob}}}/{{{branch|main}}}/{{{file|{{{1|src/main/java/attitudes/LOFOffsetAttitudeLaw.java}}}}}}{{#if:{{{line|#56}}}|&amp;amp;#35;L{{{line}}}}} {{{text|{{{2|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt;&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|LOFOffsetAttitudeLaw.java}}}}}}]&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3810</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3810"/>
		<updated>2024-09-19T14:46:15Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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;[https://github.com/{{{owner|CNES}}}/{{{repo|patrius-tutorials}}}/{{{action|blob}}}/{{{branch|main}}}/{{{file|{{{1|src/main/java/attitudes/LOFOffsetAttitudeLaw.java}}}}}}{{#if:{{{line|#56}}}|&amp;amp;#35;L{{{line}}}}} {{{text|{{{2|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt;&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|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3809</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3809"/>
		<updated>2024-09-19T14:44:54Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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;[https://github.com/{{{owner|CNES}}}/{{{repo|patrius-tutorials}}}/{{{action|blob}}}/{{{branch|main}}}/{{{file|{{{1|src/main/java/attitudes/LOFOffsetAttitudeLaw.java}}}}}}{{#if:{{{line|#56}}}|&amp;amp;#35;L{{{line}}}}} {{{text|{{{2|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt;&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}}}}}}{{#if:{{{line|}}}|&amp;amp;#56;L{{{line|56}}}}} {{{text|{{{2|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3808</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3808"/>
		<updated>2024-09-19T14:43:36Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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;[https://github.com/{{{owner|CNES}}}/{{{repo|patrius-tutorials}}}/{{{action|blob}}}/{{{branch|main}}}/{{{file|{{{1|src/main/java/attitudes/LOFOffsetAttitudeLaw.java}}}}}}{{#if:{{{line|#56}}}|&amp;amp;#35;L{{{line}}}}} {{{text|{{{2|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt;&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}}}}}}{{{{{line|56}}}}} {{{text|{{{2|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3807</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3807"/>
		<updated>2024-09-19T14:42:33Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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;[https://github.com/{{{owner|CNES}}}/{{{repo|patrius-tutorials}}}/{{{action|blob}}}/{{{branch|main}}}/{{{file|{{{1|src/main/java/attitudes/LOFOffsetAttitudeLaw.java}}}}}}{{#if:{{{line|#56}}}|&amp;amp;#35;L{{{line}}}}} {{{text|{{{2|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt;&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}}}}}}{{#if:{{{line|}}}|&amp;amp;#35;L{{{line|56}}}}} {{{text|{{{2|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&lt;br /&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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3806</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3806"/>
		<updated>2024-09-19T14:40:33Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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;[https://github.com/{{{owner|CNES}}}/{{{repo|patrius-tutorials}}}/{{{action|blob}}}/{{{branch|main}}}/{{{file|{{{1|src/main/java/attitudes/LOFOffsetAttitudeLaw.java}}}}}}{{#if:{{{line|#56}}}|&amp;amp;#35;L{{{line}}}}} {{{text|{{{2|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&amp;lt;/span&amp;gt;&amp;lt;noinclude&amp;gt;&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}}}}}}{{#if:{{{line|56}}}|&amp;amp;#35;L{{{line}}}}} {{{text|{{{2|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3805</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3805"/>
		<updated>2024-09-19T14:39:16Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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;[https://github.com/{{{owner|CNES}}}/{{{repo|patrius-tutorials}}}/{{{action|blob}}}/{{{branch|main}}}/{{{file|{{{1|src/main/java/attitudes/LOFOffsetAttitudeLaw.java}}}}}}{{#if:{{{line|#56}}}|&amp;amp;#35;L{{{line}}}}} {{{text|{{{2|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&amp;lt;/span&amp;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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3804</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3804"/>
		<updated>2024-09-19T14:38:30Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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;[https://github.com/{{{owner|CNES}}}/{{{repo|patrius-tutorials}}}/{{{action|blob}}}/{{{branch|main}}}/{{{file|{{{1|src/main/java/attitudes/LOFOffsetAttitudeLaw.java}}}}}}{{#if:{{{line|56}}}|&amp;amp;#35;L{{{line}}}}} {{{text|{{{2|{{{file|{{{1|LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&amp;lt;/span&amp;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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3803</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3803"/>
		<updated>2024-09-19T14:37:42Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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;[https://github.com/{{{owner|CNES}}}/{{{repo|patrius-tutorials}}}/{{{action|blob}}}/{{{branch|main}}}/{{{file|{{{1|src/main/java/attitudes/LOFOffsetAttitudeLaw.java}}}}}}{{#if:{{{line|}}}|&amp;amp;#35;L{{{line}}}}} {{{text|{{{2|{{{file|{{{1|attitudes/LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&amp;lt;/span&amp;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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3802</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3802"/>
		<updated>2024-09-19T14:31:21Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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;[https://github.com/{{{owner|CNES}}}/{{{repo|patrius-tutorials}}}/{{{action|blob}}}/{{{branch|main}}}/{{{file|{{{1|}}}}}}{{#if:{{{line|}}}|&amp;amp;#35;L{{{line}}}}} {{{text|{{{2|{{{file|{{{1|src/main/java/attitudes/LOFOffsetAttitudeLaw.java}}}}}}}}}}}}]&amp;lt;/span&amp;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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3801</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3801"/>
		<updated>2024-09-19T14:21:57Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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;
{{github |file=https://github.com/CNES/patrius-tutorials/blob/main/src/main/java/attitudes/LOFOffsetAttitudeLaw.java |line=1 }}&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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3800</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3800"/>
		<updated>2024-09-19T14:19:43Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.14}}/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.14}}/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;
{{github |text=https://github.com/CNES/patrius-tutorials/blob/main/src/main/java/attitudes/LOFOffsetAttitudeLaw.java |line=1 }}&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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3799</id>
		<title>User Manual 4.14 Attitude law</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.14_Attitude_law&amp;diff=3799"/>
		<updated>2024-09-19T14:16:32Z</updated>

		<summary type="html">&lt;p&gt;Admin : test&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.14}}/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.14}}/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;
{{github |file=https://github.com/CNES/patrius-tutorials/blob/main/src/main/java/attitudes/LOFOffsetAttitudeLaw.java |line=1 }}&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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/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.14}}/fr/cnes/sirius/patrius/attitudes/AeroAttitudeLaw.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.14_Attitude]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_5.0&amp;diff=3798</id>
		<title>Catégorie:User Manual 5.0</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:User_Manual_5.0&amp;diff=3798"/>
		<updated>2024-09-17T08:04:44Z</updated>

		<summary type="html">&lt;p&gt;Admin : 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.... »&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;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Mod%C3%A8le:PathCurrentJavaDoc&amp;diff=3718</id>
		<title>Modèle:PathCurrentJavaDoc</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Mod%C3%A8le:PathCurrentJavaDoc&amp;diff=3718"/>
		<updated>2024-09-02T09:01:52Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;http://patrius.cnes.fr/uploads/JavaDocs/V4.14&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.8.1&amp;diff=3635</id>
		<title>Catégorie:Tutorials 4.8.1</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.8.1&amp;diff=3635"/>
		<updated>2024-08-01T09:08:45Z</updated>

		<summary type="html">&lt;p&gt;Admin : patrius 4.8.1 tutorials&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://github.com/CNES/patrius-tutorials/tree/patrius-v4.8.1 Tutorials PATRIUS 4.8.1]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The tutorials for PATRIUS v4.8.1 can now be found on the [https://github.com/CNES/patrius-tutorials/tree/patrius-v4.8.1 CNES&#039; GitHub page]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=MediaWiki:Sidebar&amp;diff=3634</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=MediaWiki:Sidebar&amp;diff=3634"/>
		<updated>2024-08-01T09:07:49Z</updated>

		<summary type="html">&lt;p&gt;Admin : update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
* PATRIUS&lt;br /&gt;
** mainpage|Welcome&lt;br /&gt;
* Evolutions&lt;br /&gt;
** Main_differences_between_V4.13_and_V4.12|Main differences between V4.13 and V4.12&lt;br /&gt;
** Main_differences_between_V4.12_and_V4.11|Main differences between V4.12 and V4.11&lt;br /&gt;
** Main_differences_between_V4.11_and_V4.10|Main differences between V4.11 and V4.10&lt;br /&gt;
** Main_differences_between_V4.10_and_V4.9|Main differences between V4.10 and V4.9&lt;br /&gt;
** Main_differences_between_V4.9_and_V4.8|Main differences between V4.9 and V4.8&lt;br /&gt;
** Main_differences_between_V4.8_and_V4.7|Main differences between V4.8 and V4.7&lt;br /&gt;
** Main_differences_between_V4.7_and_V4.6.1|Main differences between V4.7 and V4.6.1&lt;br /&gt;
** Main_differences_between_V4.6_and_V4.5.1|Main differences between V4.6.1 and V4.5.1&lt;br /&gt;
** Main_differences_between_V4.5_and_V4.4|Main differences between V4.5.1 and V4.4&lt;br /&gt;
** Main_differences_between_V4.4_and_V4.3|Main differences between V4.4 and V4.3&lt;br /&gt;
** Main_differences_between_V4.3_and_V4.2|Main differences between V4.3 and V4.2&lt;br /&gt;
** Main_differences_between_V4.2_and_V4.1.1|Main differences between V4.2 and V4.1.1&lt;br /&gt;
** Main_differences_between_V4.1.1_and_V4.1|Main differences between V4.1.1 and V4.1&lt;br /&gt;
** Main_differences_between_V4.1_and_V4.0|Main differences between V4.1 and V4.0&lt;br /&gt;
** Main_differences_between_V4.0_and_V3.4.1|Main differences between V4.0 and V3.4.1&lt;br /&gt;
* User Manual&lt;br /&gt;
** Category:User_Manual_4.13|User Manual 4.13&lt;br /&gt;
** Category:User_Manual_4.12|User Manual 4.12&lt;br /&gt;
** Category:User_Manual_4.11|User Manual 4.11&lt;br /&gt;
** Category:User_Manual_4.10|User Manual 4.10&lt;br /&gt;
** Category:User_Manual_4.9|User Manual 4.9&lt;br /&gt;
** Category:User_Manual_4.8|User Manual 4.8&lt;br /&gt;
** Category:User_Manual_4.7|User Manual 4.7&lt;br /&gt;
** Category:User_Manual_4.6|User Manual 4.6.1&lt;br /&gt;
** Category:User_Manual_4.5|User Manual 4.5.1&lt;br /&gt;
** Category:User_Manual_4.4|User Manual 4.4&lt;br /&gt;
** Category:User_Manual_4.3|User Manual 4.3&lt;br /&gt;
** Category:User_Manual_4.2|User Manual 4.2&lt;br /&gt;
** Category:User_Manual_4.1|User Manual 4.1&lt;br /&gt;
** Category:User_Manual_4.0|User Manual 4.0&lt;br /&gt;
** Category:User_Manual_3.4.1|User Manual 3.4.1&lt;br /&gt;
** Category:User_Manual_3.3|User Manual 3.3&lt;br /&gt;
* Tutorials&lt;br /&gt;
** Category:Tutorials_4.13.5|Tutorials 4.13.5&lt;br /&gt;
** Category:Tutorials_4.12.1|Tutorials 4.12.1&lt;br /&gt;
** Category:Tutorials_4.8.1|Tutorials 4.8.1&lt;br /&gt;
** Category:Tutorials_4.5.1|Tutorials 4.5.1&lt;br /&gt;
** Category:Tutorials_4.4|Tutorials 4.4&lt;br /&gt;
** Category:Tutorials_4.1|Tutorials 4.1&lt;br /&gt;
** Category:Tutorials_4.0|Tutorials 4.0&lt;br /&gt;
* Links&lt;br /&gt;
** https://logiciels.cnes.fr/en/home|CNES freeware server&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.12.1&amp;diff=3633</id>
		<title>Catégorie:Tutorials 4.12.1</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.12.1&amp;diff=3633"/>
		<updated>2024-08-01T09:04:27Z</updated>

		<summary type="html">&lt;p&gt;Admin : patrius 4.12.1 tutorials&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://github.com/CNES/patrius-tutorials/tree/patrius-v4.12.1 Tutorials PATRIUS 4.12.1]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The tutorials for PATRIUS v4.12.1 can now be found on the [https://github.com/CNES/patrius-tutorials/tree/patrius-v4.12.1 CNES&#039; GitHub page].&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.13.5&amp;diff=3632</id>
		<title>Catégorie:Tutorials 4.13.5</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Cat%C3%A9gorie:Tutorials_4.13.5&amp;diff=3632"/>
		<updated>2024-07-30T08:22:25Z</updated>

		<summary type="html">&lt;p&gt;Admin : minor update&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[https://github.com/CNES/patrius-tutorials/tree/patrius-v4.13.5 Tutorials PATRIUS 4.13.5]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The tutorials for PATRIUS v4.13.5 can now be found on the [https://github.com/CNES/patrius-tutorials/tree/patrius-v4.13.5 CNES&#039; GitHub page]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=MediaWiki:Sidebar&amp;diff=3631</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=MediaWiki:Sidebar&amp;diff=3631"/>
		<updated>2024-07-30T08:17:53Z</updated>

		<summary type="html">&lt;p&gt;Admin : Added link to tutorials for PATRIUS 4.13.5&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*&lt;br /&gt;
* PATRIUS&lt;br /&gt;
** mainpage|Welcome&lt;br /&gt;
* Evolutions&lt;br /&gt;
** Main_differences_between_V4.13_and_V4.12|Main differences between V4.13 and V4.12&lt;br /&gt;
** Main_differences_between_V4.12_and_V4.11|Main differences between V4.12 and V4.11&lt;br /&gt;
** Main_differences_between_V4.11_and_V4.10|Main differences between V4.11 and V4.10&lt;br /&gt;
** Main_differences_between_V4.10_and_V4.9|Main differences between V4.10 and V4.9&lt;br /&gt;
** Main_differences_between_V4.9_and_V4.8|Main differences between V4.9 and V4.8&lt;br /&gt;
** Main_differences_between_V4.8_and_V4.7|Main differences between V4.8 and V4.7&lt;br /&gt;
** Main_differences_between_V4.7_and_V4.6.1|Main differences between V4.7 and V4.6.1&lt;br /&gt;
** Main_differences_between_V4.6_and_V4.5.1|Main differences between V4.6.1 and V4.5.1&lt;br /&gt;
** Main_differences_between_V4.5_and_V4.4|Main differences between V4.5.1 and V4.4&lt;br /&gt;
** Main_differences_between_V4.4_and_V4.3|Main differences between V4.4 and V4.3&lt;br /&gt;
** Main_differences_between_V4.3_and_V4.2|Main differences between V4.3 and V4.2&lt;br /&gt;
** Main_differences_between_V4.2_and_V4.1.1|Main differences between V4.2 and V4.1.1&lt;br /&gt;
** Main_differences_between_V4.1.1_and_V4.1|Main differences between V4.1.1 and V4.1&lt;br /&gt;
** Main_differences_between_V4.1_and_V4.0|Main differences between V4.1 and V4.0&lt;br /&gt;
** Main_differences_between_V4.0_and_V3.4.1|Main differences between V4.0 and V3.4.1&lt;br /&gt;
* User Manual&lt;br /&gt;
** Category:User_Manual_4.13|User Manual 4.13&lt;br /&gt;
** Category:User_Manual_4.12|User Manual 4.12&lt;br /&gt;
** Category:User_Manual_4.11|User Manual 4.11&lt;br /&gt;
** Category:User_Manual_4.10|User Manual 4.10&lt;br /&gt;
** Category:User_Manual_4.9|User Manual 4.9&lt;br /&gt;
** Category:User_Manual_4.8|User Manual 4.8&lt;br /&gt;
** Category:User_Manual_4.7|User Manual 4.7&lt;br /&gt;
** Category:User_Manual_4.6|User Manual 4.6.1&lt;br /&gt;
** Category:User_Manual_4.5|User Manual 4.5.1&lt;br /&gt;
** Category:User_Manual_4.4|User Manual 4.4&lt;br /&gt;
** Category:User_Manual_4.3|User Manual 4.3&lt;br /&gt;
** Category:User_Manual_4.2|User Manual 4.2&lt;br /&gt;
** Category:User_Manual_4.1|User Manual 4.1&lt;br /&gt;
** Category:User_Manual_4.0|User Manual 4.0&lt;br /&gt;
** Category:User_Manual_3.4.1|User Manual 3.4.1&lt;br /&gt;
** Category:User_Manual_3.3|User Manual 3.3&lt;br /&gt;
* Tutorials&lt;br /&gt;
** Category:Tutorials_4.13.5|Tutorials 4.13.5&lt;br /&gt;
** Category:Tutorials_4.5.1|Tutorials 4.5.1&lt;br /&gt;
** Category:Tutorials_4.4|Tutorials 4.4&lt;br /&gt;
** Category:Tutorials_4.1|Tutorials 4.1&lt;br /&gt;
** Category:Tutorials_4.0|Tutorials 4.0&lt;br /&gt;
* Links&lt;br /&gt;
** https://logiciels.cnes.fr/en/home|CNES freeware server&lt;br /&gt;
* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** randompage-url|randompage&lt;br /&gt;
** helppage|help&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Mod%C3%A8le:PathCurrentJavaDoc&amp;diff=3627</id>
		<title>Modèle:PathCurrentJavaDoc</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Mod%C3%A8le:PathCurrentJavaDoc&amp;diff=3627"/>
		<updated>2024-01-11T13:09:03Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;http://patrius.cnes.fr/uploads/JavaDocs/V4.13&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Accueil&amp;diff=3626</id>
		<title>Accueil</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Accueil&amp;diff=3626"/>
		<updated>2024-01-11T13:05:29Z</updated>

		<summary type="html">&lt;p&gt;Admin : /* JAVA DOC */&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://logiciels.cnes.fr/en/content/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.13 ==&lt;br /&gt;
&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; V4.13 is a release adding a few features as well as correcting some bugs (see [[Main_differences_between_V4.13_and_V4.12|here]]).&lt;br /&gt;
&lt;br /&gt;
== PREVIOUS VERSIONS (available on the Web site) ==&lt;br /&gt;
&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;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Version&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.13&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.12&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.11&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.10&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.9&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.8&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.7&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.6.1&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.5.1&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.4&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.2&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.1.1&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.0&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|3.x&lt;br /&gt;
|-&lt;br /&gt;
|Disponibility&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 19/12/2023&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 19/12/2023&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 23/05/2023&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 03/11/2022&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 30/05/2022&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 20/10/2021&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 04/06/2021&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 02/04/2021&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 13/08/2020&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 30/10/2019&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 15/06/2019&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 17/01/2019&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 16/10/2018&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 22/01/2018&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| -&lt;br /&gt;
|-&lt;br /&gt;
|Javadoc&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes            &lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|-&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|Dependencies &lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.7&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.7&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.6&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.6&amp;lt;br/&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== JAVA DOC ==&lt;br /&gt;
&lt;br /&gt;
[{{PathCurrentJavaDoc}} Current Java Doc]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.13 Java Doc 4.13]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.12 Java Doc 4.12]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.11 Java Doc 4.11]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.10.2 Java Doc 4.10.2]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.9.1 Java Doc 4.9.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.8 Java Doc 4.8]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.7 Java Doc 4.7]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.6.1 Java Doc 4.6.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.5.1 Java Doc 4.5.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.4 Java Doc 4.4]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.3 Java Doc 4.3]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.2 Java Doc 4.2]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.1.1 Java Doc 4.1.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.1 Java Doc 4.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.0 Java Doc 4.0]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V3.4.1 Java Doc 3.4.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V3.3 Java Doc 3.3]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V3.2 Java Doc 3.2]&amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=Accueil&amp;diff=3625</id>
		<title>Accueil</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=Accueil&amp;diff=3625"/>
		<updated>2024-01-11T13:04:31Z</updated>

		<summary type="html">&lt;p&gt;Admin : /* JAVA DOC */&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://logiciels.cnes.fr/en/content/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.13 ==&lt;br /&gt;
&amp;lt;font color=#556B2F&amp;gt;&#039;&#039;&#039;PATRIUS&#039;&#039;&#039;&amp;lt;/font&amp;gt; V4.13 is a release adding a few features as well as correcting some bugs (see [[Main_differences_between_V4.13_and_V4.12|here]]).&lt;br /&gt;
&lt;br /&gt;
== PREVIOUS VERSIONS (available on the Web site) ==&lt;br /&gt;
&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;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Version&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.13&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.12&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.11&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.10&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.9&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.8&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.7&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.6.1&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.5.1&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.4&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.3&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.2&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.1.1&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|4.0&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|3.x&lt;br /&gt;
|-&lt;br /&gt;
|Disponibility&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 19/12/2023&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 19/12/2023&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 23/05/2023&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 03/11/2022&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 30/05/2022&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 20/10/2021&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 04/06/2021&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 02/04/2021&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 13/08/2020&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 30/10/2019&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 15/06/2019&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 17/01/2019&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 16/10/2018&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| from 22/01/2018&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;| -&lt;br /&gt;
|-&lt;br /&gt;
|Javadoc&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes            &lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|yes&lt;br /&gt;
|-&lt;br /&gt;
|- style=&amp;quot;vertical-align:top;&amp;quot;&lt;br /&gt;
|Dependencies &lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.8&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.7&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.7&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.6&amp;lt;br/&amp;gt;&lt;br /&gt;
|style=&amp;quot;text-align:center;&amp;quot;|Java 1.6&amp;lt;br/&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== JAVA DOC ==&lt;br /&gt;
&lt;br /&gt;
[{{PathCurrentJavaDoc}} http://patrius.cnes.fr/uploads/JavaDocs/V4.13 Java Doc 4.13]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.13 Java Doc 4.13]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.12 Java Doc 4.12]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.11 Java Doc 4.11]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.10.2 Java Doc 4.10.2]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.9.1 Java Doc 4.9.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.8 Java Doc 4.8]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.7 Java Doc 4.7]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.6.1 Java Doc 4.6.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.5.1 Java Doc 4.5.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.4 Java Doc 4.4]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.3 Java Doc 4.3]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.2 Java Doc 4.2]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.1.1 Java Doc 4.1.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.1 Java Doc 4.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V4.0 Java Doc 4.0]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V3.4.1 Java Doc 3.4.1]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V3.3 Java Doc 3.3]&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://patrius.cnes.fr/uploads/JavaDocs/V3.2 Java Doc 3.2]&amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Celestial_bodies&amp;diff=3624</id>
		<title>User Manual 4.13 Celestial bodies</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Celestial_bodies&amp;diff=3624"/>
		<updated>2023-12-21T15:14:53Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.13}}/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.13}}/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.13}}/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;
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;
* &amp;lt;code&amp;gt;getEllipsoid(EllipsoidType)&amp;lt;/code&amp;gt; which returns the ellipsoid corresponding to the ellipsoid type given in input.&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;
== 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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/fr/cnes/sirius/patrius/bodies/mesh/FacetBodyShape.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.13}}/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.13}}/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.13}}/fr/cnes/sirius/patrius/bodies/mesh/GeodeticMeshLoader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.13_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Celestial_bodies&amp;diff=3623</id>
		<title>User Manual 4.13 Celestial bodies</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Celestial_bodies&amp;diff=3623"/>
		<updated>2023-12-21T15:09:14Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.13}}/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.13}}/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.13}}/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;
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;
==== 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;
* &amp;lt;code&amp;gt;getEllipsoid(EllipsoidType)&amp;lt;/code&amp;gt; which returns the ellipsoid corresponding to the ellipsoid type given in input.&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;
== 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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/fr/cnes/sirius/patrius/bodies/mesh/FacetBodyShape.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.13}}/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.13}}/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.13}}/fr/cnes/sirius/patrius/bodies/mesh/GeodeticMeshLoader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.13_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Frames&amp;diff=3622</id>
		<title>User Manual 4.13 Frames</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Frames&amp;diff=3622"/>
		<updated>2023-12-21T15:03:21Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.13}}/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.13}}/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.13}}/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 BodyShape and GeodeticPoint classes.&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 GeodeticPoint point = new GeodeticPoint(FastMath.toRadians(43.604482), FastMath.toRadians(1.443962), 0.);     &lt;br /&gt;
final TopocentricFrame topoNorth = new TopocentricFrame(earthSpheric, 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;
== 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;FactoryManagedFrame&#039;&#039;&#039;&lt;br /&gt;
| Base class for the predefined frames that are managed by FramesFactory.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/frames/FactoryManagedFrame.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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/fr/cnes/sirius/patrius/frames/H0MinusNFrame.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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Frames&amp;diff=3621</id>
		<title>User Manual 4.13 Frames</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Frames&amp;diff=3621"/>
		<updated>2023-12-21T14:46:28Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.13}}/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.13}}/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;
** 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.13}}/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 BodyShape and GeodeticPoint classes.&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 GeodeticPoint point = new GeodeticPoint(FastMath.toRadians(43.604482), FastMath.toRadians(1.443962), 0.);     &lt;br /&gt;
final TopocentricFrame topoNorth = new TopocentricFrame(earthSpheric, 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;
== 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;FactoryManagedFrame&#039;&#039;&#039;&lt;br /&gt;
| Base class for the predefined frames that are managed by FramesFactory.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/frames/FactoryManagedFrame.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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/fr/cnes/sirius/patrius/frames/H0MinusNFrame.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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Frames_configuration&amp;diff=3620</id>
		<title>User Manual 4.13 Frames configuration</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Frames_configuration&amp;diff=3620"/>
		<updated>2023-12-21T14:39:46Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOPHistory.html EOPHistory] interface represents EOP data. It has two implementations : [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOP1980History.html EOP1980History] and [{{JavaDoc4.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/fr/cnes/sirius/patrius/frames/configuration/eop/EOPC04FilesLoader.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.13_Flight_Dynamics]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Events:_ground_stations_and_satellites&amp;diff=3619</id>
		<title>User Manual 4.13 Events: ground stations and satellites</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Events:_ground_stations_and_satellites&amp;diff=3619"/>
		<updated>2023-12-21T14:35:06Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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;stations and satellites&amp;quot;.&lt;br /&gt;
&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.13}}/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.13}}/fr/cnes/sirius/patrius/events/package-summary.html Package fr.cnes.sirius.patrius.events]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The classes to build the stations models and satellites models are in the packages (and their sub-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.13}}/fr/cnes/sirius/patrius/assembly/package-summary.html Package fr.cnes.sirius.patrius.assembly]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/groundstation/package-summary.html Package fr.cnes.sirius.patrius.groundstation]&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;stations and satellites&amp;quot; event detectors :&lt;br /&gt;
&lt;br /&gt;
==== ApparentElevationDetector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function computes the difference between the satellite apparent elevation &amp;lt;math&amp;gt;\theta_{app}&amp;lt;/math&amp;gt;(the sum of geometrical elevation and refraction angle) and the threshold elevation &amp;lt;math&amp;gt;\theta_{thr}&amp;lt;/math&amp;gt;. &amp;lt;br&amp;gt;&lt;br /&gt;
This function is identical to the satellite elevation g function, except for the refraction angle term.&amp;lt;br&amp;gt;&lt;br /&gt;
The tropospheric correction refraction angle is computed according to Saemundssen formula quoted by Meeus.&lt;br /&gt;
&lt;br /&gt;
==== ElevationDetector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function is the difference between the current elevation &amp;lt;math&amp;gt;\theta _{satellite}&amp;lt;/math&amp;gt;and the threshold elevation &amp;lt;math&amp;gt;\theta _{seuil}&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;lt;0 :&amp;lt;/math&amp;gt;: the satellite is outside the cone delimited by the threshold elevation angle;&lt;br /&gt;
* &amp;lt;math&amp;gt;g&amp;gt;0 :&amp;lt;/math&amp;gt;: the satellite is inside the cone.&lt;br /&gt;
[[File:elevation.png]]&lt;br /&gt;
&lt;br /&gt;
==== ExtremaElevationDetector ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;ExtremaElevationDetector&amp;lt;/code&amp;gt; detects if the spacecraft is at a local extremum for the elevation. The choice of the extremum (maximum, minimum, or both) is done with the constructor, through the &amp;lt;code&amp;gt;elevationType&amp;lt;/code&amp;gt; parameter.&amp;lt;br&amp;gt;&lt;br /&gt;
The g switching function returns the elevation rate in the topocentric frame. An event occurs when the elevation rate is 0 meaning the satellite has reached an extrema. With P the satellite position, V its velocity and P,,proj,, the projection of the satellite position in the (X, Y) plane of the topocentric frame, the elevation rate is P,,proj,, ^ (P ^ V) / (||P,,proj,,||.||P||).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== GroundMaskElevationDetector ====&lt;br /&gt;
&lt;br /&gt;
The g switching function computes the difference between the current elevation &amp;lt;math&amp;gt;\theta _{sat}&amp;lt;/math&amp;gt;and the elevation for current azimuth interpolated from azimuth-elevation mask : &amp;lt;math&amp;gt;\theta _{mask}(\alpha _{sat})&amp;lt;/math&amp;gt;. Since the &amp;lt;math&amp;gt;\theta _{mask}&amp;lt;/math&amp;gt; term can be considered as the threshold angle, the ground mask elevation detector g function is identical to the elevation detector function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== VisibilityFromStationDetector ====&lt;br /&gt;
&lt;br /&gt;
The g function is positive when the spacecraft is in the station&#039;s field of view, negative otherwise. The station is defined by its topocentric frame. A field of view of the &amp;lt;code&amp;gt;IFieldOfView&amp;lt;/code&amp;gt; type, defined in that frame, must be given, or directly an array of azimuths and elevations to define the field as it is done in the &amp;lt;code&amp;gt;GroundMaskElevationDetector&amp;lt;/code&amp;gt;&#039;s constructor. A tropospheric correction (&amp;lt;code&amp;gt;TroposphericCorrection&amp;lt;/code&amp;gt; interface) can be taken into account in the computation. Set that correction as &amp;quot;null&amp;quot; to ignore it. &amp;lt;br&amp;gt;&lt;br /&gt;
The station sensor model must have been correctly defined, its target being the spacecraft&#039;s sensor model (please refer to the next section : &amp;quot;PATRIUS models for satellites and stations antennas&amp;quot;).&lt;br /&gt;
Masking from celestial bodies and spacecraft can be taken into account.&lt;br /&gt;
&lt;br /&gt;
==== StationToSatMutualVisibilityDetector ====&lt;br /&gt;
&lt;br /&gt;
The g function is positive when the spacecraft is in the station&#039;s field of view (same definitions as in the &amp;lt;code&amp;gt;VisibilityFromStationDetector&amp;lt;/code&amp;gt; detector, with same use of a tropospheric correction, only for the sight from the station), AND the station is in the spacecraft&#039;s given sensor&#039;s field of view (same definition as in the &amp;lt;code&amp;gt;TargetInFieldOfViewDetector&amp;lt;/code&amp;gt;), negative otherwise. &amp;lt;br&amp;gt;&lt;br /&gt;
The spacecraft&#039;s sensor must have been correctly defined, its target being the station sensor model (please refer to the next section : &amp;quot;PATRIUS models for satellites and stations antennas&amp;quot;).&amp;lt;br&amp;gt;&lt;br /&gt;
A boolean set at construction allows the user to decide to take maskings into account or not. So if asked, the visibility is interrupted when an object is masking, computing it the same way as in the [MIS_SENSORS_Home MaskingDetector].&lt;br /&gt;
&lt;br /&gt;
==== SatToSatMutualVisibilityDetector ====&lt;br /&gt;
&lt;br /&gt;
The g function is positive when the main spacecraft (the one concerned by the orbit propagation that inclues this detector) is the secondary one&#039;s given sensor&#039;s field of view AND the secondary spacecraft is in the main one&#039;s given sensor&#039;s field of view (both with the same definition as in the &amp;lt;code&amp;gt;TargetInFieldOfViewDetector&amp;lt;/code&amp;gt;).&amp;lt;br&amp;gt;&lt;br /&gt;
Each of the two sensors must have been correctly defined, with the other sensor being the main target (please refer to the next section : &amp;quot;PATRIUS models for satellites and stations antennas&amp;quot;).&amp;lt;br&amp;gt;&lt;br /&gt;
A boolean set at construction allows the user to decide to take maskings into account or not. So if asked, the visibility is interrupted when an object is masking, computing it the same way as in the [MIS_SENSORS_Home MaskingDetector].&lt;br /&gt;
&lt;br /&gt;
==== RFVisibilityDetector ====&lt;br /&gt;
&lt;br /&gt;
This detector computes the link budget between the ground station antenna and the satellite antenna and compares it to a threshold value; the model representing the RF link budget (&amp;lt;code&amp;gt;RFLinkBudgetModel&amp;lt;/code&amp;gt; class) must be known by the detector in order to perform this computation (see the [SPC_LINKBUDGET_Home Link budget properties and models page]).&amp;lt;br&amp;gt;&lt;br /&gt;
The g switching function is positive when the link budget is bigger than a threshold value; the threshold value is chosen by the user as it is an input parameter of the detector.&lt;br /&gt;
&lt;br /&gt;
=== Focus on visibility detection ===&lt;br /&gt;
==== PATRIUS models for station and satellite antennas ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;VisibilityFromStationDetector&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;StationToSatMutualVisibilityDetector&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;SatToSatMutualVisibilityDetector&amp;lt;/code&amp;gt; detectors use the PATRIUS ground station antennas and satellite antennas models. Here is a short description of them. &amp;lt;br&amp;gt;&lt;br /&gt;
For more details, please refer to the specific pages (mainly in the Spacecraft user manual).&lt;br /&gt;
&lt;br /&gt;
===== Station antennas =====&lt;br /&gt;
&lt;br /&gt;
For advanced use of stations antennas, the &amp;lt;code&amp;gt;GeometricStationAntenna&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;RFStationAntenna&amp;lt;/code&amp;gt; objects are used (package &amp;lt;code&amp;gt;fr/cnes/sirius/patrius/groundstation&amp;lt;/code&amp;gt;).&amp;lt;br&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;GeometricStationAntenna&amp;lt;/code&amp;gt; is defined by :&lt;br /&gt;
&lt;br /&gt;
*  its topocentric frame (see the [FDY_FRAME_Home frames page]);&lt;br /&gt;
*  its field of view expressed in the topocentric frame (see the [SPC_FIELD_mainPage fields of view page]).&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;RFStationAntenna&amp;lt;/code&amp;gt; is defined by :&lt;br /&gt;
&lt;br /&gt;
*  its topocentric frame;&lt;br /&gt;
*  its specific parameter for RF Link Budget computations;&lt;br /&gt;
*  no limitation of the field (no mask, no field of view). It can be limited by the RF parameters.&lt;br /&gt;
&lt;br /&gt;
For detection of simple visibility events, not depending on satellite attitude, these objects are not necessary (use &amp;lt;code&amp;gt;ElevationDetector&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;ApparentElevationDetector&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;GroundMaskElevationDetector&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
===== Satellite antennas =====&lt;br /&gt;
&lt;br /&gt;
A generic satellite antenna should be represented by a Part of an assembly. One or more properties can be added to this Part to model its physical and/or geometrical features. &lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;SensorProperty&amp;lt;/code&amp;gt; can be added to a satellite antenna in order to simulate the mutual visibility among antennas; it must contain at least a &amp;quot;main field of view&amp;quot;, that will be used for all the computations.&amp;lt;br&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;SensorProperty&amp;lt;/code&amp;gt; is used by a &amp;lt;code&amp;gt;SensorModel&amp;lt;/code&amp;gt; of the [SPC_Home assembly]), which contains the algorithm to compute the antennas visibility.&amp;lt;br&amp;gt;&lt;br /&gt;
Once a &amp;lt;code&amp;gt;SensorModel&amp;lt;/code&amp;gt; built, the proper target must be set, using the &amp;quot;setMainTarget&amp;quot; method :&lt;br /&gt;
&lt;br /&gt;
* For the station-satellite mutual visibility, the station model, that is a PVCoordinatesProvider) must be set as this main target.&lt;br /&gt;
* For satellites mutual visibility, the &amp;lt;code&amp;gt;SensorModel&amp;lt;/code&amp;gt; of the other satellite must be set as this main target, for both of them.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;RFAntennaProperty&amp;lt;/code&amp;gt; is used to set some RF features to a satellite antenna, when computing an RF link budget.&lt;br /&gt;
&lt;br /&gt;
==== Detection of satellite/ground station visibility events ====&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;VisibilityFromStationDetector&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;StationToSatMutualVisibilityDetector&amp;lt;/code&amp;gt; both use the same description of a station antenna.&amp;lt;br&amp;gt;&lt;br /&gt;
Both have two constructors :&lt;br /&gt;
&lt;br /&gt;
* One that needs a &amp;lt;code&amp;gt;GeometricStationAntenna&amp;lt;/code&amp;gt; object to define the station (frame and field of view)&lt;br /&gt;
* One that directly needs a topocentric frame, and an azimuth/elevation array. Internally, this one works as the first: it creates a field of view from the azimuth/elevation array. It is juste more simple to use.&lt;br /&gt;
&lt;br /&gt;
A tropospheric correction can be considered when computing the visibility; in this case, the user should use the classes implementing the &amp;lt;code&amp;gt;TroposphericCorrection&amp;lt;/code&amp;gt; interface (in the package &amp;lt;code&amp;gt;fr/cnes/sirius/patrius/signalpropagation&amp;lt;/code&amp;gt;). When using a tropospheric correction, the temperature, moisture and pressure parameters of the station must be, if necessary, coherent with the considered station in the given tropospheric model.&lt;br /&gt;
&lt;br /&gt;
==== Detection of mutual satellites visibility events ====&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;code&amp;gt;SatToSatMutualVisibilityDetector&amp;lt;/code&amp;gt; contains the algorythm to detect satellites mutual visibility events; to use it, apply the following instructions:&lt;br /&gt;
&lt;br /&gt;
* The detector is added to one of the spacecraft&#039;s propagator: this spacecraft becomes the &amp;quot;main&amp;quot; one;&lt;br /&gt;
* Each spacecraft is built out of an Assembly object and associated to a SensorProperty/SensorModel construction that represents its antenna;&lt;br /&gt;
* The secondary spacecraft&#039;s propagation is made in the detector, lead by the main one, to compute its SpacecraftState at each time step. The user shall provide a fully paramettered propagator for him in order to do so, and give it at the detector construction;&lt;br /&gt;
* If the maskings computation is wanted, all potentially masking objects set in both sensor models will be tested at each time step. No need to set the same masking object to both : they would by tested twice.&lt;br /&gt;
&lt;br /&gt;
==== Detection of RF visibility events ====&lt;br /&gt;
&lt;br /&gt;
The class &amp;lt;code&amp;gt;RFVisibilityDetector&amp;lt;/code&amp;gt; contains the algorythm to detect ground station/satellite RF visibility events. The ground station antenna is represented by a &amp;lt;code&amp;gt;RFStationAntenna&amp;lt;/code&amp;gt; class and the satellite antenna is represented by a Part of an assembly with &amp;lt;code&amp;gt;RFAntennaProperty&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
See the [SPC_LINKBUDGET_Home Link budget properties and models page] for more details on the parameters of the station antenna, the satellite antenna and for the link budget computation algorythm.&lt;br /&gt;
&lt;br /&gt;
It is&#039;&#039;&#039;NOT&#039;&#039;&#039; possible to use &amp;lt;code&amp;gt;RFAntennaProperty&amp;lt;/code&amp;gt; for RF LinkBudget computations between two satellites. Only the geometrical aspect (using a &amp;lt;code&amp;gt;Sensor Model&amp;lt;/code&amp;gt;) is available.&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
==== Detection of satellite/ground station visibility events ====&lt;br /&gt;
&lt;br /&gt;
Here is a code sample to create properly a mutual station/satellite visibility detector:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// tropospheric correction&lt;br /&gt;
//=========================&lt;br /&gt;
// pressure (millibars)&lt;br /&gt;
final double pressure = 1020;  &lt;br /&gt;
// temperature (celcius)&lt;br /&gt;
final double temperature = 20;&lt;br /&gt;
// moisture (percent)&lt;br /&gt;
final double moisture = 20;   &lt;br /&gt;
// geodetic altitude (m)&lt;br /&gt;
final double altitude = 150;&lt;br /&gt;
&lt;br /&gt;
final AngularCorrection correctionModel = new AzoulayModel(pressure, temperature, moisture, altitude);&lt;br /&gt;
&lt;br /&gt;
// station antenna model&lt;br /&gt;
//======================&lt;br /&gt;
// frame&lt;br /&gt;
final TopocentricFrame topoFrameStation = new TopocentricFrame(point, &amp;quot;Gstation&amp;quot;);&lt;br /&gt;
// field of view&lt;br /&gt;
final String nameStationField = &amp;quot;circularStationField&amp;quot;;&lt;br /&gt;
final IFieldOfView stationField = new CircularField(nameStationField, FastMath.PI / 8., Vector3D.PLUS_K);&lt;br /&gt;
// ground station&lt;br /&gt;
final GeometricStationAntenna stationModel = new GeometricStationAntenna(topoFrameStation, stationField);&lt;br /&gt;
&lt;br /&gt;
// spacecraft sensor model&lt;br /&gt;
//========================&lt;br /&gt;
// We assume here that an assembly has been built, with a sensor property on this &amp;quot;sensorPart&amp;quot; part.&lt;br /&gt;
// model creation&lt;br /&gt;
final SensorModel spacecraftSensorModel = new SensorModel(assembly, sensorPart);&lt;br /&gt;
// target adding (the antenna is here considered ponctual)&lt;br /&gt;
spacecraftSensorModel.setMainTarget(stationModel, new ConstantRadiusProvider(0.));&lt;br /&gt;
&lt;br /&gt;
// detector creation&lt;br /&gt;
//==================&lt;br /&gt;
// the &amp;quot;false&amp;quot; boolean set here indicates that no masking will be computed&lt;br /&gt;
final EventDetector detectorMainPart = new StationToSatMutualVisibilityDetector(&lt;br /&gt;
          spacecraftSensorModel, stationModel, correctionModel, false, maxCheck, threshold);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Detection of mutual satellites visibility events ====&lt;br /&gt;
&lt;br /&gt;
Here is a code sample to create properly a mutual satellite /satellite visibility detector:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// We assume here that TWO assemblies have been built (main and secondary), with a sensor property &lt;br /&gt;
// on each of them, on their &amp;quot;mainSpcSensorPart&amp;quot; and &amp;quot;secondarySpcSensorPart&amp;quot; part.&lt;br /&gt;
&lt;br /&gt;
// sensor models (the order of those operation is important !)&lt;br /&gt;
//============================================================&lt;br /&gt;
// main spacecraft model creation&lt;br /&gt;
final SensorModel mainSpcModel = new SensorModel(mainAssembly, mainSpcSensorPart);&lt;br /&gt;
// secondary spacecraft model creation&lt;br /&gt;
final SensorModel secondarySpcModel = new SensorModel(secondaryAssembly, secondarySpcSensorPart);&lt;br /&gt;
// target addings (the antennas are here considered ponctual)&lt;br /&gt;
mainSpcModel.setMainTarget(secondarySpcModel, new ConstantRadiusProvider(0.));&lt;br /&gt;
secondarySpcModel.setMainTarget(mainSpcModel, new ConstantRadiusProvider(0.));&lt;br /&gt;
&lt;br /&gt;
// propagators&lt;br /&gt;
//============&lt;br /&gt;
// We assume here that TWO propagators avec been created (main and secondary), &lt;br /&gt;
// and that the secondary one is here fully parametered (forces, initial state... but NO event detector !!)&lt;br /&gt;
&lt;br /&gt;
// detector creation and adding&lt;br /&gt;
//==============================&lt;br /&gt;
// the &amp;quot;false&amp;quot; boolean set here indicates that no masking will be computed&lt;br /&gt;
final EventDetector detector = new SatToSatMutualVisibilityDetector(mainSpcModel, &lt;br /&gt;
                secondarySpcModel , secondaryPropagator, false, maxCheck, threshold);&lt;br /&gt;
&lt;br /&gt;
mainPropagator.addEventDetector(detector);&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;
| EventDetector&lt;br /&gt;
|This interface represents an event finder.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector ]&lt;br /&gt;
|-&lt;br /&gt;
| LocalRadiusProvider&lt;br /&gt;
|Provider for local radius.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/LocalRadiusProvider.html LocalRadiusProvider ]&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;
| ApparentElevationDetector&lt;br /&gt;
|This class handles satellite apparent elevation (apparent raising and setting for a terrestrial viewpoint) events.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/ApparentElevationDetector.html ApparentElevationDetector]&lt;br /&gt;
|-&lt;br /&gt;
| ElevationDetector&lt;br /&gt;
|This class handles satellite elevation (raising and setting for a terrestrial viewpoint) events.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/ElevationDetector.html ElevationDetector]&lt;br /&gt;
|-&lt;br /&gt;
| ExtremaElevationDetector &lt;br /&gt;
|This class handles events representing the reaching of the minimal or maximal elevation in a given topocentric frame (local frame of a station).&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/ExtremaElevationDetector.html ExtremaElevationDetector ]&lt;br /&gt;
|-&lt;br /&gt;
| GroundMaskElevationDetector&lt;br /&gt;
|This class handles satellite elevation (raising and setting for a terrestrial viewpoint) events with respect to an azimuth-elevation mask.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/GroundMaskElevationDetector.html GroundMaskElevationDetector]&lt;br /&gt;
|-&lt;br /&gt;
| VisibilityFromStationDetector&lt;br /&gt;
|This class handles events representing the satellite apparent entering in a station&#039;s field of view.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/sensor/VisibilityFromStationDetector.html VisibilityFromStationDetector]&lt;br /&gt;
|-&lt;br /&gt;
| SatToSatMutualVisibilityDetector&lt;br /&gt;
|This class handles events representing the mutual visibility between two spacecraft&#039;s sensors.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/sensor/SatToSatMutualVisibilityDetector.html SatToSatMutualVisibilityDetector]&lt;br /&gt;
|-&lt;br /&gt;
| StationToSatMutualVisibilityDetector&lt;br /&gt;
|This class handles events representing the mutual visibility between a spacecraft&#039;s sensors and a station antenna.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/sensor/StationToSatMutualVisibilityDetector.html StationToSatMutualVisibilityDetector]&lt;br /&gt;
|-&lt;br /&gt;
| RFVisibilityDetector &lt;br /&gt;
|This class handles RF visibility events (when the link budget between a ground station antenna and a satellite antenna exceeds a threshold value).&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/sensor/RFVisibilityDetector.html RFVisibilityDetector ]&lt;br /&gt;
|-&lt;br /&gt;
| Constant radius provider &lt;br /&gt;
|Provider for constant radius body.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/ConstantRadiusProvider.html ConstantRadiusProvider]&lt;br /&gt;
|-&lt;br /&gt;
| Variable radius provider &lt;br /&gt;
|Provider for variable radius body (ex: one axis ellipsoid).&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/VariableRadiusProvider.html VariableRadiusProvider]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.13_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Events:_orbital&amp;diff=3618</id>
		<title>User Manual 4.13 Events: orbital</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Events:_orbital&amp;diff=3618"/>
		<updated>2023-12-21T14:34:02Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.13}}/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.13}}/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;
=== 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;
==== NodeDetector ====&lt;br /&gt;
&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.&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;
==== 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;
=== 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;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/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.13}}/fr/cnes/sirius/patrius/propagation/events/AlignmentDetector.html AlignmentDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AltitudeDetector&lt;br /&gt;
|This class handles satellite altitude crossing events.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/ApsideDetector.html ApsideDetector]&lt;br /&gt;
|-&lt;br /&gt;
| DateDetector&lt;br /&gt;
|This class handles the occurrence of predefined dates.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/EclipseDetector.html EclipseDetector]&lt;br /&gt;
|-&lt;br /&gt;
| NodeDetector&lt;br /&gt;
|This class handles satellite equator crossing events.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/propagation/events/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.13}}/fr/cnes/sirius/patrius/events/EarthZoneDetector.html EarthZoneDetector]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
[[Category:User_Manual_4.13_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Projections&amp;diff=3617</id>
		<title>User Manual 4.13 Projections</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Projections&amp;diff=3617"/>
		<updated>2023-12-21T14:29:59Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/fr/cnes/sirius/patrius/projections/ProjectionEllipsoid.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.13_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Events_detection:_Presentation&amp;diff=3616</id>
		<title>User Manual 4.13 Events detection: Presentation</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Events_detection:_Presentation&amp;diff=3616"/>
		<updated>2023-12-19T16:20:28Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes :&lt;br /&gt;
&lt;br /&gt;
* in a mono satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions that extend  event detection mechanism.&lt;br /&gt;
* in a multi satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions, copied from the mono satellite mechanism, that extend Patrius&#039;s event detection mechanism for multi satellite propagation.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The following packages are related to events detections in mono and multi propagation context:&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.13}}/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.13}}/fr/cnes/sirius/patrius/math/ode/events/package-summary.html Package fr.cnes.sirius.patrius.math.ode.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/package-summary.html Package fr.cnes.sirius.patrius.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/multi/package-summary.html Package fr.cnes.sirius.patrius.propagation.events.multi]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as 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 architecture of the events detection for mono and multi satellite propagation.&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:EventsV3.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following diagram represents the mechanism used in the Patrius library in order to create the list of the events detected during the mono satellite propagation as well as the phenomena list :&lt;br /&gt;
&lt;br /&gt;
[[File:Events.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following classes are duplicated from mono satellite context in order to create a list of events detected : &lt;br /&gt;
* [{{JavaDoc4.13}}//fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.13}}//fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
* [{{JavaDoc4.13}}//fr/cnes/sirius/patrius/events/multi/MultiEventsLogger.html MultiEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.13}}//fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Event detection ===&lt;br /&gt;
&lt;br /&gt;
The events detection process can be used during mono or multi propagation propagation, when we need to know if some events occur and at what time (for instance when the satellite will be in eclipse, or if at a given date it will be visible or not from a ground station).&lt;br /&gt;
&lt;br /&gt;
In Patrius there is one class for every kind of event: the information related to an event is contained in this class, and it will be used by the mono satellite numerical or analytical propagator when extrapolating the orbit. The mechanism is similar for multi propagation.&lt;br /&gt;
&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are detected is the order in which they are added to the propagator.&lt;br /&gt;
&lt;br /&gt;
As of PATRIUS 4.5, detectors can optionally take into account signal propagation delay. Javadoc of each event detector indicates if signal propagation delay can be taken into account through a setter &amp;lt;code&amp;gt;setPropagationDelayType()&amp;lt;/code&amp;gt;. Delay type is of 2 types:&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.INSTANTANEOUS&amp;lt;/code&amp;gt;: signal propagation delay is not taken into account&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.LIGHT_SPEED&amp;lt;/code&amp;gt;: signal propagation delay is taken into account.&lt;br /&gt;
Signal propagation delay allows to detect events as it is exactly seen by a spacecraft, for instance a visibility between a satellite and a station.&lt;br /&gt;
All detectors involving a signal propagation and or sensors can take signal propagation delay into account (BetaAngleDetector, SensorVisibilityDetector, TargetInFieldOfViewDetector, etc.):&lt;br /&gt;
&lt;br /&gt;
By default signal propagation delay is not taken into account.&lt;br /&gt;
&lt;br /&gt;
A new detector class should implements  : &lt;br /&gt;
* [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector interface] in case of [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/Propagator.html mono satellite propagation] or [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
* [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector interface] in case of [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Construction of a detector&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The action performed at event detection can be set by user at detector&#039;s construction. Several actions can be defined if several behavior are available (depending on state and/or on increasing/forward parameter). It is possible to specify at construction if the detector should be removed after event detection and thus not be detected any more. If a single action is available, a single boolean has to be provided by the user at construction. In the case where several actions are available, the same number of boolean has to be provided to determine if the detector has to be removed after event detection.&amp;lt;br&amp;gt;&lt;br /&gt;
Focusing on the &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt; for instance, two actions are possible at event detection :&lt;br /&gt;
&lt;br /&gt;
- action_at_ascending_node if an ascending node detection is done&amp;lt;br&amp;gt;&lt;br /&gt;
- action_at_descending_node if a descending node detection is performed&lt;br /&gt;
&lt;br /&gt;
If no actions are set, the user should be aware of the default implementation.&lt;br /&gt;
By default, event detectors are never removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of eventOccurred()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The returned action of the function eventOccurred could be set by user or defined by default.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function eventOccurred is common to all [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector] classes (respectively [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]) and its purpose is to handle an event and to choose what to do next ; this method is called when the integrator has accepted a step ending exactly on a sign change of the switching function, and it allows the user to choose which action will take place after the event (the simulation could be stopped, the propagator could reset its initial state or its initial derivative state ...).&lt;br /&gt;
Plus, this method is up to determine if the detector used has to be removed after the event detection : in the above example of &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt;, the action taking place after the event is set to action_at_raising_node in the case of an ascending node detection. If one has decided to remove the detector at such detection, the attribute shouldBeRemoved will be set to remove_at_ascending_node which is true by construction, the case of descending node is similar.&lt;br /&gt;
&lt;br /&gt;
Since the default implementation of eventOccurred could unfit the user needs in terms of propagation behaviour, it is recommended to check the content of the detector before using them and to change it if necessary by using a specific constructor which take as parameter the expected action(s).&lt;br /&gt;
&lt;br /&gt;
Note that the implementation of eventOccured must not contain any action. Even if the action does not impact the state vector, the action should be implemented in the resetState method.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of resetState() or resetStates()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If the event have an action, this action should be implemented in the resetState() method. In this case, the eventOccured() of the detector concerned should return a RESET_STATE action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Convergence threshold parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The convergence threshold represents the events detection precision; the following observations can help the user when choosing a value for this parameter:&lt;br /&gt;
&lt;br /&gt;
#if the convergence threshold increases, the execution time decreases (the precision becomes worst);&lt;br /&gt;
#if the convergence threshold is bigger than the max integration step, the events detection will fail.&lt;br /&gt;
&lt;br /&gt;
If the resetState(s) could modify others event detectors, the convergence threshold should be low in order to avoid any unpredictable behavior.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Max check interval parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The max check interval parameter represents the maximum interval in which the propagator checks for an event (i.e. for a sign change of the g switching function). When choosing this parameter, the user should keep in mind the following remarks:&lt;br /&gt;
&lt;br /&gt;
#if max check interval is smaller than the integration step, the execution time increases if the max check interval decreases (the events detection is more accurate);&lt;br /&gt;
#if max check interval is bigger than the max integration step, it will be replaced by the max integration step during the events detection process; in this case the max check interval is a useless parameter that will never be used by the propagator.&lt;br /&gt;
&lt;br /&gt;
In general, the user should always choose the max check interval value as a function of the integration step used during propagation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of the event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation start date, i.e if g() equal to zero, the event is processed. This case is extremely rare. Note that in some case however, due to numerical quality rounds-off, an event may not be detected at the propagation start date although it&#039;s theoritically supposed to occur. For example, starting propagation at periapsis with a periapsis detector may not detect periapsis since the g() function of PeriapsisDetector is based on position- velocity scalar product and due to rounds-off errors, its values may be around 1E-7 which is not exactly zero. &amp;lt;br&amp;gt;&lt;br /&gt;
Also, if at the propagation start date the g() function is not continuous but changes its sign (for example value-1 before event date, value 1 after), the event will also not be detected since the g() function value is not zero.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Ephemeris propagator event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one. Consequently, when propagating with a bounded propagator, if the last substep is larger than the real one then the real end date is exceeded, raising an exception. Therefore, in this case, it is recommended to &#039;&#039;&#039;propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the same date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are processed is the order in which they are added to the propagator. If the detected event stops the propagation, the other events occuring at the same date are not processed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the end date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation end date, the event is not processed.&lt;br /&gt;
&lt;br /&gt;
==== Available event detectors ====&lt;br /&gt;
Mono events detectors detect events applied on a specific state. These detectors can be used in mono or multi propagation case.&lt;br /&gt;
&lt;br /&gt;
The available mono events detectors are presented in specific pages: &lt;br /&gt;
&lt;br /&gt;
* [MIS_ORB_Home Orbit determination events]&lt;br /&gt;
* [MIS_SENSORS_Home Sensors events]&lt;br /&gt;
* [MIS_STASAT_Home Ground stations and satellites events]&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
It also exists multi events detectors applied on several states. These detectors can only be used in multi propagation case.&lt;br /&gt;
Notice that some detectors that implies several satellite coul be used in multi or mono satellite context ; ([{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/sensor/SatToSatMutualVisibilityDetector.html SatToSatMutualVisibilityDetector], [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/ThreeBodiesAngleDetector.html ThreeBodiesAngleDetector] or [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/ExtremaThreeBodiesAngleDetector.html ExtremaThreeBodiesAngleDetector])&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HMultiEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
The [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector] is a detector that detects the nth occurrence of an underlying event detector.&amp;lt;br&amp;gt;&lt;br /&gt;
However the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every event of the underlying detector. As a result, the behaviour of this detector is the following:&lt;br /&gt;
* Before and after the nth occurrence, the eventOccurred() method returns &amp;lt;code&amp;gt;Action.CONTINUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
* At the nth occurrence, the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method returns the user-provided action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Warning&#039;&#039;&#039;&#039;&#039;: the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every occurrence of the underlying detector, not only at nth occurrence. Hence, overloading this detector should be performed carefully: in the overloaded &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method, the check &amp;lt;code&amp;gt;getCurrentOccurence() == getOccurence()&amp;lt;/code&amp;gt; should be performed first to ensure we are at nth occurrence before calling &amp;lt;code&amp;gt;super.eventOccurred()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== IntervalOccurenceDetector ====&lt;br /&gt;
This [{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurenceDetector.html IntervalOccurenceDetector ] is able for any EventDetector. It detects the &amp;lt;math&amp;gt;n^{th}&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;m^{th}&amp;lt;/math&amp;gt; event occurences by step of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; occurences. &lt;br /&gt;
Otherwise, if j event occurence, the &amp;lt;code&amp;gt;IntervalOccurenceDetector&amp;lt;/code&amp;gt; detects events as : &lt;br /&gt;
* &amp;lt;math&amp;gt;(j - n) % p = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n &amp;lt;= j &amp;lt;= m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The g switching function is the function of the event to detect.&lt;br /&gt;
&lt;br /&gt;
==== ExtremaGenericDetector ====&lt;br /&gt;
&lt;br /&gt;
This class represents an event detector that detects the derivative cancellation of an underlying detector. Using this detector recursively will allow to detect nth order derivative.&lt;br /&gt;
&lt;br /&gt;
The g switching function cancels for any extrema of the g function of the underlying detector.&lt;br /&gt;
Min, max or both at the same time.&lt;br /&gt;
&lt;br /&gt;
==== Mono Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
When a numerical propagation is performed, the event detection is done at the math level since the integration is realized by one of the numerical integrators. However, the event detectors are instanciated by the user at the Patrius level. Hence the necessity of an adapter to wrap a Patrius event detector object into a math event handler object whose interfaces provide basically the same kind of services. Once the event detectors are given to the numerical propagator, they are transformed into event handlers in order to give them to the math numerical integrator.&amp;lt;br&amp;gt;&lt;br /&gt;
The numerical integrator associates each event with another object which represents its state during the integration. At the end of each step, the method acceptStep() is systematically called and performs the event detection thanks to an interpolator, inside the current step. Thus the state of each event is updated. If an event is detected therefore the integration is either stopped or continued with or without state or derivative state resetting. It is also possible to remove the detector after the first event detection and the propagation is continued. An event is represented by a function, the function &amp;quot;g()&amp;quot;: the event occurs when the function sign changes and NOT when this function equals to zero. To find this root, in addition to the interpolator, a solver is used. By default, this solver is the Brent solver. The exception being at the beginning of the propagation where events are detected when the g() function equals exactly zero.&lt;br /&gt;
&lt;br /&gt;
===== Analytical propagator =====&lt;br /&gt;
&lt;br /&gt;
When an analytical propagation is performed, the event detection is done at the Patrius level directly. The process is basically the same than its math counterpart: the detectors are given to the propagator and associated to their states. The Patrius propagator has a method acceptStep() which is similar to the one of the math package.&lt;br /&gt;
&lt;br /&gt;
===== Ephemeris propagator =====&lt;br /&gt;
&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one which could be knotty when it comes to propagate with a bounded propagator. Indeed, if the last substep is larger than the real one then the real end date is exceeded. If the end date is equal to the ephemeris max date, an exception is raised when the interpolator sets the current date to a date exceeding the ephemeris max date. Therefore, in this case, &#039;&#039;&#039;it is recommended to propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Multi Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
The event detector process for multi satellite numerical propagation is equivalent to the process performed with single satellite numerical propagation. The multi event detection is wrapped into a math event handler object. The detector could be applied on a single satellite or on several satellites.&lt;br /&gt;
&lt;br /&gt;
=== Coded events and phenomena ===&lt;br /&gt;
==== Mono propagation ====&lt;br /&gt;
===== The coded event =====&lt;br /&gt;
&lt;br /&gt;
Patrius does detect events. This means :&lt;br /&gt;
&lt;br /&gt;
* Patrius triggers a method call on the corresponding EventDetector when the event occurs.&lt;br /&gt;
* Patrius logs the SpacecraftState and g function slope sign for the occuring event (through the EventsLogger).&lt;br /&gt;
&lt;br /&gt;
But this mechanism alone doesn&#039;t provide a programmatic representation for an &amp;quot;event&amp;quot;, which may be processed after the propagation.&lt;br /&gt;
&lt;br /&gt;
A new way of handling events as individual instances was thus designed : the &amp;quot;atomic event&amp;quot; or &amp;quot;coded event&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;coded event&amp;quot; has the following attributes :&lt;br /&gt;
&lt;br /&gt;
* an event &amp;quot;code&amp;quot; : a String identifying the category of the event, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* an event &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* an AbsoluteDate : the date at which the event occurred.&lt;br /&gt;
* a boolean, true when the event represents a &amp;quot;starting&amp;quot; event, or false when it represents an &amp;quot;ending&amp;quot; event (relative to a phenomenon, see below).&lt;br /&gt;
&lt;br /&gt;
The code and comment formats are free, they depend on the CodingEventDetector implementation (see below).&lt;br /&gt;
&lt;br /&gt;
A CodedEvent is supposed to be built by the CodedEventsLogger (see below).&lt;br /&gt;
&lt;br /&gt;
Moreover, when one of the boundaries of the phenomenon is ill-defined (e.g. unknown due to computational limits), it is an instance of CodedEvent, with the code &amp;quot;UNDEFINED_EVENT&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== The CodingEventDetector and MultiCodingEventDetector =====&lt;br /&gt;
&lt;br /&gt;
The CodingEventDetector (or MultiCodingEventDetector in MultiPropagator case) is an extension of the EventDetector type(respectively MultiEventDetector). A CodingEventDetector (or MultiCodingEventDetector) has the following requirements :&lt;br /&gt;
&lt;br /&gt;
* Providing a CodedEvent builder method, that creates a CodedEvent instance appropriate for the event (this is how the code and comment are determined).&lt;br /&gt;
* Providing a Phenomenon code if a Phenomenon makes sense in the context of the event, otherwise return null (see below).&lt;br /&gt;
* Providing a boolean telling which sign of the g() method means the Phenomenon is active (see below).&lt;br /&gt;
&lt;br /&gt;
===== The phenomenon =====&lt;br /&gt;
&lt;br /&gt;
The EventDetector provides a g() method whose sign change triggers an event. Sometimes the g() method can also be seen as conveying a &amp;quot;state&amp;quot; i.e. when g() is positive (resp. negative), a &amp;quot;phenomenon&amp;quot; is going on.&lt;br /&gt;
The clearest example would be the EclipseDetector :&lt;br /&gt;
&lt;br /&gt;
* g() going from positive to negative means that the spacecraft has entered the eclipse zone.&lt;br /&gt;
* g() going from negative to positive means that the spacecraft has exited the eclipse zone.&lt;br /&gt;
&lt;br /&gt;
The associated phenomenon would then be called &amp;quot;inside the eclipse zone&amp;quot;, bounded by the starting event &amp;quot;enter eclipse zone&amp;quot; and the ending event &amp;quot;exit eclipse zone&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This library provides a &amp;quot;phenomenon&amp;quot; abstraction, as a lightweight representation.&lt;br /&gt;
&lt;br /&gt;
A Phenomenon instance is an immutable object with the following attributes :&lt;br /&gt;
&lt;br /&gt;
* a phenomenon &amp;quot;code&amp;quot; : a String identifying the category of the phenomenon, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* a phenomenon &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* two &amp;quot;coded event&amp;quot; instances : the atomic events that represent the start and the end of the phenomenon.&lt;br /&gt;
&lt;br /&gt;
Also :&lt;br /&gt;
* it tells whether the start and end are &amp;quot;well-defined&amp;quot; : a well-defined boundary has a real event backing it. A not well-defined boundary is a boundary because of computational limits : it happens when, during a propagation, the ending event occurs, but the starting event did not (or, the opposite) because it was outside the boundaries of the propagation. In this case, an &amp;quot;UNDEFINED_EVENT&amp;quot; is given as the missing boundary (see above).&lt;br /&gt;
&lt;br /&gt;
A Phenomenon is built by the CodedEventsLogger, when the CodingEventDetector provides a non-null Phenomenon string code. The existence of this code proves the Phenomenon makes senses in the context of the CodingEventDetector. For instance :&lt;br /&gt;
&lt;br /&gt;
* for a &amp;quot;CodingEclipseDetector&amp;quot; built upon the EclipseDetector, a Phenomenon has meaning (the Phenomenon being &amp;quot;inside the eclipse&amp;quot;).&lt;br /&gt;
* for a &amp;quot;CodingApsideDetector&amp;quot; built upen the ApsideDetector, a Phenomenon has no meaning, since the events are : &amp;quot;the spacecraft is at the periapsis&amp;quot; and &amp;quot;the spacecraft is at the apoapsis&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Multi propagation ====&lt;br /&gt;
The same process exists. The corresponding classes are localized in the Patrius library.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting up a CodedEventsLogger or a MultiCodedEventsLogger ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent and Phenomenon instances are not meant to be produced by the CodingEventDetectors (or directly MultiCodedEventsLogger in MultiPropagator case) (but it could be possible if needed).&lt;br /&gt;
&lt;br /&gt;
Instead, the (Multi)CodedEventsLogger was created for this purpose.&lt;br /&gt;
&lt;br /&gt;
At first glance, a (Multi)CodedEventsLogger instance is very similar to the (Multi)EventsLogger.&lt;br /&gt;
The main difference is that the (Multi)EventsLogger instances have no inner representation of events, while the (Multi)CodedEventsLogger produces CodedEvent and Phenomenon lists.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how one uses the (Multi)CodedEventsLogger :&lt;br /&gt;
&lt;br /&gt;
* create a (Multi)CodedEventsLogger instance.&lt;br /&gt;
* create at least one (Multi)CodingEventProvider instance.&lt;br /&gt;
* call the &amp;lt;code&amp;gt;monitorDetector()&amp;lt;/code&amp;gt; method on the (Multi)CodedEventsLogger : it produces a &amp;quot;wrapper&amp;quot; of the (Multi)CodingEventProvider exposed as a regular EventProvider.&lt;br /&gt;
* pass this &amp;quot;wrapper&amp;quot; to a propagator (any kind works : those who do compute a propagation and those who replay an ephemeris).&lt;br /&gt;
* run the propagator.&lt;br /&gt;
&lt;br /&gt;
While the propagator runs, the &amp;quot;wrapper&amp;quot; calls both the (Multi)CodingEventProvider instance and the (Multi)CodedEventsLogger on each event. The (Multi)CodedEventsLogger instance uses the (Multi)CodingEventProvider to build and store all CodedEvent instances during the propagation.&lt;br /&gt;
&lt;br /&gt;
==== Getting the full coded events list ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;getCodedEventsList()&amp;lt;/code&amp;gt;.&lt;br /&gt;
It provides a list of all CodedEvents (for all the CodingEventDetectors passed to the propagator, without distinction).&lt;br /&gt;
&lt;br /&gt;
==== Getting the events list per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildCodedEventListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a CodedEventsList as value, this list only containing the events generated from the key.&amp;lt;br&amp;gt;&lt;br /&gt;
It is, therfore, the same data as the full events&#039; list, but rearranged per CodingEventProvider instance.&lt;br /&gt;
&lt;br /&gt;
==== Getting the phenomena per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildPhenomenaListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a PhenomenaList as value, this list only containing the Phenomenon instances generated from the key. The(Multi) CodingEventProvider instance provides the Phenomenon code.&lt;br /&gt;
&lt;br /&gt;
The (Multi)CodedEventsLogger only uses the (Multi)CodingEventProvider instances that provide a non-null Phenomenon code (null indicates that a Phenomenon has no meaning for this detector).&lt;br /&gt;
&lt;br /&gt;
==== N-th occurrence of a coded event, or a delayed event ====&lt;br /&gt;
&lt;br /&gt;
There are two ways to generate the n-th occurrence of an event or a delayed coded event from a detected event: the first one is using the post-processing classes, and the second one is to configure the CodingEventDetector in order to create the delayed or filtered coded events during the propagation (in addition to the &amp;quot;standard&amp;quot; coded events).&lt;br /&gt;
While the former can only be done after the propagation, the latter has to be set before the propagation and is possible thanks to the following methods in the class CodingEventDetector:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buildCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the standard CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildDelayedCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the delayed CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildOccurrenceCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the n-th occurrence CodedEvent (n will be a parameter chosen by the user)&lt;br /&gt;
&lt;br /&gt;
In order to use this feature, the delay value and/or the occurrence number must be given as input parameters of the constructor of the class implementing the CodingEventDetector class (for instance GenericCodingEventDetector). The CodedEventsLogger will then be able to read these parameters and handle the generation of standard and not-standard coded events.&lt;br /&gt;
&lt;br /&gt;
Note, in the GenericCodingEventDetector constructor (EventDetector, String, String, boolean, String, double, int), if both parameters delayIn and occurrenceIn are other than 0, the event is saved as a delayed event, not a &amp;quot;Nth occurence of&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== When to use Coded events and phenomena ===&lt;br /&gt;
* To build easier time lines of events&lt;br /&gt;
* To manipulate easier phenomena (for example between &amp;quot;starting&amp;quot; and &amp;quot;ending&amp;quot; events) and associate to them specific computations (for example the evolution of the illumination during an eclipse)&lt;br /&gt;
* To apply some [MIS_POSTP_Home post-processing filters]&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Using available events detectors ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
Example of propagation stopping at 3rd detected node with event detector overloading:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Initialization&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2003, 1, 1, TimeScalesFactory.getTAI());&lt;br /&gt;
final Orbit orbit = new KeplerianOrbit(7000000, 0.01, 0.1, 0.2, 0.3, 0.4, PositionAngle.TRUE, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
&lt;br /&gt;
// Node detector&lt;br /&gt;
final EventDetector nodeDetector = new NodeDetector(orbit, FramesFactory.getGCRF(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
// Stop at 3rd detected node&lt;br /&gt;
final NthOccurrenceDetector nthOccurrenceDetector = new NthOccurrenceDetector(nodeDetector, 3, Action.STOP) {&lt;br /&gt;
    @Override&lt;br /&gt;
    public Action eventOccurred(SpacecraftState s, boolean increasing, boolean forward) throws PatriusException {&lt;br /&gt;
        super.eventOccurred(s, increasing, forward);&lt;br /&gt;
        if (getCurrentOccurence() == getOccurence()) {&lt;br /&gt;
            return Action.STOP;&lt;br /&gt;
        } else {&lt;br /&gt;
            return Action.CONTINUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Propagation&lt;br /&gt;
final KeplerianPropagator propagator = new KeplerianPropagator(orbit);&lt;br /&gt;
propagator.addEventDetector(nthOccurrenceDetector);&lt;br /&gt;
propagator.propagate(orbit.getDate().shiftedBy(86400.));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generating coded events and phenomena ===&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent instances and Phenomenon instances are meant to be produced using :&amp;lt;br&amp;gt;&lt;br /&gt;
- CodingEventDetector implementations that provide information about events and phenomena,&amp;lt;br&amp;gt;&lt;br /&gt;
- a CodingEventsLogger, that uses the CodingEventDetector instances to build the events and phenomena.&lt;br /&gt;
&lt;br /&gt;
For example, if we want to create a list of CodedEvent objects using a detector of nodes (ascending and descending orbital nodes):&lt;br /&gt;
&lt;br /&gt;
1. Create a new EventDetector (in this case a NodeDetector):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set up the node detector:&lt;br /&gt;
  AbsoluteDate date = new AbsoluteDate(&amp;quot;2000-01-01T12:00:00Z&amp;quot;, TimeScalesFactory.getTT());&lt;br /&gt;
  AbsoluteDate dateF = date.shiftedBy(2* period);&lt;br /&gt;
  Orbit orbit = new KeplerianOrbit(7e6, 0, 0.2, 0, 0, 0.2, PositionAngle.MEAN, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
  NodeDetector node = new NodeDetector(orbit, FramesFactory.getEME2000(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Create a new generic coding event detector:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // standard event&lt;br /&gt;
  GenericCodingEventDetector nodeDet =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;);&lt;br /&gt;
  // third occurence of event&lt;br /&gt;
  GenericCodingEventDetector nodeDetOcc =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 0., 3);&lt;br /&gt;
  // delayed event (10 seconds here)&lt;br /&gt;
  GenericCodingEventDetector nodeDetDel =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 10., 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Create a new CodedEventsLogger and use the &amp;lt;code&amp;gt; monitorDetector &amp;lt;/code&amp;gt; function on the new CodedEventsLogger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  CodedEventsLogger logger = new CodedEventsLogger();&lt;br /&gt;
  // Create an EventDetector object so that event detection functions could be used:&lt;br /&gt;
  EventDetector d = logger.monitorDetector(nodeDet);&lt;br /&gt;
  EventDetector dOcc = logger.monitorDetector(nodeDetOcc);&lt;br /&gt;
  EventDetector dDel = logger.monitorDetector(nodeDetDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Add the EventDetector to the propagator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  propagator.addEventDetector(d);&lt;br /&gt;
  propagator.addEventDetector(dOcc);&lt;br /&gt;
  propagator.addEventDetector(dDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Start the propagation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set the propagator:&lt;br /&gt;
  propagator.setEphemerisMode();&lt;br /&gt;
  propagator.resetInitialState(new SpacecraftState(orbit));&lt;br /&gt;
  // Propagate:&lt;br /&gt;
  propagator.propagate(date0, dateF);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Combination of boolean phenomena ===&lt;br /&gt;
Sometimes an event (a zero of a g function) can be seen as a begin (passing zero from positive to negative or invert) or a end ( other way ) of a phenomena. For example the eclipse event can be the begin (detected when g function goes from positive to negative) or the end (when g function goes from negative to positive) of an eclipse. (cf. [MIS_ORB_Home#HEclipseDetectorandGenericEclipseDetector Eclipse detector].)&lt;br /&gt;
&lt;br /&gt;
One can choose to create an event as a combination of these phenomena, for example a station visibility outside an interference period. In this case a user can create a detector as a combination of existing detectors.&lt;br /&gt;
&lt;br /&gt;
The user simply has to provide the following parameters :&lt;br /&gt;
#First detector and the way to use it (g is positive or negative during the phenomena to combine)&lt;br /&gt;
#Second detector and the way to use it &lt;br /&gt;
#How to combine the phenomenom : both are during phenomena (will be detected as the minimum of the two g function) or at least one (will be detected as the maximum of the two g function) is during phenomena &lt;br /&gt;
&lt;br /&gt;
Once a new detector have been created in this way, it is possible to combine it with another one and so on.&lt;br /&gt;
&lt;br /&gt;
For example the [MIS_SENSORS_Home#HCentralBodyMaskCircularFOVDetector CentralBodyMaskCircularFOVDetector] detects when a target is in a circular field of view and outside of an eclipse, that is translated by :&lt;br /&gt;
&lt;br /&gt;
* Outside of eclipse : when EllipsoidEclipseDetecor g function is positive &lt;br /&gt;
* Inside circular field of view : when CircularFieldOfView g function is positive&lt;br /&gt;
&lt;br /&gt;
So the following code example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// EclipseDetector&lt;br /&gt;
final EclipseDetector eed = new EclipseDetector(targetPVP, targetRadius, spheroEarth, 1., MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// CircularFOVDetector&lt;br /&gt;
final CircularFieldOfViewDetector cfvd = new CircularFieldOfViewDetector(targetPVP, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CombinedPhenomenaDetector cbmcfovd2 = new CombinedPhenomenaDetector(eed, true, cfvd, true, true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is equivalent to CentralBodyMaskCircularFOVDetector :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CentralBodyMaskCircularFOVDetector cbmcfovd = &lt;br /&gt;
new CentralBodyMaskCircularFOVDetector(targetPVP, targetRadius, spheroEarth, false, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
==== Interfaces events detection ====&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.13}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/CodingEventDetector.html CodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiEventDetector&lt;br /&gt;
|This interface represents an event finder in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
==== Classes containing the general functions to detect events ====&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;
| AbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/AbstractDetector.html AbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiAbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiAbstractDetector.html MultiAbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedEventDetector&lt;br /&gt;
|This class adapts Patrius event detectors to math EventHandler object.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/AdaptedEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMonoEventDetector&lt;br /&gt;
|This class adapts Patrius mono event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMonoEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMultiEventDetector&lt;br /&gt;
|This class adapts Patrius multi event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMultiEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CombinedPhenomenaDetector&lt;br /&gt;
|This class handles events representing the combination of two boolean phenomena.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/CombinedPhenomenaDetector.html CombinedPhenomenaDetector]&lt;br /&gt;
|-&lt;br /&gt;
| NthOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a certain occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| IntervalOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a interval occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurrenceDetector.html IntervalOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| ExtremaGenericDetector&lt;br /&gt;
|This class represents an event detector that detects the derivative cancellation of an underlying detector.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/propagation/events/ExtremaGenericDetector.html ExtremaGenericDetector]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Classes for the generation of lists of events and phenomena ====&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;
| CodedEvent&lt;br /&gt;
|This class implements coded events (a light and simple representation of events as generated by Patrius event detectors ).&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/CodedEvent.html CodedEvent]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/CodedEventsList.html CodedEventsList]&lt;br /&gt;
|-&lt;br /&gt;
| Phenomenon&lt;br /&gt;
|This class implements the notion of a phenomenon : a state defined by a starting event and an ending event.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/Phenomenon.html Phenomenon]&lt;br /&gt;
|-&lt;br /&gt;
| PhenomenaList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/PhenomenaList.html PhenomenaList]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/CodedEventsLogger.html CodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| GenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/GenericCodingEventDetector.html GenericCodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiGenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface in multi propagation case, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.13}}/fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.13_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.12_Events_detection:_Presentation&amp;diff=3615</id>
		<title>User Manual 4.12 Events detection: Presentation</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.12_Events_detection:_Presentation&amp;diff=3615"/>
		<updated>2023-12-19T16:20:10Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes :&lt;br /&gt;
&lt;br /&gt;
* in a mono satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions that extend  event detection mechanism.&lt;br /&gt;
* in a multi satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions, copied from the mono satellite mechanism, that extend Patrius&#039;s event detection mechanism for multi satellite propagation.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The following packages are related to events detections in mono and multi propagation context:&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.12}}/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.12}}/fr/cnes/sirius/patrius/math/ode/events/package-summary.html Package fr.cnes.sirius.patrius.math.ode.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/package-summary.html Package fr.cnes.sirius.patrius.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/multi/package-summary.html Package fr.cnes.sirius.patrius.propagation.events.multi]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as 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 architecture of the events detection for mono and multi satellite propagation.&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:EventsV3.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following diagram represents the mechanism used in the Patrius library in order to create the list of the events detected during the mono satellite propagation as well as the phenomena list :&lt;br /&gt;
&lt;br /&gt;
[[File:Events.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following classes are duplicated from mono satellite context in order to create a list of events detected : &lt;br /&gt;
* [{{JavaDoc4.12}}//fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.12}}//fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
* [{{JavaDoc4.12}}//fr/cnes/sirius/patrius/events/multi/MultiEventsLogger.html MultiEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.12}}//fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Event detection ===&lt;br /&gt;
&lt;br /&gt;
The events detection process can be used during mono or multi propagation propagation, when we need to know if some events occur and at what time (for instance when the satellite will be in eclipse, or if at a given date it will be visible or not from a ground station).&lt;br /&gt;
&lt;br /&gt;
In Patrius there is one class for every kind of event: the information related to an event is contained in this class, and it will be used by the mono satellite numerical or analytical propagator when extrapolating the orbit. The mechanism is similar for multi propagation.&lt;br /&gt;
&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are detected is the order in which they are added to the propagator.&lt;br /&gt;
&lt;br /&gt;
As of PATRIUS 4.5, detectors can optionally take into account signal propagation delay. Javadoc of each event detector indicates if signal propagation delay can be taken into account through a setter &amp;lt;code&amp;gt;setPropagationDelayType()&amp;lt;/code&amp;gt;. Delay type is of 2 types:&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.INSTANTANEOUS&amp;lt;/code&amp;gt;: signal propagation delay is not taken into account&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.LIGHT_SPEED&amp;lt;/code&amp;gt;: signal propagation delay is taken into account.&lt;br /&gt;
Signal propagation delay allows to detect events as it is exactly seen by a spacecraft, for instance a visibility between a satellite and a station.&lt;br /&gt;
All detectors involving a signal propagation and or sensors can take signal propagation delay into account (BetaAngleDetector, SensorVisibilityDetector, TargetInFieldOfViewDetector, etc.):&lt;br /&gt;
&lt;br /&gt;
By default signal propagation delay is not taken into account.&lt;br /&gt;
&lt;br /&gt;
A new detector class should implements  : &lt;br /&gt;
* [{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector interface] in case of [{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/Propagator.html mono satellite propagation] or [{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
* [{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector interface] in case of [{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Construction of a detector&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The action performed at event detection can be set by user at detector&#039;s construction. Several actions can be defined if several behavior are available (depending on state and/or on increasing/forward parameter). It is possible to specify at construction if the detector should be removed after event detection and thus not be detected any more. If a single action is available, a single boolean has to be provided by the user at construction. In the case where several actions are available, the same number of boolean has to be provided to determine if the detector has to be removed after event detection.&amp;lt;br&amp;gt;&lt;br /&gt;
Focusing on the &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt; for instance, two actions are possible at event detection :&lt;br /&gt;
&lt;br /&gt;
- action_at_ascending_node if an ascending node detection is done&amp;lt;br&amp;gt;&lt;br /&gt;
- action_at_descending_node if a descending node detection is performed&lt;br /&gt;
&lt;br /&gt;
If no actions are set, the user should be aware of the default implementation.&lt;br /&gt;
By default, event detectors are never removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of eventOccurred()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The returned action of the function eventOccurred could be set by user or defined by default.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function eventOccurred is common to all [{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector] classes (respectively [{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]) and its purpose is to handle an event and to choose what to do next ; this method is called when the integrator has accepted a step ending exactly on a sign change of the switching function, and it allows the user to choose which action will take place after the event (the simulation could be stopped, the propagator could reset its initial state or its initial derivative state ...).&lt;br /&gt;
Plus, this method is up to determine if the detector used has to be removed after the event detection : in the above example of &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt;, the action taking place after the event is set to action_at_raising_node in the case of an ascending node detection. If one has decided to remove the detector at such detection, the attribute shouldBeRemoved will be set to remove_at_ascending_node which is true by construction, the case of descending node is similar.&lt;br /&gt;
&lt;br /&gt;
Since the default implementation of eventOccurred could unfit the user needs in terms of propagation behaviour, it is recommended to check the content of the detector before using them and to change it if necessary by using a specific constructor which take as parameter the expected action(s).&lt;br /&gt;
&lt;br /&gt;
Note that the implementation of eventOccured must not contain any action. Even if the action does not impact the state vector, the action should be implemented in the resetState method.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of resetState() or resetStates()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If the event have an action, this action should be implemented in the resetState() method. In this case, the eventOccured() of the detector concerned should return a RESET_STATE action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Convergence threshold parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The convergence threshold represents the events detection precision; the following observations can help the user when choosing a value for this parameter:&lt;br /&gt;
&lt;br /&gt;
#if the convergence threshold increases, the execution time decreases (the precision becomes worst);&lt;br /&gt;
#if the convergence threshold is bigger than the max integration step, the events detection will fail.&lt;br /&gt;
&lt;br /&gt;
If the resetState(s) could modify others event detectors, the convergence threshold should be low in order to avoid any unpredictable behavior.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Max check interval parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The max check interval parameter represents the maximum interval in which the propagator checks for an event (i.e. for a sign change of the g switching function). When choosing this parameter, the user should keep in mind the following remarks:&lt;br /&gt;
&lt;br /&gt;
#if max check interval is smaller than the integration step, the execution time increases if the max check interval decreases (the events detection is more accurate);&lt;br /&gt;
#if max check interval is bigger than the max integration step, it will be replaced by the max integration step during the events detection process; in this case the max check interval is a useless parameter that will never be used by the propagator.&lt;br /&gt;
&lt;br /&gt;
In general, the user should always choose the max check interval value as a function of the integration step used during propagation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of the event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation start date, i.e if g() equal to zero, the event is processed. This case is extremely rare. Note that in some case however, due to numerical quality rounds-off, an event may not be detected at the propagation start date although it&#039;s theoritically supposed to occur. For example, starting propagation at periapsis with a periapsis detector may not detect periapsis since the g() function of PeriapsisDetector is based on position- velocity scalar product and due to rounds-off errors, its values may be around 1E-7 which is not exactly zero. &amp;lt;br&amp;gt;&lt;br /&gt;
Also, if at the propagation start date the g() function is not continuous but changes its sign (for example value-1 before event date, value 1 after), the event will also not be detected since the g() function value is not zero.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Ephemeris propagator event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one. Consequently, when propagating with a bounded propagator, if the last substep is larger than the real one then the real end date is exceeded, raising an exception. Therefore, in this case, it is recommended to &#039;&#039;&#039;propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the same date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are processed is the order in which they are added to the propagator. If the detected event stops the propagation, the other events occuring at the same date are not processed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the end date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation end date, the event is not processed.&lt;br /&gt;
&lt;br /&gt;
==== Available event detectors ====&lt;br /&gt;
Mono events detectors detect events applied on a specific state. These detectors can be used in mono or multi propagation case.&lt;br /&gt;
&lt;br /&gt;
The available mono events detectors are presented in specific pages: &lt;br /&gt;
&lt;br /&gt;
* [MIS_ORB_Home Orbit determination events]&lt;br /&gt;
* [MIS_SENSORS_Home Sensors events]&lt;br /&gt;
* [MIS_STASAT_Home Ground stations and satellites events]&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
It also exists multi events detectors applied on several states. These detectors can only be used in multi propagation case.&lt;br /&gt;
Notice that some detectors that implies several satellite coul be used in multi or mono satellite context ; ([{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/sensor/SatToSatMutualVisibilityDetector.html SatToSatMutualVisibilityDetector], [{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/ThreeBodiesAngleDetector.html ThreeBodiesAngleDetector] or [{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/ExtremaThreeBodiesAngleDetector.html ExtremaThreeBodiesAngleDetector])&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HMultiEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
The [{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector] is a detector that detects the nth occurrence of an underlying event detector.&amp;lt;br&amp;gt;&lt;br /&gt;
However the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every event of the underlying detector. As a result, the behaviour of this detector is the following:&lt;br /&gt;
* Before and after the nth occurrence, the eventOccurred() method returns &amp;lt;code&amp;gt;Action.CONTINUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
* At the nth occurrence, the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method returns the user-provided action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Warning&#039;&#039;&#039;&#039;&#039;: the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every occurrence of the underlying detector, not only at nth occurrence. Hence, overloading this detector should be performed carefully: in the overloaded &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method, the check &amp;lt;code&amp;gt;getCurrentOccurence() == getOccurence()&amp;lt;/code&amp;gt; should be performed first to ensure we are at nth occurrence before calling &amp;lt;code&amp;gt;super.eventOccurred()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== IntervalOccurenceDetector ====&lt;br /&gt;
This [{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurenceDetector.html IntervalOccurenceDetector ] is able for any EventDetector. It detects the &amp;lt;math&amp;gt;n^{th}&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;m^{th}&amp;lt;/math&amp;gt; event occurences by step of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; occurences. &lt;br /&gt;
Otherwise, if j event occurence, the &amp;lt;code&amp;gt;IntervalOccurenceDetector&amp;lt;/code&amp;gt; detects events as : &lt;br /&gt;
* &amp;lt;math&amp;gt;(j - n) % p = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n &amp;lt;= j &amp;lt;= m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The g switching function is the function of the event to detect.&lt;br /&gt;
&lt;br /&gt;
==== ExtremaGenericDetector ====&lt;br /&gt;
&lt;br /&gt;
This class represents an event detector that detects the derivative cancellation of an underlying detector. Using this detector recursively will allow to detect nth order derivative.&lt;br /&gt;
&lt;br /&gt;
The g switching function cancels for any extrema of the g function of the underlying detector.&lt;br /&gt;
Min, max or both at the same time.&lt;br /&gt;
&lt;br /&gt;
==== Mono Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
When a numerical propagation is performed, the event detection is done at the math level since the integration is realized by one of the numerical integrators. However, the event detectors are instanciated by the user at the Patrius level. Hence the necessity of an adapter to wrap a Patrius event detector object into a math event handler object whose interfaces provide basically the same kind of services. Once the event detectors are given to the numerical propagator, they are transformed into event handlers in order to give them to the math numerical integrator.&amp;lt;br&amp;gt;&lt;br /&gt;
The numerical integrator associates each event with another object which represents its state during the integration. At the end of each step, the method acceptStep() is systematically called and performs the event detection thanks to an interpolator, inside the current step. Thus the state of each event is updated. If an event is detected therefore the integration is either stopped or continued with or without state or derivative state resetting. It is also possible to remove the detector after the first event detection and the propagation is continued. An event is represented by a function, the function &amp;quot;g()&amp;quot;: the event occurs when the function sign changes and NOT when this function equals to zero. To find this root, in addition to the interpolator, a solver is used. By default, this solver is the Brent solver. The exception being at the beginning of the propagation where events are detected when the g() function equals exactly zero.&lt;br /&gt;
&lt;br /&gt;
===== Analytical propagator =====&lt;br /&gt;
&lt;br /&gt;
When an analytical propagation is performed, the event detection is done at the Patrius level directly. The process is basically the same than its math counterpart: the detectors are given to the propagator and associated to their states. The Patrius propagator has a method acceptStep() which is similar to the one of the math package.&lt;br /&gt;
&lt;br /&gt;
===== Ephemeris propagator =====&lt;br /&gt;
&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one which could be knotty when it comes to propagate with a bounded propagator. Indeed, if the last substep is larger than the real one then the real end date is exceeded. If the end date is equal to the ephemeris max date, an exception is raised when the interpolator sets the current date to a date exceeding the ephemeris max date. Therefore, in this case, &#039;&#039;&#039;it is recommended to propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Multi Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
The event detector process for multi satellite numerical propagation is equivalent to the process performed with single satellite numerical propagation. The multi event detection is wrapped into a math event handler object. The detector could be applied on a single satellite or on several satellites.&lt;br /&gt;
&lt;br /&gt;
=== Coded events and phenomena ===&lt;br /&gt;
==== Mono propagation ====&lt;br /&gt;
===== The coded event =====&lt;br /&gt;
&lt;br /&gt;
Patrius does detect events. This means :&lt;br /&gt;
&lt;br /&gt;
* Patrius triggers a method call on the corresponding EventDetector when the event occurs.&lt;br /&gt;
* Patrius logs the SpacecraftState and g function slope sign for the occuring event (through the EventsLogger).&lt;br /&gt;
&lt;br /&gt;
But this mechanism alone doesn&#039;t provide a programmatic representation for an &amp;quot;event&amp;quot;, which may be processed after the propagation.&lt;br /&gt;
&lt;br /&gt;
A new way of handling events as individual instances was thus designed : the &amp;quot;atomic event&amp;quot; or &amp;quot;coded event&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;coded event&amp;quot; has the following attributes :&lt;br /&gt;
&lt;br /&gt;
* an event &amp;quot;code&amp;quot; : a String identifying the category of the event, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* an event &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* an AbsoluteDate : the date at which the event occurred.&lt;br /&gt;
* a boolean, true when the event represents a &amp;quot;starting&amp;quot; event, or false when it represents an &amp;quot;ending&amp;quot; event (relative to a phenomenon, see below).&lt;br /&gt;
&lt;br /&gt;
The code and comment formats are free, they depend on the CodingEventDetector implementation (see below).&lt;br /&gt;
&lt;br /&gt;
A CodedEvent is supposed to be built by the CodedEventsLogger (see below).&lt;br /&gt;
&lt;br /&gt;
Moreover, when one of the boundaries of the phenomenon is ill-defined (e.g. unknown due to computational limits), it is an instance of CodedEvent, with the code &amp;quot;UNDEFINED_EVENT&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== The CodingEventDetector and MultiCodingEventDetector =====&lt;br /&gt;
&lt;br /&gt;
The CodingEventDetector (or MultiCodingEventDetector in MultiPropagator case) is an extension of the EventDetector type(respectively MultiEventDetector). A CodingEventDetector (or MultiCodingEventDetector) has the following requirements :&lt;br /&gt;
&lt;br /&gt;
* Providing a CodedEvent builder method, that creates a CodedEvent instance appropriate for the event (this is how the code and comment are determined).&lt;br /&gt;
* Providing a Phenomenon code if a Phenomenon makes sense in the context of the event, otherwise return null (see below).&lt;br /&gt;
* Providing a boolean telling which sign of the g() method means the Phenomenon is active (see below).&lt;br /&gt;
&lt;br /&gt;
===== The phenomenon =====&lt;br /&gt;
&lt;br /&gt;
The EventDetector provides a g() method whose sign change triggers an event. Sometimes the g() method can also be seen as conveying a &amp;quot;state&amp;quot; i.e. when g() is positive (resp. negative), a &amp;quot;phenomenon&amp;quot; is going on.&lt;br /&gt;
The clearest example would be the EclipseDetector :&lt;br /&gt;
&lt;br /&gt;
* g() going from positive to negative means that the spacecraft has entered the eclipse zone.&lt;br /&gt;
* g() going from negative to positive means that the spacecraft has exited the eclipse zone.&lt;br /&gt;
&lt;br /&gt;
The associated phenomenon would then be called &amp;quot;inside the eclipse zone&amp;quot;, bounded by the starting event &amp;quot;enter eclipse zone&amp;quot; and the ending event &amp;quot;exit eclipse zone&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This library provides a &amp;quot;phenomenon&amp;quot; abstraction, as a lightweight representation.&lt;br /&gt;
&lt;br /&gt;
A Phenomenon instance is an immutable object with the following attributes :&lt;br /&gt;
&lt;br /&gt;
* a phenomenon &amp;quot;code&amp;quot; : a String identifying the category of the phenomenon, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* a phenomenon &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* two &amp;quot;coded event&amp;quot; instances : the atomic events that represent the start and the end of the phenomenon.&lt;br /&gt;
&lt;br /&gt;
Also :&lt;br /&gt;
* it tells whether the start and end are &amp;quot;well-defined&amp;quot; : a well-defined boundary has a real event backing it. A not well-defined boundary is a boundary because of computational limits : it happens when, during a propagation, the ending event occurs, but the starting event did not (or, the opposite) because it was outside the boundaries of the propagation. In this case, an &amp;quot;UNDEFINED_EVENT&amp;quot; is given as the missing boundary (see above).&lt;br /&gt;
&lt;br /&gt;
A Phenomenon is built by the CodedEventsLogger, when the CodingEventDetector provides a non-null Phenomenon string code. The existence of this code proves the Phenomenon makes senses in the context of the CodingEventDetector. For instance :&lt;br /&gt;
&lt;br /&gt;
* for a &amp;quot;CodingEclipseDetector&amp;quot; built upon the EclipseDetector, a Phenomenon has meaning (the Phenomenon being &amp;quot;inside the eclipse&amp;quot;).&lt;br /&gt;
* for a &amp;quot;CodingApsideDetector&amp;quot; built upen the ApsideDetector, a Phenomenon has no meaning, since the events are : &amp;quot;the spacecraft is at the periapsis&amp;quot; and &amp;quot;the spacecraft is at the apoapsis&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Multi propagation ====&lt;br /&gt;
The same process exists. The corresponding classes are localized in the Patrius library.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting up a CodedEventsLogger or a MultiCodedEventsLogger ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent and Phenomenon instances are not meant to be produced by the CodingEventDetectors (or directly MultiCodedEventsLogger in MultiPropagator case) (but it could be possible if needed).&lt;br /&gt;
&lt;br /&gt;
Instead, the (Multi)CodedEventsLogger was created for this purpose.&lt;br /&gt;
&lt;br /&gt;
At first glance, a (Multi)CodedEventsLogger instance is very similar to the (Multi)EventsLogger.&lt;br /&gt;
The main difference is that the (Multi)EventsLogger instances have no inner representation of events, while the (Multi)CodedEventsLogger produces CodedEvent and Phenomenon lists.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how one uses the (Multi)CodedEventsLogger :&lt;br /&gt;
&lt;br /&gt;
* create a (Multi)CodedEventsLogger instance.&lt;br /&gt;
* create at least one (Multi)CodingEventProvider instance.&lt;br /&gt;
* call the &amp;lt;code&amp;gt;monitorDetector()&amp;lt;/code&amp;gt; method on the (Multi)CodedEventsLogger : it produces a &amp;quot;wrapper&amp;quot; of the (Multi)CodingEventProvider exposed as a regular EventProvider.&lt;br /&gt;
* pass this &amp;quot;wrapper&amp;quot; to a propagator (any kind works : those who do compute a propagation and those who replay an ephemeris).&lt;br /&gt;
* run the propagator.&lt;br /&gt;
&lt;br /&gt;
While the propagator runs, the &amp;quot;wrapper&amp;quot; calls both the (Multi)CodingEventProvider instance and the (Multi)CodedEventsLogger on each event. The (Multi)CodedEventsLogger instance uses the (Multi)CodingEventProvider to build and store all CodedEvent instances during the propagation.&lt;br /&gt;
&lt;br /&gt;
==== Getting the full coded events list ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;getCodedEventsList()&amp;lt;/code&amp;gt;.&lt;br /&gt;
It provides a list of all CodedEvents (for all the CodingEventDetectors passed to the propagator, without distinction).&lt;br /&gt;
&lt;br /&gt;
==== Getting the events list per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildCodedEventListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a CodedEventsList as value, this list only containing the events generated from the key.&amp;lt;br&amp;gt;&lt;br /&gt;
It is, therfore, the same data as the full events&#039; list, but rearranged per CodingEventProvider instance.&lt;br /&gt;
&lt;br /&gt;
==== Getting the phenomena per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildPhenomenaListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a PhenomenaList as value, this list only containing the Phenomenon instances generated from the key. The(Multi) CodingEventProvider instance provides the Phenomenon code.&lt;br /&gt;
&lt;br /&gt;
The (Multi)CodedEventsLogger only uses the (Multi)CodingEventProvider instances that provide a non-null Phenomenon code (null indicates that a Phenomenon has no meaning for this detector).&lt;br /&gt;
&lt;br /&gt;
==== N-th occurrence of a coded event, or a delayed event ====&lt;br /&gt;
&lt;br /&gt;
There are two ways to generate the n-th occurrence of an event or a delayed coded event from a detected event: the first one is using the post-processing classes, and the second one is to configure the CodingEventDetector in order to create the delayed or filtered coded events during the propagation (in addition to the &amp;quot;standard&amp;quot; coded events).&lt;br /&gt;
While the former can only be done after the propagation, the latter has to be set before the propagation and is possible thanks to the following methods in the class CodingEventDetector:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buildCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the standard CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildDelayedCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the delayed CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildOccurrenceCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the n-th occurrence CodedEvent (n will be a parameter chosen by the user)&lt;br /&gt;
&lt;br /&gt;
In order to use this feature, the delay value and/or the occurrence number must be given as input parameters of the constructor of the class implementing the CodingEventDetector class (for instance GenericCodingEventDetector). The CodedEventsLogger will then be able to read these parameters and handle the generation of standard and not-standard coded events.&lt;br /&gt;
&lt;br /&gt;
Note, in the GenericCodingEventDetector constructor (EventDetector, String, String, boolean, String, double, int), if both parameters delayIn and occurrenceIn are other than 0, the event is saved as a delayed event, not a &amp;quot;Nth occurence of&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== When to use Coded events and phenomena ===&lt;br /&gt;
* To build easier time lines of events&lt;br /&gt;
* To manipulate easier phenomena (for example between &amp;quot;starting&amp;quot; and &amp;quot;ending&amp;quot; events) and associate to them specific computations (for example the evolution of the illumination during an eclipse)&lt;br /&gt;
* To apply some [MIS_POSTP_Home post-processing filters]&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Using available events detectors ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
Example of propagation stopping at 3rd detected node with event detector overloading:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Initialization&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2003, 1, 1, TimeScalesFactory.getTAI());&lt;br /&gt;
final Orbit orbit = new KeplerianOrbit(7000000, 0.01, 0.1, 0.2, 0.3, 0.4, PositionAngle.TRUE, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
&lt;br /&gt;
// Node detector&lt;br /&gt;
final EventDetector nodeDetector = new NodeDetector(orbit, FramesFactory.getGCRF(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
// Stop at 3rd detected node&lt;br /&gt;
final NthOccurrenceDetector nthOccurrenceDetector = new NthOccurrenceDetector(nodeDetector, 3, Action.STOP) {&lt;br /&gt;
    @Override&lt;br /&gt;
    public Action eventOccurred(SpacecraftState s, boolean increasing, boolean forward) throws PatriusException {&lt;br /&gt;
        super.eventOccurred(s, increasing, forward);&lt;br /&gt;
        if (getCurrentOccurence() == getOccurence()) {&lt;br /&gt;
            return Action.STOP;&lt;br /&gt;
        } else {&lt;br /&gt;
            return Action.CONTINUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Propagation&lt;br /&gt;
final KeplerianPropagator propagator = new KeplerianPropagator(orbit);&lt;br /&gt;
propagator.addEventDetector(nthOccurrenceDetector);&lt;br /&gt;
propagator.propagate(orbit.getDate().shiftedBy(86400.));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generating coded events and phenomena ===&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent instances and Phenomenon instances are meant to be produced using :&amp;lt;br&amp;gt;&lt;br /&gt;
- CodingEventDetector implementations that provide information about events and phenomena,&amp;lt;br&amp;gt;&lt;br /&gt;
- a CodingEventsLogger, that uses the CodingEventDetector instances to build the events and phenomena.&lt;br /&gt;
&lt;br /&gt;
For example, if we want to create a list of CodedEvent objects using a detector of nodes (ascending and descending orbital nodes):&lt;br /&gt;
&lt;br /&gt;
1. Create a new EventDetector (in this case a NodeDetector):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set up the node detector:&lt;br /&gt;
  AbsoluteDate date = new AbsoluteDate(&amp;quot;2000-01-01T12:00:00Z&amp;quot;, TimeScalesFactory.getTT());&lt;br /&gt;
  AbsoluteDate dateF = date.shiftedBy(2* period);&lt;br /&gt;
  Orbit orbit = new KeplerianOrbit(7e6, 0, 0.2, 0, 0, 0.2, PositionAngle.MEAN, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
  NodeDetector node = new NodeDetector(orbit, FramesFactory.getEME2000(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Create a new generic coding event detector:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // standard event&lt;br /&gt;
  GenericCodingEventDetector nodeDet =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;);&lt;br /&gt;
  // third occurence of event&lt;br /&gt;
  GenericCodingEventDetector nodeDetOcc =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 0., 3);&lt;br /&gt;
  // delayed event (10 seconds here)&lt;br /&gt;
  GenericCodingEventDetector nodeDetDel =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 10., 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Create a new CodedEventsLogger and use the &amp;lt;code&amp;gt; monitorDetector &amp;lt;/code&amp;gt; function on the new CodedEventsLogger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  CodedEventsLogger logger = new CodedEventsLogger();&lt;br /&gt;
  // Create an EventDetector object so that event detection functions could be used:&lt;br /&gt;
  EventDetector d = logger.monitorDetector(nodeDet);&lt;br /&gt;
  EventDetector dOcc = logger.monitorDetector(nodeDetOcc);&lt;br /&gt;
  EventDetector dDel = logger.monitorDetector(nodeDetDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Add the EventDetector to the propagator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  propagator.addEventDetector(d);&lt;br /&gt;
  propagator.addEventDetector(dOcc);&lt;br /&gt;
  propagator.addEventDetector(dDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Start the propagation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set the propagator:&lt;br /&gt;
  propagator.setEphemerisMode();&lt;br /&gt;
  propagator.resetInitialState(new SpacecraftState(orbit));&lt;br /&gt;
  // Propagate:&lt;br /&gt;
  propagator.propagate(date0, dateF);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Combination of boolean phenomena ===&lt;br /&gt;
Sometimes an event (a zero of a g function) can be seen as a begin (passing zero from positive to negative or invert) or a end ( other way ) of a phenomena. For example the eclipse event can be the begin (detected when g function goes from positive to negative) or the end (when g function goes from negative to positive) of an eclipse. (cf. [MIS_ORB_Home#HEclipseDetectorandGenericEclipseDetector Eclipse detector].)&lt;br /&gt;
&lt;br /&gt;
One can choose to create an event as a combination of these phenomena, for example a station visibility outside an interference period. In this case a user can create a detector as a combination of existing detectors.&lt;br /&gt;
&lt;br /&gt;
The user simply has to provide the following parameters :&lt;br /&gt;
#First detector and the way to use it (g is positive or negative during the phenomena to combine)&lt;br /&gt;
#Second detector and the way to use it &lt;br /&gt;
#How to combine the phenomenom : both are during phenomena (will be detected as the minimum of the two g function) or at least one (will be detected as the maximum of the two g function) is during phenomena &lt;br /&gt;
&lt;br /&gt;
Once a new detector have been created in this way, it is possible to combine it with another one and so on.&lt;br /&gt;
&lt;br /&gt;
For example the [MIS_SENSORS_Home#HCentralBodyMaskCircularFOVDetector CentralBodyMaskCircularFOVDetector] detects when a target is in a circular field of view and outside of an eclipse, that is translated by :&lt;br /&gt;
&lt;br /&gt;
* Outside of eclipse : when EllipsoidEclipseDetecor g function is positive &lt;br /&gt;
* Inside circular field of view : when CircularFieldOfView g function is positive&lt;br /&gt;
&lt;br /&gt;
So the following code example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// EclipseDetector&lt;br /&gt;
final EclipseDetector eed = new EclipseDetector(targetPVP, targetRadius, spheroEarth, 1., MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// CircularFOVDetector&lt;br /&gt;
final CircularFieldOfViewDetector cfvd = new CircularFieldOfViewDetector(targetPVP, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CombinedPhenomenaDetector cbmcfovd2 = new CombinedPhenomenaDetector(eed, true, cfvd, true, true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is equivalent to CentralBodyMaskCircularFOVDetector :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CentralBodyMaskCircularFOVDetector cbmcfovd = &lt;br /&gt;
new CentralBodyMaskCircularFOVDetector(targetPVP, targetRadius, spheroEarth, false, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
==== Interfaces events detection ====&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.12}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/CodingEventDetector.html CodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiEventDetector&lt;br /&gt;
|This interface represents an event finder in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
==== Classes containing the general functions to detect events ====&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;
| AbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/AbstractDetector.html AbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiAbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiAbstractDetector.html MultiAbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedEventDetector&lt;br /&gt;
|This class adapts Patrius event detectors to math EventHandler object.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/AdaptedEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMonoEventDetector&lt;br /&gt;
|This class adapts Patrius mono event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMonoEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMultiEventDetector&lt;br /&gt;
|This class adapts Patrius multi event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMultiEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CombinedPhenomenaDetector&lt;br /&gt;
|This class handles events representing the combination of two boolean phenomena.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/CombinedPhenomenaDetector.html CombinedPhenomenaDetector]&lt;br /&gt;
|-&lt;br /&gt;
| NthOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a certain occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| IntervalOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a interval occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurrenceDetector.html IntervalOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| ExtremaGenericDetector&lt;br /&gt;
|This class represents an event detector that detects the derivative cancellation of an underlying detector.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/propagation/events/ExtremaGenericDetector.html ExtremaGenericDetector]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Classes for the generation of lists of events and phenomena ====&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;
| CodedEvent&lt;br /&gt;
|This class implements coded events (a light and simple representation of events as generated by Patrius event detectors ).&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/CodedEvent.html CodedEvent]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/CodedEventsList.html CodedEventsList]&lt;br /&gt;
|-&lt;br /&gt;
| Phenomenon&lt;br /&gt;
|This class implements the notion of a phenomenon : a state defined by a starting event and an ending event.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/Phenomenon.html Phenomenon]&lt;br /&gt;
|-&lt;br /&gt;
| PhenomenaList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/PhenomenaList.html PhenomenaList]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/CodedEventsLogger.html CodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| GenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/GenericCodingEventDetector.html GenericCodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiGenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface in multi propagation case, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.12}}/fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.12_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.11_Events_detection:_Presentation&amp;diff=3614</id>
		<title>User Manual 4.11 Events detection: Presentation</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.11_Events_detection:_Presentation&amp;diff=3614"/>
		<updated>2023-12-19T16:19:56Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes :&lt;br /&gt;
&lt;br /&gt;
* in a mono satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions that extend  event detection mechanism.&lt;br /&gt;
* in a multi satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions, copied from the mono satellite mechanism, that extend Patrius&#039;s event detection mechanism for multi satellite propagation.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The following packages are related to events detections in mono and multi propagation context:&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.11}}/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.11}}/fr/cnes/sirius/patrius/math/ode/events/package-summary.html Package fr.cnes.sirius.patrius.math.ode.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/package-summary.html Package fr.cnes.sirius.patrius.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/multi/package-summary.html Package fr.cnes.sirius.patrius.propagation.events.multi]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as 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 architecture of the events detection for mono and multi satellite propagation.&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:EventsV3.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following diagram represents the mechanism used in the Patrius library in order to create the list of the events detected during the mono satellite propagation as well as the phenomena list :&lt;br /&gt;
&lt;br /&gt;
[[File:Events.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following classes are duplicated from mono satellite context in order to create a list of events detected : &lt;br /&gt;
* [{{JavaDoc4.11}}//fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.11}}//fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
* [{{JavaDoc4.11}}//fr/cnes/sirius/patrius/events/multi/MultiEventsLogger.html MultiEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.11}}//fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Event detection ===&lt;br /&gt;
&lt;br /&gt;
The events detection process can be used during mono or multi propagation propagation, when we need to know if some events occur and at what time (for instance when the satellite will be in eclipse, or if at a given date it will be visible or not from a ground station).&lt;br /&gt;
&lt;br /&gt;
In Patrius there is one class for every kind of event: the information related to an event is contained in this class, and it will be used by the mono satellite numerical or analytical propagator when extrapolating the orbit. The mechanism is similar for multi propagation.&lt;br /&gt;
&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are detected is the order in which they are added to the propagator.&lt;br /&gt;
&lt;br /&gt;
As of PATRIUS 4.5, detectors can optionally take into account signal propagation delay. Javadoc of each event detector indicates if signal propagation delay can be taken into account through a setter &amp;lt;code&amp;gt;setPropagationDelayType()&amp;lt;/code&amp;gt;. Delay type is of 2 types:&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.INSTANTANEOUS&amp;lt;/code&amp;gt;: signal propagation delay is not taken into account&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.LIGHT_SPEED&amp;lt;/code&amp;gt;: signal propagation delay is taken into account.&lt;br /&gt;
Signal propagation delay allows to detect events as it is exactly seen by a spacecraft, for instance a visibility between a satellite and a station.&lt;br /&gt;
All detectors involving a signal propagation and or sensors can take signal propagation delay into account (BetaAngleDetector, SensorVisibilityDetector, TargetInFieldOfViewDetector, etc.):&lt;br /&gt;
&lt;br /&gt;
By default signal propagation delay is not taken into account.&lt;br /&gt;
&lt;br /&gt;
A new detector class should implements  : &lt;br /&gt;
* [{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector interface] in case of [{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/Propagator.html mono satellite propagation] or [{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
* [{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector interface] in case of [{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Construction of a detector&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The action performed at event detection can be set by user at detector&#039;s construction. Several actions can be defined if several behavior are available (depending on state and/or on increasing/forward parameter). It is possible to specify at construction if the detector should be removed after event detection and thus not be detected any more. If a single action is available, a single boolean has to be provided by the user at construction. In the case where several actions are available, the same number of boolean has to be provided to determine if the detector has to be removed after event detection.&amp;lt;br&amp;gt;&lt;br /&gt;
Focusing on the &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt; for instance, two actions are possible at event detection :&lt;br /&gt;
&lt;br /&gt;
- action_at_ascending_node if an ascending node detection is done&amp;lt;br&amp;gt;&lt;br /&gt;
- action_at_descending_node if a descending node detection is performed&lt;br /&gt;
&lt;br /&gt;
If no actions are set, the user should be aware of the default implementation.&lt;br /&gt;
By default, event detectors are never removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of eventOccurred()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The returned action of the function eventOccurred could be set by user or defined by default.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function eventOccurred is common to all [{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector] classes (respectively [{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]) and its purpose is to handle an event and to choose what to do next ; this method is called when the integrator has accepted a step ending exactly on a sign change of the switching function, and it allows the user to choose which action will take place after the event (the simulation could be stopped, the propagator could reset its initial state or its initial derivative state ...).&lt;br /&gt;
Plus, this method is up to determine if the detector used has to be removed after the event detection : in the above example of &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt;, the action taking place after the event is set to action_at_raising_node in the case of an ascending node detection. If one has decided to remove the detector at such detection, the attribute shouldBeRemoved will be set to remove_at_ascending_node which is true by construction, the case of descending node is similar.&lt;br /&gt;
&lt;br /&gt;
Since the default implementation of eventOccurred could unfit the user needs in terms of propagation behaviour, it is recommended to check the content of the detector before using them and to change it if necessary by using a specific constructor which take as parameter the expected action(s).&lt;br /&gt;
&lt;br /&gt;
Note that the implementation of eventOccured must not contain any action. Even if the action does not impact the state vector, the action should be implemented in the resetState method.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of resetState() or resetStates()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If the event have an action, this action should be implemented in the resetState() method. In this case, the eventOccured() of the detector concerned should return a RESET_STATE action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Convergence threshold parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The convergence threshold represents the events detection precision; the following observations can help the user when choosing a value for this parameter:&lt;br /&gt;
&lt;br /&gt;
#if the convergence threshold increases, the execution time decreases (the precision becomes worst);&lt;br /&gt;
#if the convergence threshold is bigger than the max integration step, the events detection will fail.&lt;br /&gt;
&lt;br /&gt;
If the resetState(s) could modify others event detectors, the convergence threshold should be low in order to avoid any unpredictable behavior.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Max check interval parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The max check interval parameter represents the maximum interval in which the propagator checks for an event (i.e. for a sign change of the g switching function). When choosing this parameter, the user should keep in mind the following remarks:&lt;br /&gt;
&lt;br /&gt;
#if max check interval is smaller than the integration step, the execution time increases if the max check interval decreases (the events detection is more accurate);&lt;br /&gt;
#if max check interval is bigger than the max integration step, it will be replaced by the max integration step during the events detection process; in this case the max check interval is a useless parameter that will never be used by the propagator.&lt;br /&gt;
&lt;br /&gt;
In general, the user should always choose the max check interval value as a function of the integration step used during propagation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of the event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation start date, i.e if g() equal to zero, the event is processed. This case is extremely rare. Note that in some case however, due to numerical quality rounds-off, an event may not be detected at the propagation start date although it&#039;s theoritically supposed to occur. For example, starting propagation at periapsis with a periapsis detector may not detect periapsis since the g() function of PeriapsisDetector is based on position- velocity scalar product and due to rounds-off errors, its values may be around 1E-7 which is not exactly zero. &amp;lt;br&amp;gt;&lt;br /&gt;
Also, if at the propagation start date the g() function is not continuous but changes its sign (for example value-1 before event date, value 1 after), the event will also not be detected since the g() function value is not zero.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Ephemeris propagator event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one. Consequently, when propagating with a bounded propagator, if the last substep is larger than the real one then the real end date is exceeded, raising an exception. Therefore, in this case, it is recommended to &#039;&#039;&#039;propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the same date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are processed is the order in which they are added to the propagator. If the detected event stops the propagation, the other events occuring at the same date are not processed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the end date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation end date, the event is not processed.&lt;br /&gt;
&lt;br /&gt;
==== Available event detectors ====&lt;br /&gt;
Mono events detectors detect events applied on a specific state. These detectors can be used in mono or multi propagation case.&lt;br /&gt;
&lt;br /&gt;
The available mono events detectors are presented in specific pages: &lt;br /&gt;
&lt;br /&gt;
* [MIS_ORB_Home Orbit determination events]&lt;br /&gt;
* [MIS_SENSORS_Home Sensors events]&lt;br /&gt;
* [MIS_STASAT_Home Ground stations and satellites events]&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
It also exists multi events detectors applied on several states. These detectors can only be used in multi propagation case.&lt;br /&gt;
Notice that some detectors that implies several satellite coul be used in multi or mono satellite context ; ([{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/sensor/SatToSatMutualVisibilityDetector.html SatToSatMutualVisibilityDetector], [{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/ThreeBodiesAngleDetector.html ThreeBodiesAngleDetector] or [{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/ExtremaThreeBodiesAngleDetector.html ExtremaThreeBodiesAngleDetector])&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HMultiEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
The [{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector] is a detector that detects the nth occurrence of an underlying event detector.&amp;lt;br&amp;gt;&lt;br /&gt;
However the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every event of the underlying detector. As a result, the behaviour of this detector is the following:&lt;br /&gt;
* Before and after the nth occurrence, the eventOccurred() method returns &amp;lt;code&amp;gt;Action.CONTINUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
* At the nth occurrence, the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method returns the user-provided action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Warning&#039;&#039;&#039;&#039;&#039;: the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every occurrence of the underlying detector, not only at nth occurrence. Hence, overloading this detector should be performed carefully: in the overloaded &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method, the check &amp;lt;code&amp;gt;getCurrentOccurence() == getOccurence()&amp;lt;/code&amp;gt; should be performed first to ensure we are at nth occurrence before calling &amp;lt;code&amp;gt;super.eventOccurred()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== IntervalOccurenceDetector ====&lt;br /&gt;
This [{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurenceDetector.html IntervalOccurenceDetector ] is able for any EventDetector. It detects the &amp;lt;math&amp;gt;n^{th}&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;m^{th}&amp;lt;/math&amp;gt; event occurences by step of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; occurences. &lt;br /&gt;
Otherwise, if j event occurence, the &amp;lt;code&amp;gt;IntervalOccurenceDetector&amp;lt;/code&amp;gt; detects events as : &lt;br /&gt;
* &amp;lt;math&amp;gt;(j - n) % p = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n &amp;lt;= j &amp;lt;= m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The g switching function is the function of the event to detect.&lt;br /&gt;
&lt;br /&gt;
==== ExtremaGenericDetector ====&lt;br /&gt;
&lt;br /&gt;
This class represents an event detector that detects the derivative cancellation of an underlying detector. Using this detector recursively will allow to detect nth order derivative.&lt;br /&gt;
&lt;br /&gt;
The g switching function cancels for any extrema of the g function of the underlying detector.&lt;br /&gt;
Min, max or both at the same time.&lt;br /&gt;
&lt;br /&gt;
==== Mono Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
When a numerical propagation is performed, the event detection is done at the math level since the integration is realized by one of the numerical integrators. However, the event detectors are instanciated by the user at the Patrius level. Hence the necessity of an adapter to wrap a Patrius event detector object into a math event handler object whose interfaces provide basically the same kind of services. Once the event detectors are given to the numerical propagator, they are transformed into event handlers in order to give them to the math numerical integrator.&amp;lt;br&amp;gt;&lt;br /&gt;
The numerical integrator associates each event with another object which represents its state during the integration. At the end of each step, the method acceptStep() is systematically called and performs the event detection thanks to an interpolator, inside the current step. Thus the state of each event is updated. If an event is detected therefore the integration is either stopped or continued with or without state or derivative state resetting. It is also possible to remove the detector after the first event detection and the propagation is continued. An event is represented by a function, the function &amp;quot;g()&amp;quot;: the event occurs when the function sign changes and NOT when this function equals to zero. To find this root, in addition to the interpolator, a solver is used. By default, this solver is the Brent solver. The exception being at the beginning of the propagation where events are detected when the g() function equals exactly zero.&lt;br /&gt;
&lt;br /&gt;
===== Analytical propagator =====&lt;br /&gt;
&lt;br /&gt;
When an analytical propagation is performed, the event detection is done at the Patrius level directly. The process is basically the same than its math counterpart: the detectors are given to the propagator and associated to their states. The Patrius propagator has a method acceptStep() which is similar to the one of the math package.&lt;br /&gt;
&lt;br /&gt;
===== Ephemeris propagator =====&lt;br /&gt;
&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one which could be knotty when it comes to propagate with a bounded propagator. Indeed, if the last substep is larger than the real one then the real end date is exceeded. If the end date is equal to the ephemeris max date, an exception is raised when the interpolator sets the current date to a date exceeding the ephemeris max date. Therefore, in this case, &#039;&#039;&#039;it is recommended to propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Multi Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
The event detector process for multi satellite numerical propagation is equivalent to the process performed with single satellite numerical propagation. The multi event detection is wrapped into a math event handler object. The detector could be applied on a single satellite or on several satellites.&lt;br /&gt;
&lt;br /&gt;
=== Coded events and phenomena ===&lt;br /&gt;
==== Mono propagation ====&lt;br /&gt;
===== The coded event =====&lt;br /&gt;
&lt;br /&gt;
Patrius does detect events. This means :&lt;br /&gt;
&lt;br /&gt;
* Patrius triggers a method call on the corresponding EventDetector when the event occurs.&lt;br /&gt;
* Patrius logs the SpacecraftState and g function slope sign for the occuring event (through the EventsLogger).&lt;br /&gt;
&lt;br /&gt;
But this mechanism alone doesn&#039;t provide a programmatic representation for an &amp;quot;event&amp;quot;, which may be processed after the propagation.&lt;br /&gt;
&lt;br /&gt;
A new way of handling events as individual instances was thus designed : the &amp;quot;atomic event&amp;quot; or &amp;quot;coded event&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;coded event&amp;quot; has the following attributes :&lt;br /&gt;
&lt;br /&gt;
* an event &amp;quot;code&amp;quot; : a String identifying the category of the event, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* an event &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* an AbsoluteDate : the date at which the event occurred.&lt;br /&gt;
* a boolean, true when the event represents a &amp;quot;starting&amp;quot; event, or false when it represents an &amp;quot;ending&amp;quot; event (relative to a phenomenon, see below).&lt;br /&gt;
&lt;br /&gt;
The code and comment formats are free, they depend on the CodingEventDetector implementation (see below).&lt;br /&gt;
&lt;br /&gt;
A CodedEvent is supposed to be built by the CodedEventsLogger (see below).&lt;br /&gt;
&lt;br /&gt;
Moreover, when one of the boundaries of the phenomenon is ill-defined (e.g. unknown due to computational limits), it is an instance of CodedEvent, with the code &amp;quot;UNDEFINED_EVENT&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== The CodingEventDetector and MultiCodingEventDetector =====&lt;br /&gt;
&lt;br /&gt;
The CodingEventDetector (or MultiCodingEventDetector in MultiPropagator case) is an extension of the EventDetector type(respectively MultiEventDetector). A CodingEventDetector (or MultiCodingEventDetector) has the following requirements :&lt;br /&gt;
&lt;br /&gt;
* Providing a CodedEvent builder method, that creates a CodedEvent instance appropriate for the event (this is how the code and comment are determined).&lt;br /&gt;
* Providing a Phenomenon code if a Phenomenon makes sense in the context of the event, otherwise return null (see below).&lt;br /&gt;
* Providing a boolean telling which sign of the g() method means the Phenomenon is active (see below).&lt;br /&gt;
&lt;br /&gt;
===== The phenomenon =====&lt;br /&gt;
&lt;br /&gt;
The EventDetector provides a g() method whose sign change triggers an event. Sometimes the g() method can also be seen as conveying a &amp;quot;state&amp;quot; i.e. when g() is positive (resp. negative), a &amp;quot;phenomenon&amp;quot; is going on.&lt;br /&gt;
The clearest example would be the EclipseDetector :&lt;br /&gt;
&lt;br /&gt;
* g() going from positive to negative means that the spacecraft has entered the eclipse zone.&lt;br /&gt;
* g() going from negative to positive means that the spacecraft has exited the eclipse zone.&lt;br /&gt;
&lt;br /&gt;
The associated phenomenon would then be called &amp;quot;inside the eclipse zone&amp;quot;, bounded by the starting event &amp;quot;enter eclipse zone&amp;quot; and the ending event &amp;quot;exit eclipse zone&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This library provides a &amp;quot;phenomenon&amp;quot; abstraction, as a lightweight representation.&lt;br /&gt;
&lt;br /&gt;
A Phenomenon instance is an immutable object with the following attributes :&lt;br /&gt;
&lt;br /&gt;
* a phenomenon &amp;quot;code&amp;quot; : a String identifying the category of the phenomenon, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* a phenomenon &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* two &amp;quot;coded event&amp;quot; instances : the atomic events that represent the start and the end of the phenomenon.&lt;br /&gt;
&lt;br /&gt;
Also :&lt;br /&gt;
* it tells whether the start and end are &amp;quot;well-defined&amp;quot; : a well-defined boundary has a real event backing it. A not well-defined boundary is a boundary because of computational limits : it happens when, during a propagation, the ending event occurs, but the starting event did not (or, the opposite) because it was outside the boundaries of the propagation. In this case, an &amp;quot;UNDEFINED_EVENT&amp;quot; is given as the missing boundary (see above).&lt;br /&gt;
&lt;br /&gt;
A Phenomenon is built by the CodedEventsLogger, when the CodingEventDetector provides a non-null Phenomenon string code. The existence of this code proves the Phenomenon makes senses in the context of the CodingEventDetector. For instance :&lt;br /&gt;
&lt;br /&gt;
* for a &amp;quot;CodingEclipseDetector&amp;quot; built upon the EclipseDetector, a Phenomenon has meaning (the Phenomenon being &amp;quot;inside the eclipse&amp;quot;).&lt;br /&gt;
* for a &amp;quot;CodingApsideDetector&amp;quot; built upen the ApsideDetector, a Phenomenon has no meaning, since the events are : &amp;quot;the spacecraft is at the periapsis&amp;quot; and &amp;quot;the spacecraft is at the apoapsis&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Multi propagation ====&lt;br /&gt;
The same process exists. The corresponding classes are localized in the Patrius library.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting up a CodedEventsLogger or a MultiCodedEventsLogger ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent and Phenomenon instances are not meant to be produced by the CodingEventDetectors (or directly MultiCodedEventsLogger in MultiPropagator case) (but it could be possible if needed).&lt;br /&gt;
&lt;br /&gt;
Instead, the (Multi)CodedEventsLogger was created for this purpose.&lt;br /&gt;
&lt;br /&gt;
At first glance, a (Multi)CodedEventsLogger instance is very similar to the (Multi)EventsLogger.&lt;br /&gt;
The main difference is that the (Multi)EventsLogger instances have no inner representation of events, while the (Multi)CodedEventsLogger produces CodedEvent and Phenomenon lists.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how one uses the (Multi)CodedEventsLogger :&lt;br /&gt;
&lt;br /&gt;
* create a (Multi)CodedEventsLogger instance.&lt;br /&gt;
* create at least one (Multi)CodingEventProvider instance.&lt;br /&gt;
* call the &amp;lt;code&amp;gt;monitorDetector()&amp;lt;/code&amp;gt; method on the (Multi)CodedEventsLogger : it produces a &amp;quot;wrapper&amp;quot; of the (Multi)CodingEventProvider exposed as a regular EventProvider.&lt;br /&gt;
* pass this &amp;quot;wrapper&amp;quot; to a propagator (any kind works : those who do compute a propagation and those who replay an ephemeris).&lt;br /&gt;
* run the propagator.&lt;br /&gt;
&lt;br /&gt;
While the propagator runs, the &amp;quot;wrapper&amp;quot; calls both the (Multi)CodingEventProvider instance and the (Multi)CodedEventsLogger on each event. The (Multi)CodedEventsLogger instance uses the (Multi)CodingEventProvider to build and store all CodedEvent instances during the propagation.&lt;br /&gt;
&lt;br /&gt;
==== Getting the full coded events list ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;getCodedEventsList()&amp;lt;/code&amp;gt;.&lt;br /&gt;
It provides a list of all CodedEvents (for all the CodingEventDetectors passed to the propagator, without distinction).&lt;br /&gt;
&lt;br /&gt;
==== Getting the events list per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildCodedEventListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a CodedEventsList as value, this list only containing the events generated from the key.&amp;lt;br&amp;gt;&lt;br /&gt;
It is, therfore, the same data as the full events&#039; list, but rearranged per CodingEventProvider instance.&lt;br /&gt;
&lt;br /&gt;
==== Getting the phenomena per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildPhenomenaListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a PhenomenaList as value, this list only containing the Phenomenon instances generated from the key. The(Multi) CodingEventProvider instance provides the Phenomenon code.&lt;br /&gt;
&lt;br /&gt;
The (Multi)CodedEventsLogger only uses the (Multi)CodingEventProvider instances that provide a non-null Phenomenon code (null indicates that a Phenomenon has no meaning for this detector).&lt;br /&gt;
&lt;br /&gt;
==== N-th occurrence of a coded event, or a delayed event ====&lt;br /&gt;
&lt;br /&gt;
There are two ways to generate the n-th occurrence of an event or a delayed coded event from a detected event: the first one is using the post-processing classes, and the second one is to configure the CodingEventDetector in order to create the delayed or filtered coded events during the propagation (in addition to the &amp;quot;standard&amp;quot; coded events).&lt;br /&gt;
While the former can only be done after the propagation, the latter has to be set before the propagation and is possible thanks to the following methods in the class CodingEventDetector:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buildCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the standard CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildDelayedCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the delayed CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildOccurrenceCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the n-th occurrence CodedEvent (n will be a parameter chosen by the user)&lt;br /&gt;
&lt;br /&gt;
In order to use this feature, the delay value and/or the occurrence number must be given as input parameters of the constructor of the class implementing the CodingEventDetector class (for instance GenericCodingEventDetector). The CodedEventsLogger will then be able to read these parameters and handle the generation of standard and not-standard coded events.&lt;br /&gt;
&lt;br /&gt;
Note, in the GenericCodingEventDetector constructor (EventDetector, String, String, boolean, String, double, int), if both parameters delayIn and occurrenceIn are other than 0, the event is saved as a delayed event, not a &amp;quot;Nth occurence of&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== When to use Coded events and phenomena ===&lt;br /&gt;
* To build easier time lines of events&lt;br /&gt;
* To manipulate easier phenomena (for example between &amp;quot;starting&amp;quot; and &amp;quot;ending&amp;quot; events) and associate to them specific computations (for example the evolution of the illumination during an eclipse)&lt;br /&gt;
* To apply some [MIS_POSTP_Home post-processing filters]&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Using available events detectors ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
Example of propagation stopping at 3rd detected node with event detector overloading:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Initialization&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2003, 1, 1, TimeScalesFactory.getTAI());&lt;br /&gt;
final Orbit orbit = new KeplerianOrbit(7000000, 0.01, 0.1, 0.2, 0.3, 0.4, PositionAngle.TRUE, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
&lt;br /&gt;
// Node detector&lt;br /&gt;
final EventDetector nodeDetector = new NodeDetector(orbit, FramesFactory.getGCRF(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
// Stop at 3rd detected node&lt;br /&gt;
final NthOccurrenceDetector nthOccurrenceDetector = new NthOccurrenceDetector(nodeDetector, 3, Action.STOP) {&lt;br /&gt;
    @Override&lt;br /&gt;
    public Action eventOccurred(SpacecraftState s, boolean increasing, boolean forward) throws PatriusException {&lt;br /&gt;
        super.eventOccurred(s, increasing, forward);&lt;br /&gt;
        if (getCurrentOccurence() == getOccurence()) {&lt;br /&gt;
            return Action.STOP;&lt;br /&gt;
        } else {&lt;br /&gt;
            return Action.CONTINUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Propagation&lt;br /&gt;
final KeplerianPropagator propagator = new KeplerianPropagator(orbit);&lt;br /&gt;
propagator.addEventDetector(nthOccurrenceDetector);&lt;br /&gt;
propagator.propagate(orbit.getDate().shiftedBy(86400.));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generating coded events and phenomena ===&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent instances and Phenomenon instances are meant to be produced using :&amp;lt;br&amp;gt;&lt;br /&gt;
- CodingEventDetector implementations that provide information about events and phenomena,&amp;lt;br&amp;gt;&lt;br /&gt;
- a CodingEventsLogger, that uses the CodingEventDetector instances to build the events and phenomena.&lt;br /&gt;
&lt;br /&gt;
For example, if we want to create a list of CodedEvent objects using a detector of nodes (ascending and descending orbital nodes):&lt;br /&gt;
&lt;br /&gt;
1. Create a new EventDetector (in this case a NodeDetector):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set up the node detector:&lt;br /&gt;
  AbsoluteDate date = new AbsoluteDate(&amp;quot;2000-01-01T12:00:00Z&amp;quot;, TimeScalesFactory.getTT());&lt;br /&gt;
  AbsoluteDate dateF = date.shiftedBy(2* period);&lt;br /&gt;
  Orbit orbit = new KeplerianOrbit(7e6, 0, 0.2, 0, 0, 0.2, PositionAngle.MEAN, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
  NodeDetector node = new NodeDetector(orbit, FramesFactory.getEME2000(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Create a new generic coding event detector:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // standard event&lt;br /&gt;
  GenericCodingEventDetector nodeDet =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;);&lt;br /&gt;
  // third occurence of event&lt;br /&gt;
  GenericCodingEventDetector nodeDetOcc =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 0., 3);&lt;br /&gt;
  // delayed event (10 seconds here)&lt;br /&gt;
  GenericCodingEventDetector nodeDetDel =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 10., 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Create a new CodedEventsLogger and use the &amp;lt;code&amp;gt; monitorDetector &amp;lt;/code&amp;gt; function on the new CodedEventsLogger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  CodedEventsLogger logger = new CodedEventsLogger();&lt;br /&gt;
  // Create an EventDetector object so that event detection functions could be used:&lt;br /&gt;
  EventDetector d = logger.monitorDetector(nodeDet);&lt;br /&gt;
  EventDetector dOcc = logger.monitorDetector(nodeDetOcc);&lt;br /&gt;
  EventDetector dDel = logger.monitorDetector(nodeDetDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Add the EventDetector to the propagator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  propagator.addEventDetector(d);&lt;br /&gt;
  propagator.addEventDetector(dOcc);&lt;br /&gt;
  propagator.addEventDetector(dDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Start the propagation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set the propagator:&lt;br /&gt;
  propagator.setEphemerisMode();&lt;br /&gt;
  propagator.resetInitialState(new SpacecraftState(orbit));&lt;br /&gt;
  // Propagate:&lt;br /&gt;
  propagator.propagate(date0, dateF);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Combination of boolean phenomena ===&lt;br /&gt;
Sometimes an event (a zero of a g function) can be seen as a begin (passing zero from positive to negative or invert) or a end ( other way ) of a phenomena. For example the eclipse event can be the begin (detected when g function goes from positive to negative) or the end (when g function goes from negative to positive) of an eclipse. (cf. [MIS_ORB_Home#HEclipseDetectorandGenericEclipseDetector Eclipse detector].)&lt;br /&gt;
&lt;br /&gt;
One can choose to create an event as a combination of these phenomena, for example a station visibility outside an interference period. In this case a user can create a detector as a combination of existing detectors.&lt;br /&gt;
&lt;br /&gt;
The user simply has to provide the following parameters :&lt;br /&gt;
#First detector and the way to use it (g is positive or negative during the phenomena to combine)&lt;br /&gt;
#Second detector and the way to use it &lt;br /&gt;
#How to combine the phenomenom : both are during phenomena (will be detected as the minimum of the two g function) or at least one (will be detected as the maximum of the two g function) is during phenomena &lt;br /&gt;
&lt;br /&gt;
Once a new detector have been created in this way, it is possible to combine it with another one and so on.&lt;br /&gt;
&lt;br /&gt;
For example the [MIS_SENSORS_Home#HCentralBodyMaskCircularFOVDetector CentralBodyMaskCircularFOVDetector] detects when a target is in a circular field of view and outside of an eclipse, that is translated by :&lt;br /&gt;
&lt;br /&gt;
* Outside of eclipse : when EllipsoidEclipseDetecor g function is positive &lt;br /&gt;
* Inside circular field of view : when CircularFieldOfView g function is positive&lt;br /&gt;
&lt;br /&gt;
So the following code example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// EclipseDetector&lt;br /&gt;
final EclipseDetector eed = new EclipseDetector(targetPVP, targetRadius, spheroEarth, 1., MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// CircularFOVDetector&lt;br /&gt;
final CircularFieldOfViewDetector cfvd = new CircularFieldOfViewDetector(targetPVP, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CombinedPhenomenaDetector cbmcfovd2 = new CombinedPhenomenaDetector(eed, true, cfvd, true, true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is equivalent to CentralBodyMaskCircularFOVDetector :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CentralBodyMaskCircularFOVDetector cbmcfovd = &lt;br /&gt;
new CentralBodyMaskCircularFOVDetector(targetPVP, targetRadius, spheroEarth, false, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
==== Interfaces events detection ====&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.11}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/CodingEventDetector.html CodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiEventDetector&lt;br /&gt;
|This interface represents an event finder in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
==== Classes containing the general functions to detect events ====&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;
| AbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/AbstractDetector.html AbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiAbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiAbstractDetector.html MultiAbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedEventDetector&lt;br /&gt;
|This class adapts Patrius event detectors to math EventHandler object.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/AdaptedEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMonoEventDetector&lt;br /&gt;
|This class adapts Patrius mono event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMonoEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMultiEventDetector&lt;br /&gt;
|This class adapts Patrius multi event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMultiEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CombinedPhenomenaDetector&lt;br /&gt;
|This class handles events representing the combination of two boolean phenomena.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/CombinedPhenomenaDetector.html CombinedPhenomenaDetector]&lt;br /&gt;
|-&lt;br /&gt;
| NthOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a certain occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| IntervalOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a interval occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurrenceDetector.html IntervalOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| ExtremaGenericDetector&lt;br /&gt;
|This class represents an event detector that detects the derivative cancellation of an underlying detector.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/propagation/events/ExtremaGenericDetector.html ExtremaGenericDetector]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Classes for the generation of lists of events and phenomena ====&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;
| CodedEvent&lt;br /&gt;
|This class implements coded events (a light and simple representation of events as generated by Patrius event detectors ).&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/CodedEvent.html CodedEvent]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/CodedEventsList.html CodedEventsList]&lt;br /&gt;
|-&lt;br /&gt;
| Phenomenon&lt;br /&gt;
|This class implements the notion of a phenomenon : a state defined by a starting event and an ending event.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/Phenomenon.html Phenomenon]&lt;br /&gt;
|-&lt;br /&gt;
| PhenomenaList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/PhenomenaList.html PhenomenaList]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/CodedEventsLogger.html CodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| GenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/GenericCodingEventDetector.html GenericCodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiGenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface in multi propagation case, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.11}}/fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.11_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.10_Events_detection:_Presentation&amp;diff=3613</id>
		<title>User Manual 4.10 Events detection: Presentation</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.10_Events_detection:_Presentation&amp;diff=3613"/>
		<updated>2023-12-19T16:19:40Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes :&lt;br /&gt;
&lt;br /&gt;
* in a mono satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions that extend  event detection mechanism.&lt;br /&gt;
* in a multi satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions, copied from the mono satellite mechanism, that extend Patrius&#039;s event detection mechanism for multi satellite propagation.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The following packages are related to events detections in mono and multi propagation context:&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.10}}/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.10}}/fr/cnes/sirius/patrius/math/ode/events/package-summary.html Package fr.cnes.sirius.patrius.math.ode.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/package-summary.html Package fr.cnes.sirius.patrius.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/multi/package-summary.html Package fr.cnes.sirius.patrius.propagation.events.multi]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as 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 architecture of the events detection for mono and multi satellite propagation.&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:EventsV3.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following diagram represents the mechanism used in the Patrius library in order to create the list of the events detected during the mono satellite propagation as well as the phenomena list :&lt;br /&gt;
&lt;br /&gt;
[[File:Events.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following classes are duplicated from mono satellite context in order to create a list of events detected : &lt;br /&gt;
* [{{JavaDoc4.10}}//fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.10}}//fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
* [{{JavaDoc4.10}}//fr/cnes/sirius/patrius/events/multi/MultiEventsLogger.html MultiEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.10}}//fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Event detection ===&lt;br /&gt;
&lt;br /&gt;
The events detection process can be used during mono or multi propagation propagation, when we need to know if some events occur and at what time (for instance when the satellite will be in eclipse, or if at a given date it will be visible or not from a ground station).&lt;br /&gt;
&lt;br /&gt;
In Patrius there is one class for every kind of event: the information related to an event is contained in this class, and it will be used by the mono satellite numerical or analytical propagator when extrapolating the orbit. The mechanism is similar for multi propagation.&lt;br /&gt;
&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are detected is the order in which they are added to the propagator.&lt;br /&gt;
&lt;br /&gt;
As of PATRIUS 4.5, detectors can optionally take into account signal propagation delay. Javadoc of each event detector indicates if signal propagation delay can be taken into account through a setter &amp;lt;code&amp;gt;setPropagationDelayType()&amp;lt;/code&amp;gt;. Delay type is of 2 types:&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.INSTANTANEOUS&amp;lt;/code&amp;gt;: signal propagation delay is not taken into account&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.LIGHT_SPEED&amp;lt;/code&amp;gt;: signal propagation delay is taken into account.&lt;br /&gt;
Signal propagation delay allows to detect events as it is exactly seen by a spacecraft, for instance a visibility between a satellite and a station.&lt;br /&gt;
All detectors involving a signal propagation and or sensors can take signal propagation delay into account (BetaAngleDetector, SensorVisibilityDetector, TargetInFieldOfViewDetector, etc.):&lt;br /&gt;
&lt;br /&gt;
By default signal propagation delay is not taken into account.&lt;br /&gt;
&lt;br /&gt;
A new detector class should implements  : &lt;br /&gt;
* [{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector interface] in case of [{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/Propagator.html mono satellite propagation] or [{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
* [{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector interface] in case of [{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Construction of a detector&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The action performed at event detection can be set by user at detector&#039;s construction. Several actions can be defined if several behavior are available (depending on state and/or on increasing/forward parameter). It is possible to specify at construction if the detector should be removed after event detection and thus not be detected any more. If a single action is available, a single boolean has to be provided by the user at construction. In the case where several actions are available, the same number of boolean has to be provided to determine if the detector has to be removed after event detection.&amp;lt;br&amp;gt;&lt;br /&gt;
Focusing on the &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt; for instance, two actions are possible at event detection :&lt;br /&gt;
&lt;br /&gt;
- action_at_ascending_node if an ascending node detection is done&amp;lt;br&amp;gt;&lt;br /&gt;
- action_at_descending_node if a descending node detection is performed&lt;br /&gt;
&lt;br /&gt;
If no actions are set, the user should be aware of the default implementation.&lt;br /&gt;
By default, event detectors are never removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of eventOccurred()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The returned action of the function eventOccurred could be set by user or defined by default.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function eventOccurred is common to all [{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector] classes (respectively [{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]) and its purpose is to handle an event and to choose what to do next ; this method is called when the integrator has accepted a step ending exactly on a sign change of the switching function, and it allows the user to choose which action will take place after the event (the simulation could be stopped, the propagator could reset its initial state or its initial derivative state ...).&lt;br /&gt;
Plus, this method is up to determine if the detector used has to be removed after the event detection : in the above example of &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt;, the action taking place after the event is set to action_at_raising_node in the case of an ascending node detection. If one has decided to remove the detector at such detection, the attribute shouldBeRemoved will be set to remove_at_ascending_node which is true by construction, the case of descending node is similar.&lt;br /&gt;
&lt;br /&gt;
Since the default implementation of eventOccurred could unfit the user needs in terms of propagation behaviour, it is recommended to check the content of the detector before using them and to change it if necessary by using a specific constructor which take as parameter the expected action(s).&lt;br /&gt;
&lt;br /&gt;
Note that the implementation of eventOccured must not contain any action. Even if the action does not impact the state vector, the action should be implemented in the resetState method.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of resetState() or resetStates()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If the event have an action, this action should be implemented in the resetState() method. In this case, the eventOccured() of the detector concerned should return a RESET_STATE action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Convergence threshold parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The convergence threshold represents the events detection precision; the following observations can help the user when choosing a value for this parameter:&lt;br /&gt;
&lt;br /&gt;
#if the convergence threshold increases, the execution time decreases (the precision becomes worst);&lt;br /&gt;
#if the convergence threshold is bigger than the max integration step, the events detection will fail.&lt;br /&gt;
&lt;br /&gt;
If the resetState(s) could modify others event detectors, the convergence threshold should be low in order to avoid any unpredictable behavior.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Max check interval parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The max check interval parameter represents the maximum interval in which the propagator checks for an event (i.e. for a sign change of the g switching function). When choosing this parameter, the user should keep in mind the following remarks:&lt;br /&gt;
&lt;br /&gt;
#if max check interval is smaller than the integration step, the execution time increases if the max check interval decreases (the events detection is more accurate);&lt;br /&gt;
#if max check interval is bigger than the max integration step, it will be replaced by the max integration step during the events detection process; in this case the max check interval is a useless parameter that will never be used by the propagator.&lt;br /&gt;
&lt;br /&gt;
In general, the user should always choose the max check interval value as a function of the integration step used during propagation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of the event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation start date, i.e if g() equal to zero, the event is processed. This case is extremely rare. Note that in some case however, due to numerical quality rounds-off, an event may not be detected at the propagation start date although it&#039;s theoritically supposed to occur. For example, starting propagation at periapsis with a periapsis detector may not detect periapsis since the g() function of PeriapsisDetector is based on position- velocity scalar product and due to rounds-off errors, its values may be around 1E-7 which is not exactly zero. &amp;lt;br&amp;gt;&lt;br /&gt;
Also, if at the propagation start date the g() function is not continuous but changes its sign (for example value-1 before event date, value 1 after), the event will also not be detected since the g() function value is not zero.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Ephemeris propagator event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one. Consequently, when propagating with a bounded propagator, if the last substep is larger than the real one then the real end date is exceeded, raising an exception. Therefore, in this case, it is recommended to &#039;&#039;&#039;propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the same date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are processed is the order in which they are added to the propagator. If the detected event stops the propagation, the other events occuring at the same date are not processed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the end date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation end date, the event is not processed.&lt;br /&gt;
&lt;br /&gt;
==== Available event detectors ====&lt;br /&gt;
Mono events detectors detect events applied on a specific state. These detectors can be used in mono or multi propagation case.&lt;br /&gt;
&lt;br /&gt;
The available mono events detectors are presented in specific pages: &lt;br /&gt;
&lt;br /&gt;
* [MIS_ORB_Home Orbit determination events]&lt;br /&gt;
* [MIS_SENSORS_Home Sensors events]&lt;br /&gt;
* [MIS_STASAT_Home Ground stations and satellites events]&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
It also exists multi events detectors applied on several states. These detectors can only be used in multi propagation case.&lt;br /&gt;
Notice that some detectors that implies several satellite coul be used in multi or mono satellite context ; ([{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/sensor/SatToSatMutualVisibilityDetector.html SatToSatMutualVisibilityDetector], [{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/ThreeBodiesAngleDetector.html ThreeBodiesAngleDetector] or [{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/ExtremaThreeBodiesAngleDetector.html ExtremaThreeBodiesAngleDetector])&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HMultiEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
The [{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector] is a detector that detects the nth occurrence of an underlying event detector.&amp;lt;br&amp;gt;&lt;br /&gt;
However the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every event of the underlying detector. As a result, the behaviour of this detector is the following:&lt;br /&gt;
* Before and after the nth occurrence, the eventOccurred() method returns &amp;lt;code&amp;gt;Action.CONTINUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
* At the nth occurrence, the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method returns the user-provided action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Warning&#039;&#039;&#039;&#039;&#039;: the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every occurrence of the underlying detector, not only at nth occurrence. Hence, overloading this detector should be performed carefully: in the overloaded &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method, the check &amp;lt;code&amp;gt;getCurrentOccurence() == getOccurence()&amp;lt;/code&amp;gt; should be performed first to ensure we are at nth occurrence before calling &amp;lt;code&amp;gt;super.eventOccurred()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== IntervalOccurenceDetector ====&lt;br /&gt;
This [{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurenceDetector.html IntervalOccurenceDetector ] is able for any EventDetector. It detects the &amp;lt;math&amp;gt;n^{th}&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;m^{th}&amp;lt;/math&amp;gt; event occurences by step of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; occurences. &lt;br /&gt;
Otherwise, if j event occurence, the &amp;lt;code&amp;gt;IntervalOccurenceDetector&amp;lt;/code&amp;gt; detects events as : &lt;br /&gt;
* &amp;lt;math&amp;gt;(j - n) % p = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n &amp;lt;= j &amp;lt;= m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The g switching function is the function of the event to detect.&lt;br /&gt;
&lt;br /&gt;
==== ExtremaGenericDetector ====&lt;br /&gt;
&lt;br /&gt;
This class represents an event detector that detects the derivative cancellation of an underlying detector. Using this detector recursively will allow to detect nth order derivative.&lt;br /&gt;
&lt;br /&gt;
The g switching function cancels for any extrema of the g function of the underlying detector.&lt;br /&gt;
Min, max or both at the same time.&lt;br /&gt;
&lt;br /&gt;
==== Mono Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
When a numerical propagation is performed, the event detection is done at the math level since the integration is realized by one of the numerical integrators. However, the event detectors are instanciated by the user at the Patrius level. Hence the necessity of an adapter to wrap a Patrius event detector object into a math event handler object whose interfaces provide basically the same kind of services. Once the event detectors are given to the numerical propagator, they are transformed into event handlers in order to give them to the math numerical integrator.&amp;lt;br&amp;gt;&lt;br /&gt;
The numerical integrator associates each event with another object which represents its state during the integration. At the end of each step, the method acceptStep() is systematically called and performs the event detection thanks to an interpolator, inside the current step. Thus the state of each event is updated. If an event is detected therefore the integration is either stopped or continued with or without state or derivative state resetting. It is also possible to remove the detector after the first event detection and the propagation is continued. An event is represented by a function, the function &amp;quot;g()&amp;quot;: the event occurs when the function sign changes and NOT when this function equals to zero. To find this root, in addition to the interpolator, a solver is used. By default, this solver is the Brent solver. The exception being at the beginning of the propagation where events are detected when the g() function equals exactly zero.&lt;br /&gt;
&lt;br /&gt;
===== Analytical propagator =====&lt;br /&gt;
&lt;br /&gt;
When an analytical propagation is performed, the event detection is done at the Patrius level directly. The process is basically the same than its math counterpart: the detectors are given to the propagator and associated to their states. The Patrius propagator has a method acceptStep() which is similar to the one of the math package.&lt;br /&gt;
&lt;br /&gt;
===== Ephemeris propagator =====&lt;br /&gt;
&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one which could be knotty when it comes to propagate with a bounded propagator. Indeed, if the last substep is larger than the real one then the real end date is exceeded. If the end date is equal to the ephemeris max date, an exception is raised when the interpolator sets the current date to a date exceeding the ephemeris max date. Therefore, in this case, &#039;&#039;&#039;it is recommended to propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Multi Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
The event detector process for multi satellite numerical propagation is equivalent to the process performed with single satellite numerical propagation. The multi event detection is wrapped into a math event handler object. The detector could be applied on a single satellite or on several satellites.&lt;br /&gt;
&lt;br /&gt;
=== Coded events and phenomena ===&lt;br /&gt;
==== Mono propagation ====&lt;br /&gt;
===== The coded event =====&lt;br /&gt;
&lt;br /&gt;
Patrius does detect events. This means :&lt;br /&gt;
&lt;br /&gt;
* Patrius triggers a method call on the corresponding EventDetector when the event occurs.&lt;br /&gt;
* Patrius logs the SpacecraftState and g function slope sign for the occuring event (through the EventsLogger).&lt;br /&gt;
&lt;br /&gt;
But this mechanism alone doesn&#039;t provide a programmatic representation for an &amp;quot;event&amp;quot;, which may be processed after the propagation.&lt;br /&gt;
&lt;br /&gt;
A new way of handling events as individual instances was thus designed : the &amp;quot;atomic event&amp;quot; or &amp;quot;coded event&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;coded event&amp;quot; has the following attributes :&lt;br /&gt;
&lt;br /&gt;
* an event &amp;quot;code&amp;quot; : a String identifying the category of the event, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* an event &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* an AbsoluteDate : the date at which the event occurred.&lt;br /&gt;
* a boolean, true when the event represents a &amp;quot;starting&amp;quot; event, or false when it represents an &amp;quot;ending&amp;quot; event (relative to a phenomenon, see below).&lt;br /&gt;
&lt;br /&gt;
The code and comment formats are free, they depend on the CodingEventDetector implementation (see below).&lt;br /&gt;
&lt;br /&gt;
A CodedEvent is supposed to be built by the CodedEventsLogger (see below).&lt;br /&gt;
&lt;br /&gt;
Moreover, when one of the boundaries of the phenomenon is ill-defined (e.g. unknown due to computational limits), it is an instance of CodedEvent, with the code &amp;quot;UNDEFINED_EVENT&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== The CodingEventDetector and MultiCodingEventDetector =====&lt;br /&gt;
&lt;br /&gt;
The CodingEventDetector (or MultiCodingEventDetector in MultiPropagator case) is an extension of the EventDetector type(respectively MultiEventDetector). A CodingEventDetector (or MultiCodingEventDetector) has the following requirements :&lt;br /&gt;
&lt;br /&gt;
* Providing a CodedEvent builder method, that creates a CodedEvent instance appropriate for the event (this is how the code and comment are determined).&lt;br /&gt;
* Providing a Phenomenon code if a Phenomenon makes sense in the context of the event, otherwise return null (see below).&lt;br /&gt;
* Providing a boolean telling which sign of the g() method means the Phenomenon is active (see below).&lt;br /&gt;
&lt;br /&gt;
===== The phenomenon =====&lt;br /&gt;
&lt;br /&gt;
The EventDetector provides a g() method whose sign change triggers an event. Sometimes the g() method can also be seen as conveying a &amp;quot;state&amp;quot; i.e. when g() is positive (resp. negative), a &amp;quot;phenomenon&amp;quot; is going on.&lt;br /&gt;
The clearest example would be the EclipseDetector :&lt;br /&gt;
&lt;br /&gt;
* g() going from positive to negative means that the spacecraft has entered the eclipse zone.&lt;br /&gt;
* g() going from negative to positive means that the spacecraft has exited the eclipse zone.&lt;br /&gt;
&lt;br /&gt;
The associated phenomenon would then be called &amp;quot;inside the eclipse zone&amp;quot;, bounded by the starting event &amp;quot;enter eclipse zone&amp;quot; and the ending event &amp;quot;exit eclipse zone&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This library provides a &amp;quot;phenomenon&amp;quot; abstraction, as a lightweight representation.&lt;br /&gt;
&lt;br /&gt;
A Phenomenon instance is an immutable object with the following attributes :&lt;br /&gt;
&lt;br /&gt;
* a phenomenon &amp;quot;code&amp;quot; : a String identifying the category of the phenomenon, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* a phenomenon &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* two &amp;quot;coded event&amp;quot; instances : the atomic events that represent the start and the end of the phenomenon.&lt;br /&gt;
&lt;br /&gt;
Also :&lt;br /&gt;
* it tells whether the start and end are &amp;quot;well-defined&amp;quot; : a well-defined boundary has a real event backing it. A not well-defined boundary is a boundary because of computational limits : it happens when, during a propagation, the ending event occurs, but the starting event did not (or, the opposite) because it was outside the boundaries of the propagation. In this case, an &amp;quot;UNDEFINED_EVENT&amp;quot; is given as the missing boundary (see above).&lt;br /&gt;
&lt;br /&gt;
A Phenomenon is built by the CodedEventsLogger, when the CodingEventDetector provides a non-null Phenomenon string code. The existence of this code proves the Phenomenon makes senses in the context of the CodingEventDetector. For instance :&lt;br /&gt;
&lt;br /&gt;
* for a &amp;quot;CodingEclipseDetector&amp;quot; built upon the EclipseDetector, a Phenomenon has meaning (the Phenomenon being &amp;quot;inside the eclipse&amp;quot;).&lt;br /&gt;
* for a &amp;quot;CodingApsideDetector&amp;quot; built upen the ApsideDetector, a Phenomenon has no meaning, since the events are : &amp;quot;the spacecraft is at the periapsis&amp;quot; and &amp;quot;the spacecraft is at the apoapsis&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Multi propagation ====&lt;br /&gt;
The same process exists. The corresponding classes are localized in the Patrius library.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting up a CodedEventsLogger or a MultiCodedEventsLogger ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent and Phenomenon instances are not meant to be produced by the CodingEventDetectors (or directly MultiCodedEventsLogger in MultiPropagator case) (but it could be possible if needed).&lt;br /&gt;
&lt;br /&gt;
Instead, the (Multi)CodedEventsLogger was created for this purpose.&lt;br /&gt;
&lt;br /&gt;
At first glance, a (Multi)CodedEventsLogger instance is very similar to the (Multi)EventsLogger.&lt;br /&gt;
The main difference is that the (Multi)EventsLogger instances have no inner representation of events, while the (Multi)CodedEventsLogger produces CodedEvent and Phenomenon lists.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how one uses the (Multi)CodedEventsLogger :&lt;br /&gt;
&lt;br /&gt;
* create a (Multi)CodedEventsLogger instance.&lt;br /&gt;
* create at least one (Multi)CodingEventProvider instance.&lt;br /&gt;
* call the &amp;lt;code&amp;gt;monitorDetector()&amp;lt;/code&amp;gt; method on the (Multi)CodedEventsLogger : it produces a &amp;quot;wrapper&amp;quot; of the (Multi)CodingEventProvider exposed as a regular EventProvider.&lt;br /&gt;
* pass this &amp;quot;wrapper&amp;quot; to a propagator (any kind works : those who do compute a propagation and those who replay an ephemeris).&lt;br /&gt;
* run the propagator.&lt;br /&gt;
&lt;br /&gt;
While the propagator runs, the &amp;quot;wrapper&amp;quot; calls both the (Multi)CodingEventProvider instance and the (Multi)CodedEventsLogger on each event. The (Multi)CodedEventsLogger instance uses the (Multi)CodingEventProvider to build and store all CodedEvent instances during the propagation.&lt;br /&gt;
&lt;br /&gt;
==== Getting the full coded events list ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;getCodedEventsList()&amp;lt;/code&amp;gt;.&lt;br /&gt;
It provides a list of all CodedEvents (for all the CodingEventDetectors passed to the propagator, without distinction).&lt;br /&gt;
&lt;br /&gt;
==== Getting the events list per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildCodedEventListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a CodedEventsList as value, this list only containing the events generated from the key.&amp;lt;br&amp;gt;&lt;br /&gt;
It is, therfore, the same data as the full events&#039; list, but rearranged per CodingEventProvider instance.&lt;br /&gt;
&lt;br /&gt;
==== Getting the phenomena per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildPhenomenaListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a PhenomenaList as value, this list only containing the Phenomenon instances generated from the key. The(Multi) CodingEventProvider instance provides the Phenomenon code.&lt;br /&gt;
&lt;br /&gt;
The (Multi)CodedEventsLogger only uses the (Multi)CodingEventProvider instances that provide a non-null Phenomenon code (null indicates that a Phenomenon has no meaning for this detector).&lt;br /&gt;
&lt;br /&gt;
==== N-th occurrence of a coded event, or a delayed event ====&lt;br /&gt;
&lt;br /&gt;
There are two ways to generate the n-th occurrence of an event or a delayed coded event from a detected event: the first one is using the post-processing classes, and the second one is to configure the CodingEventDetector in order to create the delayed or filtered coded events during the propagation (in addition to the &amp;quot;standard&amp;quot; coded events).&lt;br /&gt;
While the former can only be done after the propagation, the latter has to be set before the propagation and is possible thanks to the following methods in the class CodingEventDetector:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buildCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the standard CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildDelayedCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the delayed CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildOccurrenceCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the n-th occurrence CodedEvent (n will be a parameter chosen by the user)&lt;br /&gt;
&lt;br /&gt;
In order to use this feature, the delay value and/or the occurrence number must be given as input parameters of the constructor of the class implementing the CodingEventDetector class (for instance GenericCodingEventDetector). The CodedEventsLogger will then be able to read these parameters and handle the generation of standard and not-standard coded events.&lt;br /&gt;
&lt;br /&gt;
Note, in the GenericCodingEventDetector constructor (EventDetector, String, String, boolean, String, double, int), if both parameters delayIn and occurrenceIn are other than 0, the event is saved as a delayed event, not a &amp;quot;Nth occurence of&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== When to use Coded events and phenomena ===&lt;br /&gt;
* To build easier time lines of events&lt;br /&gt;
* To manipulate easier phenomena (for example between &amp;quot;starting&amp;quot; and &amp;quot;ending&amp;quot; events) and associate to them specific computations (for example the evolution of the illumination during an eclipse)&lt;br /&gt;
* To apply some [MIS_POSTP_Home post-processing filters]&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Using available events detectors ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
Example of propagation stopping at 3rd detected node with event detector overloading:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Initialization&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2003, 1, 1, TimeScalesFactory.getTAI());&lt;br /&gt;
final Orbit orbit = new KeplerianOrbit(7000000, 0.01, 0.1, 0.2, 0.3, 0.4, PositionAngle.TRUE, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
&lt;br /&gt;
// Node detector&lt;br /&gt;
final EventDetector nodeDetector = new NodeDetector(orbit, FramesFactory.getGCRF(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
// Stop at 3rd detected node&lt;br /&gt;
final NthOccurrenceDetector nthOccurrenceDetector = new NthOccurrenceDetector(nodeDetector, 3, Action.STOP) {&lt;br /&gt;
    @Override&lt;br /&gt;
    public Action eventOccurred(SpacecraftState s, boolean increasing, boolean forward) throws PatriusException {&lt;br /&gt;
        super.eventOccurred(s, increasing, forward);&lt;br /&gt;
        if (getCurrentOccurence() == getOccurence()) {&lt;br /&gt;
            return Action.STOP;&lt;br /&gt;
        } else {&lt;br /&gt;
            return Action.CONTINUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Propagation&lt;br /&gt;
final KeplerianPropagator propagator = new KeplerianPropagator(orbit);&lt;br /&gt;
propagator.addEventDetector(nthOccurrenceDetector);&lt;br /&gt;
propagator.propagate(orbit.getDate().shiftedBy(86400.));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generating coded events and phenomena ===&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent instances and Phenomenon instances are meant to be produced using :&amp;lt;br&amp;gt;&lt;br /&gt;
- CodingEventDetector implementations that provide information about events and phenomena,&amp;lt;br&amp;gt;&lt;br /&gt;
- a CodingEventsLogger, that uses the CodingEventDetector instances to build the events and phenomena.&lt;br /&gt;
&lt;br /&gt;
For example, if we want to create a list of CodedEvent objects using a detector of nodes (ascending and descending orbital nodes):&lt;br /&gt;
&lt;br /&gt;
1. Create a new EventDetector (in this case a NodeDetector):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set up the node detector:&lt;br /&gt;
  AbsoluteDate date = new AbsoluteDate(&amp;quot;2000-01-01T12:00:00Z&amp;quot;, TimeScalesFactory.getTT());&lt;br /&gt;
  AbsoluteDate dateF = date.shiftedBy(2* period);&lt;br /&gt;
  Orbit orbit = new KeplerianOrbit(7e6, 0, 0.2, 0, 0, 0.2, PositionAngle.MEAN, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
  NodeDetector node = new NodeDetector(orbit, FramesFactory.getEME2000(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Create a new generic coding event detector:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // standard event&lt;br /&gt;
  GenericCodingEventDetector nodeDet =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;);&lt;br /&gt;
  // third occurence of event&lt;br /&gt;
  GenericCodingEventDetector nodeDetOcc =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 0., 3);&lt;br /&gt;
  // delayed event (10 seconds here)&lt;br /&gt;
  GenericCodingEventDetector nodeDetDel =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 10., 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Create a new CodedEventsLogger and use the &amp;lt;code&amp;gt; monitorDetector &amp;lt;/code&amp;gt; function on the new CodedEventsLogger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  CodedEventsLogger logger = new CodedEventsLogger();&lt;br /&gt;
  // Create an EventDetector object so that event detection functions could be used:&lt;br /&gt;
  EventDetector d = logger.monitorDetector(nodeDet);&lt;br /&gt;
  EventDetector dOcc = logger.monitorDetector(nodeDetOcc);&lt;br /&gt;
  EventDetector dDel = logger.monitorDetector(nodeDetDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Add the EventDetector to the propagator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  propagator.addEventDetector(d);&lt;br /&gt;
  propagator.addEventDetector(dOcc);&lt;br /&gt;
  propagator.addEventDetector(dDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Start the propagation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set the propagator:&lt;br /&gt;
  propagator.setEphemerisMode();&lt;br /&gt;
  propagator.resetInitialState(new SpacecraftState(orbit));&lt;br /&gt;
  // Propagate:&lt;br /&gt;
  propagator.propagate(date0, dateF);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Combination of boolean phenomena ===&lt;br /&gt;
Sometimes an event (a zero of a g function) can be seen as a begin (passing zero from positive to negative or invert) or a end ( other way ) of a phenomena. For example the eclipse event can be the begin (detected when g function goes from positive to negative) or the end (when g function goes from negative to positive) of an eclipse. (cf. [MIS_ORB_Home#HEclipseDetectorandGenericEclipseDetector Eclipse detector].)&lt;br /&gt;
&lt;br /&gt;
One can choose to create an event as a combination of these phenomena, for example a station visibility outside an interference period. In this case a user can create a detector as a combination of existing detectors.&lt;br /&gt;
&lt;br /&gt;
The user simply has to provide the following parameters :&lt;br /&gt;
#First detector and the way to use it (g is positive or negative during the phenomena to combine)&lt;br /&gt;
#Second detector and the way to use it &lt;br /&gt;
#How to combine the phenomenom : both are during phenomena (will be detected as the minimum of the two g function) or at least one (will be detected as the maximum of the two g function) is during phenomena &lt;br /&gt;
&lt;br /&gt;
Once a new detector have been created in this way, it is possible to combine it with another one and so on.&lt;br /&gt;
&lt;br /&gt;
For example the [MIS_SENSORS_Home#HCentralBodyMaskCircularFOVDetector CentralBodyMaskCircularFOVDetector] detects when a target is in a circular field of view and outside of an eclipse, that is translated by :&lt;br /&gt;
&lt;br /&gt;
* Outside of eclipse : when EllipsoidEclipseDetecor g function is positive &lt;br /&gt;
* Inside circular field of view : when CircularFieldOfView g function is positive&lt;br /&gt;
&lt;br /&gt;
So the following code example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// EclipseDetector&lt;br /&gt;
final EclipseDetector eed = new EclipseDetector(targetPVP, targetRadius, spheroEarth, 1., MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// CircularFOVDetector&lt;br /&gt;
final CircularFieldOfViewDetector cfvd = new CircularFieldOfViewDetector(targetPVP, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CombinedPhenomenaDetector cbmcfovd2 = new CombinedPhenomenaDetector(eed, true, cfvd, true, true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is equivalent to CentralBodyMaskCircularFOVDetector :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CentralBodyMaskCircularFOVDetector cbmcfovd = &lt;br /&gt;
new CentralBodyMaskCircularFOVDetector(targetPVP, targetRadius, spheroEarth, false, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
==== Interfaces events detection ====&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.10}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/CodingEventDetector.html CodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiEventDetector&lt;br /&gt;
|This interface represents an event finder in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
==== Classes containing the general functions to detect events ====&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;
| AbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/AbstractDetector.html AbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiAbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiAbstractDetector.html MultiAbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedEventDetector&lt;br /&gt;
|This class adapts Patrius event detectors to math EventHandler object.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/AdaptedEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMonoEventDetector&lt;br /&gt;
|This class adapts Patrius mono event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMonoEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMultiEventDetector&lt;br /&gt;
|This class adapts Patrius multi event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMultiEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CombinedPhenomenaDetector&lt;br /&gt;
|This class handles events representing the combination of two boolean phenomena.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/CombinedPhenomenaDetector.html CombinedPhenomenaDetector]&lt;br /&gt;
|-&lt;br /&gt;
| NthOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a certain occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| IntervalOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a interval occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurrenceDetector.html IntervalOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| ExtremaGenericDetector&lt;br /&gt;
|This class represents an event detector that detects the derivative cancellation of an underlying detector.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/propagation/events/ExtremaGenericDetector.html ExtremaGenericDetector]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Classes for the generation of lists of events and phenomena ====&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;
| CodedEvent&lt;br /&gt;
|This class implements coded events (a light and simple representation of events as generated by Patrius event detectors ).&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/CodedEvent.html CodedEvent]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/CodedEventsList.html CodedEventsList]&lt;br /&gt;
|-&lt;br /&gt;
| Phenomenon&lt;br /&gt;
|This class implements the notion of a phenomenon : a state defined by a starting event and an ending event.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/Phenomenon.html Phenomenon]&lt;br /&gt;
|-&lt;br /&gt;
| PhenomenaList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/PhenomenaList.html PhenomenaList]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/CodedEventsLogger.html CodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| GenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/GenericCodingEventDetector.html GenericCodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiGenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface in multi propagation case, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.10}}/fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.10_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.9_Events_detection:_Presentation&amp;diff=3612</id>
		<title>User Manual 4.9 Events detection: Presentation</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.9_Events_detection:_Presentation&amp;diff=3612"/>
		<updated>2023-12-19T16:19:25Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes :&lt;br /&gt;
&lt;br /&gt;
* in a mono satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions that extend  event detection mechanism.&lt;br /&gt;
* in a multi satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions, copied from the mono satellite mechanism, that extend Patrius&#039;s event detection mechanism for multi satellite propagation.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The following packages are related to events detections in mono and multi propagation context:&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.9}}/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.9}}/fr/cnes/sirius/patrius/math/ode/events/package-summary.html Package fr.cnes.sirius.patrius.math.ode.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/package-summary.html Package fr.cnes.sirius.patrius.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/multi/package-summary.html Package fr.cnes.sirius.patrius.propagation.events.multi]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as 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 architecture of the events detection for mono and multi satellite propagation:&lt;br /&gt;
&lt;br /&gt;
[[File:EventsV3.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following diagram represents the mechanism used in the Patrius library in order to create the list of the events detected during the mono satellite propagation as well as the phenomena list :&lt;br /&gt;
&lt;br /&gt;
[[File:Events.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following classes are duplicated from mono satellite context in order to create a list of events detected : &lt;br /&gt;
* [{{JavaDoc4.9}}//fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.9}}//fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
* [{{JavaDoc4.9}}//fr/cnes/sirius/patrius/events/multi/MultiEventsLogger.html MultiEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.9}}//fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Event detection ===&lt;br /&gt;
&lt;br /&gt;
The events detection process can be used during mono or multi propagation propagation, when we need to know if some events occur and at what time (for instance when the satellite will be in eclipse, or if at a given date it will be visible or not from a ground station).&lt;br /&gt;
&lt;br /&gt;
In Patrius there is one class for every kind of event: the information related to an event is contained in this class, and it will be used by the mono satellite numerical or analytical propagator when extrapolating the orbit. The mechanism is similar for multi propagation.&lt;br /&gt;
&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are detected is the order in which they are added to the propagator.&lt;br /&gt;
&lt;br /&gt;
As of PATRIUS 4.5, detectors can optionally take into account signal propagation delay. Javadoc of each event detector indicates if signal propagation delay can be taken into account through a setter &amp;lt;code&amp;gt;setPropagationDelayType()&amp;lt;/code&amp;gt;. Delay type is of 2 types:&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.INSTANTANEOUS&amp;lt;/code&amp;gt;: signal propagation delay is not taken into account&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.LIGHT_SPEED&amp;lt;/code&amp;gt;: signal propagation delay is taken into account.&lt;br /&gt;
Signal propagation delay allows to detect events as it is exactly seen by a spacecraft, for instance a visibility between a satellite and a station.&lt;br /&gt;
All detectors involving a signal propagation and or sensors can take signal propagation delay into account (BetaAngleDetector, SensorVisibilityDetector, TargetInFieldOfViewDetector, etc.):&lt;br /&gt;
&lt;br /&gt;
By default signal propagation delay is not taken into account.&lt;br /&gt;
&lt;br /&gt;
A new detector class should implements  : &lt;br /&gt;
* [{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector interface] in case of [{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/Propagator.html mono satellite propagation] or [{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
* [{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector interface] in case of [{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Construction of a detector&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The action performed at event detection can be set by user at detector&#039;s construction. Several actions can be defined if several behavior are available (depending on state and/or on increasing/forward parameter). It is possible to specify at construction if the detector should be removed after event detection and thus not be detected any more. If a single action is available, a single boolean has to be provided by the user at construction. In the case where several actions are available, the same number of boolean has to be provided to determine if the detector has to be removed after event detection.&amp;lt;br&amp;gt;&lt;br /&gt;
Focusing on the &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt; for instance, two actions are possible at event detection :&lt;br /&gt;
&lt;br /&gt;
- action_at_ascending_node if an ascending node detection is done&amp;lt;br&amp;gt;&lt;br /&gt;
- action_at_descending_node if a descending node detection is performed&lt;br /&gt;
&lt;br /&gt;
If no actions are set, the user should be aware of the default implementation.&lt;br /&gt;
By default, event detectors are never removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of eventOccurred()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The returned action of the function eventOccurred could be set by user or defined by default.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function eventOccurred is common to all [{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector] classes (respectively [{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]) and its purpose is to handle an event and to choose what to do next ; this method is called when the integrator has accepted a step ending exactly on a sign change of the switching function, and it allows the user to choose which action will take place after the event (the simulation could be stopped, the propagator could reset its initial state or its initial derivative state ...).&lt;br /&gt;
Plus, this method is up to determine if the detector used has to be removed after the event detection : in the above example of &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt;, the action taking place after the event is set to action_at_raising_node in the case of an ascending node detection. If one has decided to remove the detector at such detection, the attribute shouldBeRemoved will be set to remove_at_ascending_node which is true by construction, the case of descending node is similar.&lt;br /&gt;
&lt;br /&gt;
Since the default implementation of eventOccurred could unfit the user needs in terms of propagation behaviour, it is recommended to check the content of the detector before using them and to change it if necessary by using a specific constructor which take as parameter the expected action(s).&lt;br /&gt;
&lt;br /&gt;
Note that the implementation of eventOccured must not contain any action. Even if the action does not impact the state vector, the action should be implemented in the resetState method.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of resetState() or resetStates()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If the event have an action, this action should be implemented in the resetState() method. In this case, the eventOccured() of the detector concerned should return a RESET_STATE action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Convergence threshold parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The convergence threshold represents the events detection precision; the following observations can help the user when choosing a value for this parameter:&lt;br /&gt;
&lt;br /&gt;
#if the convergence threshold increases, the execution time decreases (the precision becomes worst);&lt;br /&gt;
#if the convergence threshold is bigger than the max integration step, the events detection will fail.&lt;br /&gt;
&lt;br /&gt;
If the resetState(s) could modify others event detectors, the convergence threshold should be low in order to avoid any unpredictable behavior.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Max check interval parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The max check interval parameter represents the maximum interval in which the propagator checks for an event (i.e. for a sign change of the g switching function). When choosing this parameter, the user should keep in mind the following remarks:&lt;br /&gt;
&lt;br /&gt;
#if max check interval is smaller than the integration step, the execution time increases if the max check interval decreases (the events detection is more accurate);&lt;br /&gt;
#if max check interval is bigger than the max integration step, it will be replaced by the max integration step during the events detection process; in this case the max check interval is a useless parameter that will never be used by the propagator.&lt;br /&gt;
&lt;br /&gt;
In general, the user should always choose the max check interval value as a function of the integration step used during propagation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of the event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation start date, i.e if g() equal to zero, the event is processed. This case is extremely rare. Note that in some case however, due to numerical quality rounds-off, an event may not be detected at the propagation start date although it&#039;s theoritically supposed to occur. For example, starting propagation at periapsis with a periapsis detector may not detect periapsis since the g() function of PeriapsisDetector is based on position- velocity scalar product and due to rounds-off errors, its values may be around 1E-7 which is not exactly zero. &amp;lt;br&amp;gt;&lt;br /&gt;
Also, if at the propagation start date the g() function is not continuous but changes its sign (for example value-1 before event date, value 1 after), the event will also not be detected since the g() function value is not zero.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Ephemeris propagator event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one. Consequently, when propagating with a bounded propagator, if the last substep is larger than the real one then the real end date is exceeded, raising an exception. Therefore, in this case, it is recommended to &#039;&#039;&#039;propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the same date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are processed is the order in which they are added to the propagator. If the detected event stops the propagation, the other events occuring at the same date are not processed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the end date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation end date, the event is not processed.&lt;br /&gt;
&lt;br /&gt;
==== Available event detectors ====&lt;br /&gt;
Mono events detectors detect events applied on a specific state. These detectors can be used in mono or multi propagation case.&lt;br /&gt;
&lt;br /&gt;
The available mono events detectors are presented in specific pages: &lt;br /&gt;
&lt;br /&gt;
* [MIS_ORB_Home Orbit determination events]&lt;br /&gt;
* [MIS_SENSORS_Home Sensors events]&lt;br /&gt;
* [MIS_STASAT_Home Ground stations and satellites events]&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
It also exists multi events detectors applied on several states. These detectors can only be used in multi propagation case.&lt;br /&gt;
Notice that some detectors that implies several satellite coul be used in multi or mono satellite context ; ([{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/sensor/SatToSatMutualVisibilityDetector.html SatToSatMutualVisibilityDetector], [{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/ThreeBodiesAngleDetector.html ThreeBodiesAngleDetector] or [{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/ExtremaThreeBodiesAngleDetector.html ExtremaThreeBodiesAngleDetector])&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HMultiEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
The [{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector] is a detector that detects the nth occurrence of an underlying event detector.&amp;lt;br&amp;gt;&lt;br /&gt;
However the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every event of the underlying detector. As a result, the behaviour of this detector is the following:&lt;br /&gt;
* Before and after the nth occurrence, the eventOccurred() method returns &amp;lt;code&amp;gt;Action.CONTINUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
* At the nth occurrence, the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method returns the user-provided action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Warning&#039;&#039;&#039;&#039;&#039;: the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every occurrence of the underlying detector, not only at nth occurrence. Hence, overloading this detector should be performed carefully: in the overloaded &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method, the check &amp;lt;code&amp;gt;getCurrentOccurence() == getOccurence()&amp;lt;/code&amp;gt; should be performed first to ensure we are at nth occurrence before calling &amp;lt;code&amp;gt;super.eventOccurred()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== IntervalOccurenceDetector ====&lt;br /&gt;
This [{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurenceDetector.html IntervalOccurenceDetector ] is able for any EventDetector. It detects the &amp;lt;math&amp;gt;n^{th}&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;m^{th}&amp;lt;/math&amp;gt; event occurences by step of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; occurences. &lt;br /&gt;
Otherwise, if j event occurence, the &amp;lt;code&amp;gt;IntervalOccurenceDetector&amp;lt;/code&amp;gt; detects events as : &lt;br /&gt;
* &amp;lt;math&amp;gt;(j - n) % p = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n &amp;lt;= j &amp;lt;= m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The g switching function is the function of the event to detect.&lt;br /&gt;
&lt;br /&gt;
==== ExtremaGenericDetector ====&lt;br /&gt;
&lt;br /&gt;
This class represents an event detector that detects the derivative cancellation of an underlying detector. Using this detector recursively will allow to detect nth order derivative.&lt;br /&gt;
&lt;br /&gt;
The g switching function cancels for any extrema of the g function of the underlying detector.&lt;br /&gt;
Min, max or both at the same time.&lt;br /&gt;
&lt;br /&gt;
==== Mono Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
When a numerical propagation is performed, the event detection is done at the math level since the integration is realized by one of the numerical integrators. However, the event detectors are instanciated by the user at the Patrius level. Hence the necessity of an adapter to wrap a Patrius event detector object into a math event handler object whose interfaces provide basically the same kind of services. Once the event detectors are given to the numerical propagator, they are transformed into event handlers in order to give them to the math numerical integrator.&amp;lt;br&amp;gt;&lt;br /&gt;
The numerical integrator associates each event with another object which represents its state during the integration. At the end of each step, the method acceptStep() is systematically called and performs the event detection thanks to an interpolator, inside the current step. Thus the state of each event is updated. If an event is detected therefore the integration is either stopped or continued with or without state or derivative state resetting. It is also possible to remove the detector after the first event detection and the propagation is continued. An event is represented by a function, the function &amp;quot;g()&amp;quot;: the event occurs when the function sign changes and NOT when this function equals to zero. To find this root, in addition to the interpolator, a solver is used. By default, this solver is the Brent solver. The exception being at the beginning of the propagation where events are detected when the g() function equals exactly zero.&lt;br /&gt;
&lt;br /&gt;
===== Analytical propagator =====&lt;br /&gt;
&lt;br /&gt;
When an analytical propagation is performed, the event detection is done at the Patrius level directly. The process is basically the same than its math counterpart: the detectors are given to the propagator and associated to their states. The Patrius propagator has a method acceptStep() which is similar to the one of the math package.&lt;br /&gt;
&lt;br /&gt;
===== Ephemeris propagator =====&lt;br /&gt;
&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one which could be knotty when it comes to propagate with a bounded propagator. Indeed, if the last substep is larger than the real one then the real end date is exceeded. If the end date is equal to the ephemeris max date, an exception is raised when the interpolator sets the current date to a date exceeding the ephemeris max date. Therefore, in this case, &#039;&#039;&#039;it is recommended to propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Multi Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
The event detector process for multi satellite numerical propagation is equivalent to the process performed with single satellite numerical propagation. The multi event detection is wrapped into a math event handler object. The detector could be applied on a single satellite or on several satellites.&lt;br /&gt;
&lt;br /&gt;
=== Coded events and phenomena ===&lt;br /&gt;
==== Mono propagation ====&lt;br /&gt;
===== The coded event =====&lt;br /&gt;
&lt;br /&gt;
Patrius does detect events. This means :&lt;br /&gt;
&lt;br /&gt;
* Patrius triggers a method call on the corresponding EventDetector when the event occurs.&lt;br /&gt;
* Patrius logs the SpacecraftState and g function slope sign for the occuring event (through the EventsLogger).&lt;br /&gt;
&lt;br /&gt;
But this mechanism alone doesn&#039;t provide a programmatic representation for an &amp;quot;event&amp;quot;, which may be processed after the propagation.&lt;br /&gt;
&lt;br /&gt;
A new way of handling events as individual instances was thus designed : the &amp;quot;atomic event&amp;quot; or &amp;quot;coded event&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;coded event&amp;quot; has the following attributes :&lt;br /&gt;
&lt;br /&gt;
* an event &amp;quot;code&amp;quot; : a String identifying the category of the event, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* an event &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* an AbsoluteDate : the date at which the event occurred.&lt;br /&gt;
* a boolean, true when the event represents a &amp;quot;starting&amp;quot; event, or false when it represents an &amp;quot;ending&amp;quot; event (relative to a phenomenon, see below).&lt;br /&gt;
&lt;br /&gt;
The code and comment formats are free, they depend on the CodingEventDetector implementation (see below).&lt;br /&gt;
&lt;br /&gt;
A CodedEvent is supposed to be built by the CodedEventsLogger (see below).&lt;br /&gt;
&lt;br /&gt;
Moreover, when one of the boundaries of the phenomenon is ill-defined (e.g. unknown due to computational limits), it is an instance of CodedEvent, with the code &amp;quot;UNDEFINED_EVENT&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== The CodingEventDetector and MultiCodingEventDetector =====&lt;br /&gt;
&lt;br /&gt;
The CodingEventDetector (or MultiCodingEventDetector in MultiPropagator case) is an extension of the EventDetector type(respectively MultiEventDetector). A CodingEventDetector (or MultiCodingEventDetector) has the following requirements :&lt;br /&gt;
&lt;br /&gt;
* Providing a CodedEvent builder method, that creates a CodedEvent instance appropriate for the event (this is how the code and comment are determined).&lt;br /&gt;
* Providing a Phenomenon code if a Phenomenon makes sense in the context of the event, otherwise return null (see below).&lt;br /&gt;
* Providing a boolean telling which sign of the g() method means the Phenomenon is active (see below).&lt;br /&gt;
&lt;br /&gt;
===== The phenomenon =====&lt;br /&gt;
&lt;br /&gt;
The EventDetector provides a g() method whose sign change triggers an event. Sometimes the g() method can also be seen as conveying a &amp;quot;state&amp;quot; i.e. when g() is positive (resp. negative), a &amp;quot;phenomenon&amp;quot; is going on.&lt;br /&gt;
The clearest example would be the EclipseDetector :&lt;br /&gt;
&lt;br /&gt;
* g() going from positive to negative means that the spacecraft has entered the eclipse zone.&lt;br /&gt;
* g() going from negative to positive means that the spacecraft has exited the eclipse zone.&lt;br /&gt;
&lt;br /&gt;
The associated phenomenon would then be called &amp;quot;inside the eclipse zone&amp;quot;, bounded by the starting event &amp;quot;enter eclipse zone&amp;quot; and the ending event &amp;quot;exit eclipse zone&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This library provides a &amp;quot;phenomenon&amp;quot; abstraction, as a lightweight representation.&lt;br /&gt;
&lt;br /&gt;
A Phenomenon instance is an immutable object with the following attributes :&lt;br /&gt;
&lt;br /&gt;
* a phenomenon &amp;quot;code&amp;quot; : a String identifying the category of the phenomenon, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* a phenomenon &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* two &amp;quot;coded event&amp;quot; instances : the atomic events that represent the start and the end of the phenomenon.&lt;br /&gt;
&lt;br /&gt;
Also :&lt;br /&gt;
* it tells whether the start and end are &amp;quot;well-defined&amp;quot; : a well-defined boundary has a real event backing it. A not well-defined boundary is a boundary because of computational limits : it happens when, during a propagation, the ending event occurs, but the starting event did not (or, the opposite) because it was outside the boundaries of the propagation. In this case, an &amp;quot;UNDEFINED_EVENT&amp;quot; is given as the missing boundary (see above).&lt;br /&gt;
&lt;br /&gt;
A Phenomenon is built by the CodedEventsLogger, when the CodingEventDetector provides a non-null Phenomenon string code. The existence of this code proves the Phenomenon makes senses in the context of the CodingEventDetector. For instance :&lt;br /&gt;
&lt;br /&gt;
* for a &amp;quot;CodingEclipseDetector&amp;quot; built upon the EclipseDetector, a Phenomenon has meaning (the Phenomenon being &amp;quot;inside the eclipse&amp;quot;).&lt;br /&gt;
* for a &amp;quot;CodingApsideDetector&amp;quot; built upen the ApsideDetector, a Phenomenon has no meaning, since the events are : &amp;quot;the spacecraft is at the periapsis&amp;quot; and &amp;quot;the spacecraft is at the apoapsis&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Multi propagation ====&lt;br /&gt;
The same process exists. The corresponding classes are localized in the Patrius library.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting up a CodedEventsLogger or a MultiCodedEventsLogger ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent and Phenomenon instances are not meant to be produced by the CodingEventDetectors (or directly MultiCodedEventsLogger in MultiPropagator case) (but it could be possible if needed).&lt;br /&gt;
&lt;br /&gt;
Instead, the (Multi)CodedEventsLogger was created for this purpose.&lt;br /&gt;
&lt;br /&gt;
At first glance, a (Multi)CodedEventsLogger instance is very similar to the (Multi)EventsLogger.&lt;br /&gt;
The main difference is that the (Multi)EventsLogger instances have no inner representation of events, while the (Multi)CodedEventsLogger produces CodedEvent and Phenomenon lists.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how one uses the (Multi)CodedEventsLogger :&lt;br /&gt;
&lt;br /&gt;
* create a (Multi)CodedEventsLogger instance.&lt;br /&gt;
* create at least one (Multi)CodingEventProvider instance.&lt;br /&gt;
* call the &amp;lt;code&amp;gt;monitorDetector()&amp;lt;/code&amp;gt; method on the (Multi)CodedEventsLogger : it produces a &amp;quot;wrapper&amp;quot; of the (Multi)CodingEventProvider exposed as a regular EventProvider.&lt;br /&gt;
* pass this &amp;quot;wrapper&amp;quot; to a propagator (any kind works : those who do compute a propagation and those who replay an ephemeris).&lt;br /&gt;
* run the propagator.&lt;br /&gt;
&lt;br /&gt;
While the propagator runs, the &amp;quot;wrapper&amp;quot; calls both the (Multi)CodingEventProvider instance and the (Multi)CodedEventsLogger on each event. The (Multi)CodedEventsLogger instance uses the (Multi)CodingEventProvider to build and store all CodedEvent instances during the propagation.&lt;br /&gt;
&lt;br /&gt;
==== Getting the full coded events list ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;getCodedEventsList()&amp;lt;/code&amp;gt;.&lt;br /&gt;
It provides a list of all CodedEvents (for all the CodingEventDetectors passed to the propagator, without distinction).&lt;br /&gt;
&lt;br /&gt;
==== Getting the events list per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildCodedEventListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a CodedEventsList as value, this list only containing the events generated from the key.&amp;lt;br&amp;gt;&lt;br /&gt;
It is, therfore, the same data as the full events&#039; list, but rearranged per CodingEventProvider instance.&lt;br /&gt;
&lt;br /&gt;
==== Getting the phenomena per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildPhenomenaListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a PhenomenaList as value, this list only containing the Phenomenon instances generated from the key. The(Multi) CodingEventProvider instance provides the Phenomenon code.&lt;br /&gt;
&lt;br /&gt;
The (Multi)CodedEventsLogger only uses the (Multi)CodingEventProvider instances that provide a non-null Phenomenon code (null indicates that a Phenomenon has no meaning for this detector).&lt;br /&gt;
&lt;br /&gt;
==== N-th occurrence of a coded event, or a delayed event ====&lt;br /&gt;
&lt;br /&gt;
There are two ways to generate the n-th occurrence of an event or a delayed coded event from a detected event: the first one is using the post-processing classes, and the second one is to configure the CodingEventDetector in order to create the delayed or filtered coded events during the propagation (in addition to the &amp;quot;standard&amp;quot; coded events).&lt;br /&gt;
While the former can only be done after the propagation, the latter has to be set before the propagation and is possible thanks to the following methods in the class CodingEventDetector:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buildCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the standard CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildDelayedCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the delayed CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildOccurrenceCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the n-th occurrence CodedEvent (n will be a parameter chosen by the user)&lt;br /&gt;
&lt;br /&gt;
In order to use this feature, the delay value and/or the occurrence number must be given as input parameters of the constructor of the class implementing the CodingEventDetector class (for instance GenericCodingEventDetector). The CodedEventsLogger will then be able to read these parameters and handle the generation of standard and not-standard coded events.&lt;br /&gt;
&lt;br /&gt;
Note, in the GenericCodingEventDetector constructor (EventDetector, String, String, boolean, String, double, int), if both parameters delayIn and occurrenceIn are other than 0, the event is saved as a delayed event, not a &amp;quot;Nth occurence of&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== When to use Coded events and phenomena ===&lt;br /&gt;
* To build easier time lines of events&lt;br /&gt;
* To manipulate easier phenomena (for example between &amp;quot;starting&amp;quot; and &amp;quot;ending&amp;quot; events) and associate to them specific computations (for example the evolution of the illumination during an eclipse)&lt;br /&gt;
* To apply some [MIS_POSTP_Home post-processing filters]&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Using available events detectors ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
Example of propagation stopping at 3rd detected node with event detector overloading:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Initialization&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2003, 1, 1, TimeScalesFactory.getTAI());&lt;br /&gt;
final Orbit orbit = new KeplerianOrbit(7000000, 0.01, 0.1, 0.2, 0.3, 0.4, PositionAngle.TRUE, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
&lt;br /&gt;
// Node detector&lt;br /&gt;
final EventDetector nodeDetector = new NodeDetector(orbit, FramesFactory.getGCRF(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
// Stop at 3rd detected node&lt;br /&gt;
final NthOccurrenceDetector nthOccurrenceDetector = new NthOccurrenceDetector(nodeDetector, 3, Action.STOP) {&lt;br /&gt;
    @Override&lt;br /&gt;
    public Action eventOccurred(SpacecraftState s, boolean increasing, boolean forward) throws PatriusException {&lt;br /&gt;
        super.eventOccurred(s, increasing, forward);&lt;br /&gt;
        if (getCurrentOccurence() == getOccurence()) {&lt;br /&gt;
            return Action.STOP;&lt;br /&gt;
        } else {&lt;br /&gt;
            return Action.CONTINUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Propagation&lt;br /&gt;
final KeplerianPropagator propagator = new KeplerianPropagator(orbit);&lt;br /&gt;
propagator.addEventDetector(nthOccurrenceDetector);&lt;br /&gt;
propagator.propagate(orbit.getDate().shiftedBy(86400.));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generating coded events and phenomena ===&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent instances and Phenomenon instances are meant to be produced using :&amp;lt;br&amp;gt;&lt;br /&gt;
- CodingEventDetector implementations that provide information about events and phenomena,&amp;lt;br&amp;gt;&lt;br /&gt;
- a CodingEventsLogger, that uses the CodingEventDetector instances to build the events and phenomena.&lt;br /&gt;
&lt;br /&gt;
For example, if we want to create a list of CodedEvent objects using a detector of nodes (ascending and descending orbital nodes):&lt;br /&gt;
&lt;br /&gt;
1. Create a new EventDetector (in this case a NodeDetector):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set up the node detector:&lt;br /&gt;
  AbsoluteDate date = new AbsoluteDate(&amp;quot;2000-01-01T12:00:00Z&amp;quot;, TimeScalesFactory.getTT());&lt;br /&gt;
  AbsoluteDate dateF = date.shiftedBy(2* period);&lt;br /&gt;
  Orbit orbit = new KeplerianOrbit(7e6, 0, 0.2, 0, 0, 0.2, PositionAngle.MEAN, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
  NodeDetector node = new NodeDetector(orbit, FramesFactory.getEME2000(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Create a new generic coding event detector:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // standard event&lt;br /&gt;
  GenericCodingEventDetector nodeDet =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;);&lt;br /&gt;
  // third occurence of event&lt;br /&gt;
  GenericCodingEventDetector nodeDetOcc =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 0., 3);&lt;br /&gt;
  // delayed event (10 seconds here)&lt;br /&gt;
  GenericCodingEventDetector nodeDetDel =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 10., 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Create a new CodedEventsLogger and use the &amp;lt;code&amp;gt; monitorDetector &amp;lt;/code&amp;gt; function on the new CodedEventsLogger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  CodedEventsLogger logger = new CodedEventsLogger();&lt;br /&gt;
  // Create an EventDetector object so that event detection functions could be used:&lt;br /&gt;
  EventDetector d = logger.monitorDetector(nodeDet);&lt;br /&gt;
  EventDetector dOcc = logger.monitorDetector(nodeDetOcc);&lt;br /&gt;
  EventDetector dDel = logger.monitorDetector(nodeDetDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Add the EventDetector to the propagator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  propagator.addEventDetector(d);&lt;br /&gt;
  propagator.addEventDetector(dOcc);&lt;br /&gt;
  propagator.addEventDetector(dDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Start the propagation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set the propagator:&lt;br /&gt;
  propagator.setEphemerisMode();&lt;br /&gt;
  propagator.resetInitialState(new SpacecraftState(orbit));&lt;br /&gt;
  // Propagate:&lt;br /&gt;
  propagator.propagate(date0, dateF);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Combination of boolean phenomena ===&lt;br /&gt;
Sometimes an event (a zero of a g function) can be seen as a begin (passing zero from positive to negative or invert) or a end ( other way ) of a phenomena. For example the eclipse event can be the begin (detected when g function goes from positive to negative) or the end (when g function goes from negative to positive) of an eclipse. (cf. [MIS_ORB_Home#HEclipseDetectorandGenericEclipseDetector Eclipse detector].)&lt;br /&gt;
&lt;br /&gt;
One can choose to create an event as a combination of these phenomena, for example a station visibility outside an interference period. In this case a user can create a detector as a combination of existing detectors.&lt;br /&gt;
&lt;br /&gt;
The user simply has to provide the following parameters :&lt;br /&gt;
#First detector and the way to use it (g is positive or negative during the phenomena to combine)&lt;br /&gt;
#Second detector and the way to use it &lt;br /&gt;
#How to combine the phenomenom : both are during phenomena (will be detected as the minimum of the two g function) or at least one (will be detected as the maximum of the two g function) is during phenomena &lt;br /&gt;
&lt;br /&gt;
Once a new detector have been created in this way, it is possible to combine it with another one and so on.&lt;br /&gt;
&lt;br /&gt;
For example the [MIS_SENSORS_Home#HCentralBodyMaskCircularFOVDetector CentralBodyMaskCircularFOVDetector] detects when a target is in a circular field of view and outside of an eclipse, that is translated by :&lt;br /&gt;
&lt;br /&gt;
* Outside of eclipse : when EllipsoidEclipseDetecor g function is positive &lt;br /&gt;
* Inside circular field of view : when CircularFieldOfView g function is positive&lt;br /&gt;
&lt;br /&gt;
So the following code example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// EclipseDetector&lt;br /&gt;
final EclipseDetector eed = new EclipseDetector(targetPVP, targetRadius, spheroEarth, 1., MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// CircularFOVDetector&lt;br /&gt;
final CircularFieldOfViewDetector cfvd = new CircularFieldOfViewDetector(targetPVP, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CombinedPhenomenaDetector cbmcfovd2 = new CombinedPhenomenaDetector(eed, true, cfvd, true, true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is equivalent to CentralBodyMaskCircularFOVDetector :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CentralBodyMaskCircularFOVDetector cbmcfovd = &lt;br /&gt;
new CentralBodyMaskCircularFOVDetector(targetPVP, targetRadius, spheroEarth, false, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
==== Interfaces events detection ====&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.9}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/CodingEventDetector.html CodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiEventDetector&lt;br /&gt;
|This interface represents an event finder in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
==== Classes containing the general functions to detect events ====&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;
| AbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/AbstractDetector.html AbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiAbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiAbstractDetector.html MultiAbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedEventDetector&lt;br /&gt;
|This class adapts Patrius event detectors to math EventHandler object.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/AdaptedEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMonoEventDetector&lt;br /&gt;
|This class adapts Patrius mono event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMonoEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMultiEventDetector&lt;br /&gt;
|This class adapts Patrius multi event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMultiEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CombinedPhenomenaDetector&lt;br /&gt;
|This class handles events representing the combination of two boolean phenomena.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/CombinedPhenomenaDetector.html CombinedPhenomenaDetector]&lt;br /&gt;
|-&lt;br /&gt;
| NthOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a certain occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| IntervalOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a interval occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurrenceDetector.html IntervalOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| ExtremaGenericDetector&lt;br /&gt;
|This class represents an event detector that detects the derivative cancellation of an underlying detector.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/propagation/events/ExtremaGenericDetector.html ExtremaGenericDetector]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Classes for the generation of lists of events and phenomena ====&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;
| CodedEvent&lt;br /&gt;
|This class implements coded events (a light and simple representation of events as generated by Patrius event detectors ).&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/CodedEvent.html CodedEvent]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/CodedEventsList.html CodedEventsList]&lt;br /&gt;
|-&lt;br /&gt;
| Phenomenon&lt;br /&gt;
|This class implements the notion of a phenomenon : a state defined by a starting event and an ending event.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/Phenomenon.html Phenomenon]&lt;br /&gt;
|-&lt;br /&gt;
| PhenomenaList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/PhenomenaList.html PhenomenaList]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/CodedEventsLogger.html CodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| GenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/GenericCodingEventDetector.html GenericCodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiGenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface in multi propagation case, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.9}}/fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.9_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.8_Events_detection:_Presentation&amp;diff=3611</id>
		<title>User Manual 4.8 Events detection: Presentation</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.8_Events_detection:_Presentation&amp;diff=3611"/>
		<updated>2023-12-19T16:19:11Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes :&lt;br /&gt;
&lt;br /&gt;
* in a mono satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions that extend  event detection mechanism.&lt;br /&gt;
* in a multi satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions, copied from the mono satellite mechanism, that extend Patrius&#039;s event detection mechanism for multi satellite propagation.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The following packages are related to events detections in mono and multi propagation context:&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.8}}/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.8}}/fr/cnes/sirius/patrius/math/ode/events/package-summary.html Package fr.cnes.sirius.patrius.math.ode.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/package-summary.html Package fr.cnes.sirius.patrius.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/multi/package-summary.html Package fr.cnes.sirius.patrius.propagation.events.multi]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as 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 architecture of the events detection for mono and multi satellite propagation:&lt;br /&gt;
&lt;br /&gt;
[[File:EventsV3.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following diagram represents the mechanism used in the Patrius library in order to create the list of the events detected during the mono satellite propagation as well as the phenomena list :&lt;br /&gt;
&lt;br /&gt;
[[File:Events.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following classes are duplicated from mono satellite context in order to create a list of events detected : &lt;br /&gt;
* [{{JavaDoc4.8}}//fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.8}}//fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
* [{{JavaDoc4.8}}//fr/cnes/sirius/patrius/events/multi/MultiEventsLogger.html MultiEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.8}}//fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Event detection ===&lt;br /&gt;
&lt;br /&gt;
The events detection process can be used during mono or multi propagation propagation, when we need to know if some events occur and at what time (for instance when the satellite will be in eclipse, or if at a given date it will be visible or not from a ground station).&lt;br /&gt;
&lt;br /&gt;
In Patrius there is one class for every kind of event: the information related to an event is contained in this class, and it will be used by the mono satellite numerical or analytical propagator when extrapolating the orbit. The mechanism is similar for multi propagation.&lt;br /&gt;
&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are detected is the order in which they are added to the propagator.&lt;br /&gt;
&lt;br /&gt;
As of PATRIUS 4.5, detectors can optionally take into account signal propagation delay. Javadoc of each event detector indicates if signal propagation delay can be taken into account through a setter &amp;lt;code&amp;gt;setPropagationDelayType()&amp;lt;/code&amp;gt;. Delay type is of 2 types:&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.INSTANTANEOUS&amp;lt;/code&amp;gt;: signal propagation delay is not taken into account&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.LIGHT_SPEED&amp;lt;/code&amp;gt;: signal propagation delay is taken into account.&lt;br /&gt;
Signal propagation delay allows to detect events as it is exactly seen by a spacecraft, for instance a visibility between a satellite and a station.&lt;br /&gt;
All detectors involving a signal propagation and or sensors can take signal propagation delay into account (BetaAngleDetector, SensorVisibilityDetector, TargetInFieldOfViewDetector, etc.):&lt;br /&gt;
&lt;br /&gt;
By default signal propagation delay is not taken into account.&lt;br /&gt;
&lt;br /&gt;
A new detector class should implements  : &lt;br /&gt;
* [{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector interface] in case of [{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/Propagator.html mono satellite propagation] or [{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
* [{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector interface] in case of [{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Construction of a detector&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The action performed at event detection can be set by user at detector&#039;s construction. Several actions can be defined if several behavior are available (depending on state and/or on increasing/forward parameter). It is possible to specify at construction if the detector should be removed after event detection and thus not be detected any more. If a single action is available, a single boolean has to be provided by the user at construction. In the case where several actions are available, the same number of boolean has to be provided to determine if the detector has to be removed after event detection.&amp;lt;br&amp;gt;&lt;br /&gt;
Focusing on the &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt; for instance, two actions are possible at event detection :&lt;br /&gt;
&lt;br /&gt;
- action_at_ascending_node if an ascending node detection is done&amp;lt;br&amp;gt;&lt;br /&gt;
- action_at_descending_node if a descending node detection is performed&lt;br /&gt;
&lt;br /&gt;
If no actions are set, the user should be aware of the default implementation.&lt;br /&gt;
By default, event detectors are never removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of eventOccurred()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The returned action of the function eventOccurred could be set by user or defined by default.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function eventOccurred is common to all [{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector] classes (respectively [{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]) and its purpose is to handle an event and to choose what to do next ; this method is called when the integrator has accepted a step ending exactly on a sign change of the switching function, and it allows the user to choose which action will take place after the event (the simulation could be stopped, the propagator could reset its initial state or its initial derivative state ...).&lt;br /&gt;
Plus, this method is up to determine if the detector used has to be removed after the event detection : in the above example of &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt;, the action taking place after the event is set to action_at_raising_node in the case of an ascending node detection. If one has decided to remove the detector at such detection, the attribute shouldBeRemoved will be set to remove_at_ascending_node which is true by construction, the case of descending node is similar.&lt;br /&gt;
&lt;br /&gt;
Since the default implementation of eventOccurred could unfit the user needs in terms of propagation behaviour, it is recommended to check the content of the detector before using them and to change it if necessary by using a specific constructor which take as parameter the expected action(s).&lt;br /&gt;
&lt;br /&gt;
Note that the implementation of eventOccured must not contain any action. Even if the action does not impact the state vector, the action should be implemented in the resetState method.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of resetState() or resetStates()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If the event have an action, this action should be implemented in the resetState() method. In this case, the eventOccured() of the detector concerned should return a RESET_STATE action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Convergence threshold parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The convergence threshold represents the events detection precision; the following observations can help the user when choosing a value for this parameter:&lt;br /&gt;
&lt;br /&gt;
#if the convergence threshold increases, the execution time decreases (the precision becomes worst);&lt;br /&gt;
#if the convergence threshold is bigger than the max integration step, the events detection will fail.&lt;br /&gt;
&lt;br /&gt;
If the resetState(s) could modify others event detectors, the convergence threshold should be low in order to avoid any unpredictable behavior.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Max check interval parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The max check interval parameter represents the maximum interval in which the propagator checks for an event (i.e. for a sign change of the g switching function). When choosing this parameter, the user should keep in mind the following remarks:&lt;br /&gt;
&lt;br /&gt;
#if max check interval is smaller than the integration step, the execution time increases if the max check interval decreases (the events detection is more accurate);&lt;br /&gt;
#if max check interval is bigger than the max integration step, it will be replaced by the max integration step during the events detection process; in this case the max check interval is a useless parameter that will never be used by the propagator.&lt;br /&gt;
&lt;br /&gt;
In general, the user should always choose the max check interval value as a function of the integration step used during propagation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of the event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation start date, i.e if g() equal to zero, the event is processed. This case is extremely rare. Note that in some case however, due to numerical quality rounds-off, an event may not be detected at the propagation start date although it&#039;s theoritically supposed to occur. For example, starting propagation at periapsis with a periapsis detector may not detect periapsis since the g() function of PeriapsisDetector is based on position- velocity scalar product and due to rounds-off errors, its values may be around 1E-7 which is not exactly zero. &amp;lt;br&amp;gt;&lt;br /&gt;
Also, if at the propagation start date the g() function is not continuous but changes its sign (for example value-1 before event date, value 1 after), the event will also not be detected since the g() function value is not zero.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Ephemeris propagator event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one. Consequently, when propagating with a bounded propagator, if the last substep is larger than the real one then the real end date is exceeded, raising an exception. Therefore, in this case, it is recommended to &#039;&#039;&#039;propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the same date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are processed is the order in which they are added to the propagator. If the detected event stops the propagation, the other events occuring at the same date are not processed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the end date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation end date, the event is not processed.&lt;br /&gt;
&lt;br /&gt;
==== Available event detectors ====&lt;br /&gt;
Mono events detectors detect events applied on a specific state. These detectors can be used in mono or multi propagation case.&lt;br /&gt;
&lt;br /&gt;
The available mono events detectors are presented in specific pages: &lt;br /&gt;
&lt;br /&gt;
* [MIS_ORB_Home Orbit determination events]&lt;br /&gt;
* [MIS_SENSORS_Home Sensors events]&lt;br /&gt;
* [MIS_STASAT_Home Ground stations and satellites events]&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
It also exists multi events detectors applied on several states. These detectors can only be used in multi propagation case.&lt;br /&gt;
Notice that some detectors that implies several satellite coul be used in multi or mono satellite context ; ([{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/sensor/SatToSatMutualVisibilityDetector.html SatToSatMutualVisibilityDetector], [{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/ThreeBodiesAngleDetector.html ThreeBodiesAngleDetector] or [{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/ExtremaThreeBodiesAngleDetector.html ExtremaThreeBodiesAngleDetector])&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HMultiEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
The [{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector] is a detector that detects the nth occurrence of an underlying event detector.&amp;lt;br&amp;gt;&lt;br /&gt;
However the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every event of the underlying detector. As a result, the behaviour of this detector is the following:&lt;br /&gt;
* Before and after the nth occurrence, the eventOccurred() method returns &amp;lt;code&amp;gt;Action.CONTINUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
* At the nth occurrence, the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method returns the user-provided action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Warning&#039;&#039;&#039;&#039;&#039;: the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every occurrence of the underlying detector, not only at nth occurrence. Hence, overloading this detector should be performed carefully: in the overloaded &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method, the check &amp;lt;code&amp;gt;getCurrentOccurence() == getOccurence()&amp;lt;/code&amp;gt; should be performed first to ensure we are at nth occurrence before calling &amp;lt;code&amp;gt;super.eventOccurred()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== IntervalOccurenceDetector ====&lt;br /&gt;
This [{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurenceDetector.html IntervalOccurenceDetector ] is able for any EventDetector. It detects the &amp;lt;math&amp;gt;n^{th}&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;m^{th}&amp;lt;/math&amp;gt; event occurences by step of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; occurences. &lt;br /&gt;
Otherwise, if j event occurence, the &amp;lt;code&amp;gt;IntervalOccurenceDetector&amp;lt;/code&amp;gt; detects events as : &lt;br /&gt;
* &amp;lt;math&amp;gt;(j - n) % p = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n &amp;lt;= j &amp;lt;= m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The g switching function is the function of the event to detect.&lt;br /&gt;
&lt;br /&gt;
==== Mono Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
When a numerical propagation is performed, the event detection is done at the math level since the integration is realized by one of the numerical integrators. However, the event detectors are instanciated by the user at the Patrius level. Hence the necessity of an adapter to wrap a Patrius event detector object into a math event handler object whose interfaces provide basically the same kind of services. Once the event detectors are given to the numerical propagator, they are transformed into event handlers in order to give them to the math numerical integrator.&amp;lt;br&amp;gt;&lt;br /&gt;
The numerical integrator associates each event with another object which represents its state during the integration. At the end of each step, the method acceptStep() is systematically called and performs the event detection thanks to an interpolator, inside the current step. Thus the state of each event is updated. If an event is detected therefore the integration is either stopped or continued with or without state or derivative state resetting. It is also possible to remove the detector after the first event detection and the propagation is continued. An event is represented by a function, the function &amp;quot;g()&amp;quot;: the event occurs when the function sign changes and NOT when this function equals to zero. To find this root, in addition to the interpolator, a solver is used. By default, this solver is the Brent solver. The exception being at the beginning of the propagation where events are detected when the g() function equals exactly zero.&lt;br /&gt;
&lt;br /&gt;
===== Analytical propagator =====&lt;br /&gt;
&lt;br /&gt;
When an analytical propagation is performed, the event detection is done at the Patrius level directly. The process is basically the same than its math counterpart: the detectors are given to the propagator and associated to their states. The Patrius propagator has a method acceptStep() which is similar to the one of the math package.&lt;br /&gt;
&lt;br /&gt;
===== Ephemeris propagator =====&lt;br /&gt;
&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one which could be knotty when it comes to propagate with a bounded propagator. Indeed, if the last substep is larger than the real one then the real end date is exceeded. If the end date is equal to the ephemeris max date, an exception is raised when the interpolator sets the current date to a date exceeding the ephemeris max date. Therefore, in this case, &#039;&#039;&#039;it is recommended to propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Multi Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
The event detector process for multi satellite numerical propagation is equivalent to the process performed with single satellite numerical propagation. The multi event detection is wrapped into a math event handler object. The detector could be applied on a single satellite or on several satellites.&lt;br /&gt;
&lt;br /&gt;
=== Coded events and phenomena ===&lt;br /&gt;
==== Mono propagation ====&lt;br /&gt;
===== The coded event =====&lt;br /&gt;
&lt;br /&gt;
Patrius does detect events. This means :&lt;br /&gt;
&lt;br /&gt;
* Patrius triggers a method call on the corresponding EventDetector when the event occurs.&lt;br /&gt;
* Patrius logs the SpacecraftState and g function slope sign for the occuring event (through the EventsLogger).&lt;br /&gt;
&lt;br /&gt;
But this mechanism alone doesn&#039;t provide a programmatic representation for an &amp;quot;event&amp;quot;, which may be processed after the propagation.&lt;br /&gt;
&lt;br /&gt;
A new way of handling events as individual instances was thus designed : the &amp;quot;atomic event&amp;quot; or &amp;quot;coded event&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;coded event&amp;quot; has the following attributes :&lt;br /&gt;
&lt;br /&gt;
* an event &amp;quot;code&amp;quot; : a String identifying the category of the event, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* an event &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* an AbsoluteDate : the date at which the event occurred.&lt;br /&gt;
* a boolean, true when the event represents a &amp;quot;starting&amp;quot; event, or false when it represents an &amp;quot;ending&amp;quot; event (relative to a phenomenon, see below).&lt;br /&gt;
&lt;br /&gt;
The code and comment formats are free, they depend on the CodingEventDetector implementation (see below).&lt;br /&gt;
&lt;br /&gt;
A CodedEvent is supposed to be built by the CodedEventsLogger (see below).&lt;br /&gt;
&lt;br /&gt;
Moreover, when one of the boundaries of the phenomenon is ill-defined (e.g. unknown due to computational limits), it is an instance of CodedEvent, with the code &amp;quot;UNDEFINED_EVENT&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== The CodingEventDetector and MultiCodingEventDetector =====&lt;br /&gt;
&lt;br /&gt;
The CodingEventDetector (or MultiCodingEventDetector in MultiPropagator case) is an extension of the EventDetector type(respectively MultiEventDetector). A CodingEventDetector (or MultiCodingEventDetector) has the following requirements :&lt;br /&gt;
&lt;br /&gt;
* Providing a CodedEvent builder method, that creates a CodedEvent instance appropriate for the event (this is how the code and comment are determined).&lt;br /&gt;
* Providing a Phenomenon code if a Phenomenon makes sense in the context of the event, otherwise return null (see below).&lt;br /&gt;
* Providing a boolean telling which sign of the g() method means the Phenomenon is active (see below).&lt;br /&gt;
&lt;br /&gt;
===== The phenomenon =====&lt;br /&gt;
&lt;br /&gt;
The EventDetector provides a g() method whose sign change triggers an event. Sometimes the g() method can also be seen as conveying a &amp;quot;state&amp;quot; i.e. when g() is positive (resp. negative), a &amp;quot;phenomenon&amp;quot; is going on.&lt;br /&gt;
The clearest example would be the EclipseDetector :&lt;br /&gt;
&lt;br /&gt;
* g() going from positive to negative means that the spacecraft has entered the eclipse zone.&lt;br /&gt;
* g() going from negative to positive means that the spacecraft has exited the eclipse zone.&lt;br /&gt;
&lt;br /&gt;
The associated phenomenon would then be called &amp;quot;inside the eclipse zone&amp;quot;, bounded by the starting event &amp;quot;enter eclipse zone&amp;quot; and the ending event &amp;quot;exit eclipse zone&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This library provides a &amp;quot;phenomenon&amp;quot; abstraction, as a lightweight representation.&lt;br /&gt;
&lt;br /&gt;
A Phenomenon instance is an immutable object with the following attributes :&lt;br /&gt;
&lt;br /&gt;
* a phenomenon &amp;quot;code&amp;quot; : a String identifying the category of the phenomenon, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* a phenomenon &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* two &amp;quot;coded event&amp;quot; instances : the atomic events that represent the start and the end of the phenomenon.&lt;br /&gt;
&lt;br /&gt;
Also :&lt;br /&gt;
* it tells whether the start and end are &amp;quot;well-defined&amp;quot; : a well-defined boundary has a real event backing it. A not well-defined boundary is a boundary because of computational limits : it happens when, during a propagation, the ending event occurs, but the starting event did not (or, the opposite) because it was outside the boundaries of the propagation. In this case, an &amp;quot;UNDEFINED_EVENT&amp;quot; is given as the missing boundary (see above).&lt;br /&gt;
&lt;br /&gt;
A Phenomenon is built by the CodedEventsLogger, when the CodingEventDetector provides a non-null Phenomenon string code. The existence of this code proves the Phenomenon makes senses in the context of the CodingEventDetector. For instance :&lt;br /&gt;
&lt;br /&gt;
* for a &amp;quot;CodingEclipseDetector&amp;quot; built upon the EclipseDetector, a Phenomenon has meaning (the Phenomenon being &amp;quot;inside the eclipse&amp;quot;).&lt;br /&gt;
* for a &amp;quot;CodingApsideDetector&amp;quot; built upen the ApsideDetector, a Phenomenon has no meaning, since the events are : &amp;quot;the spacecraft is at the periapsis&amp;quot; and &amp;quot;the spacecraft is at the apoapsis&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Multi propagation ====&lt;br /&gt;
The same process exists. The corresponding classes are localized in the Patrius library.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting up a CodedEventsLogger or a MultiCodedEventsLogger ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent and Phenomenon instances are not meant to be produced by the CodingEventDetectors (or directly MultiCodedEventsLogger in MultiPropagator case) (but it could be possible if needed).&lt;br /&gt;
&lt;br /&gt;
Instead, the (Multi)CodedEventsLogger was created for this purpose.&lt;br /&gt;
&lt;br /&gt;
At first glance, a (Multi)CodedEventsLogger instance is very similar to the (Multi)EventsLogger.&lt;br /&gt;
The main difference is that the (Multi)EventsLogger instances have no inner representation of events, while the (Multi)CodedEventsLogger produces CodedEvent and Phenomenon lists.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how one uses the (Multi)CodedEventsLogger :&lt;br /&gt;
&lt;br /&gt;
* create a (Multi)CodedEventsLogger instance.&lt;br /&gt;
* create at least one (Multi)CodingEventProvider instance.&lt;br /&gt;
* call the &amp;lt;code&amp;gt;monitorDetector()&amp;lt;/code&amp;gt; method on the (Multi)CodedEventsLogger : it produces a &amp;quot;wrapper&amp;quot; of the (Multi)CodingEventProvider exposed as a regular EventProvider.&lt;br /&gt;
* pass this &amp;quot;wrapper&amp;quot; to a propagator (any kind works : those who do compute a propagation and those who replay an ephemeris).&lt;br /&gt;
* run the propagator.&lt;br /&gt;
&lt;br /&gt;
While the propagator runs, the &amp;quot;wrapper&amp;quot; calls both the (Multi)CodingEventProvider instance and the (Multi)CodedEventsLogger on each event. The (Multi)CodedEventsLogger instance uses the (Multi)CodingEventProvider to build and store all CodedEvent instances during the propagation.&lt;br /&gt;
&lt;br /&gt;
==== Getting the full coded events list ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;getCodedEventsList()&amp;lt;/code&amp;gt;.&lt;br /&gt;
It provides a list of all CodedEvents (for all the CodingEventDetectors passed to the propagator, without distinction).&lt;br /&gt;
&lt;br /&gt;
==== Getting the events list per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildCodedEventListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a CodedEventsList as value, this list only containing the events generated from the key.&amp;lt;br&amp;gt;&lt;br /&gt;
It is, therfore, the same data as the full events&#039; list, but rearranged per CodingEventProvider instance.&lt;br /&gt;
&lt;br /&gt;
==== Getting the phenomena per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildPhenomenaListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a PhenomenaList as value, this list only containing the Phenomenon instances generated from the key. The(Multi) CodingEventProvider instance provides the Phenomenon code.&lt;br /&gt;
&lt;br /&gt;
The (Multi)CodedEventsLogger only uses the (Multi)CodingEventProvider instances that provide a non-null Phenomenon code (null indicates that a Phenomenon has no meaning for this detector).&lt;br /&gt;
&lt;br /&gt;
==== N-th occurrence of a coded event, or a delayed event ====&lt;br /&gt;
&lt;br /&gt;
There are two ways to generate the n-th occurrence of an event or a delayed coded event from a detected event: the first one is using the post-processing classes, and the second one is to configure the CodingEventDetector in order to create the delayed or filtered coded events during the propagation (in addition to the &amp;quot;standard&amp;quot; coded events).&lt;br /&gt;
While the former can only be done after the propagation, the latter has to be set before the propagation and is possible thanks to the following methods in the class CodingEventDetector:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buildCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the standard CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildDelayedCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the delayed CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildOccurrenceCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the n-th occurrence CodedEvent (n will be a parameter chosen by the user)&lt;br /&gt;
&lt;br /&gt;
In order to use this feature, the delay value and/or the occurrence number must be given as input parameters of the constructor of the class implementing the CodingEventDetector class (for instance GenericCodingEventDetector). The CodedEventsLogger will then be able to read these parameters and handle the generation of standard and not-standard coded events.&lt;br /&gt;
&lt;br /&gt;
Note, in the GenericCodingEventDetector constructor (EventDetector, String, String, boolean, String, double, int), if both parameters delayIn and occurrenceIn are other than 0, the event is saved as a delayed event, not a &amp;quot;Nth occurence of&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== When to use Coded events and phenomena ===&lt;br /&gt;
* To build easier time lines of events&lt;br /&gt;
* To manipulate easier phenomena (for example between &amp;quot;starting&amp;quot; and &amp;quot;ending&amp;quot; events) and associate to them specific computations (for example the evolution of the illumination during an eclipse)&lt;br /&gt;
* To apply some [MIS_POSTP_Home post-processing filters]&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Using available events detectors ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
Example of propagation stopping at 3rd detected node with event detector overloading:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Initialization&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2003, 1, 1, TimeScalesFactory.getTAI());&lt;br /&gt;
final Orbit orbit = new KeplerianOrbit(7000000, 0.01, 0.1, 0.2, 0.3, 0.4, PositionAngle.TRUE, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
&lt;br /&gt;
// Node detector&lt;br /&gt;
final EventDetector nodeDetector = new NodeDetector(orbit, FramesFactory.getGCRF(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
// Stop at 3rd detected node&lt;br /&gt;
final NthOccurrenceDetector nthOccurrenceDetector = new NthOccurrenceDetector(nodeDetector, 3, Action.STOP) {&lt;br /&gt;
    @Override&lt;br /&gt;
    public Action eventOccurred(SpacecraftState s, boolean increasing, boolean forward) throws PatriusException {&lt;br /&gt;
        super.eventOccurred(s, increasing, forward);&lt;br /&gt;
        if (getCurrentOccurence() == getOccurence()) {&lt;br /&gt;
            return Action.STOP;&lt;br /&gt;
        } else {&lt;br /&gt;
            return Action.CONTINUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Propagation&lt;br /&gt;
final KeplerianPropagator propagator = new KeplerianPropagator(orbit);&lt;br /&gt;
propagator.addEventDetector(nthOccurrenceDetector);&lt;br /&gt;
propagator.propagate(orbit.getDate().shiftedBy(86400.));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generating coded events and phenomena ===&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent instances and Phenomenon instances are meant to be produced using :&amp;lt;br&amp;gt;&lt;br /&gt;
- CodingEventDetector implementations that provide information about events and phenomena,&amp;lt;br&amp;gt;&lt;br /&gt;
- a CodingEventsLogger, that uses the CodingEventDetector instances to build the events and phenomena.&lt;br /&gt;
&lt;br /&gt;
For example, if we want to create a list of CodedEvent objects using a detector of nodes (ascending and descending orbital nodes):&lt;br /&gt;
&lt;br /&gt;
1. Create a new EventDetector (in this case a NodeDetector):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set up the node detector:&lt;br /&gt;
  AbsoluteDate date = new AbsoluteDate(&amp;quot;2000-01-01T12:00:00Z&amp;quot;, TimeScalesFactory.getTT());&lt;br /&gt;
  AbsoluteDate dateF = date.shiftedBy(2* period);&lt;br /&gt;
  Orbit orbit = new KeplerianOrbit(7e6, 0, 0.2, 0, 0, 0.2, PositionAngle.MEAN, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
  NodeDetector node = new NodeDetector(orbit, FramesFactory.getEME2000(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Create a new generic coding event detector:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // standard event&lt;br /&gt;
  GenericCodingEventDetector nodeDet =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;);&lt;br /&gt;
  // third occurence of event&lt;br /&gt;
  GenericCodingEventDetector nodeDetOcc =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 0., 3);&lt;br /&gt;
  // delayed event (10 seconds here)&lt;br /&gt;
  GenericCodingEventDetector nodeDetDel =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 10., 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Create a new CodedEventsLogger and use the &amp;lt;code&amp;gt; monitorDetector &amp;lt;/code&amp;gt; function on the new CodedEventsLogger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  CodedEventsLogger logger = new CodedEventsLogger();&lt;br /&gt;
  // Create an EventDetector object so that event detection functions could be used:&lt;br /&gt;
  EventDetector d = logger.monitorDetector(nodeDet);&lt;br /&gt;
  EventDetector dOcc = logger.monitorDetector(nodeDetOcc);&lt;br /&gt;
  EventDetector dDel = logger.monitorDetector(nodeDetDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Add the EventDetector to the propagator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  propagator.addEventDetector(d);&lt;br /&gt;
  propagator.addEventDetector(dOcc);&lt;br /&gt;
  propagator.addEventDetector(dDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Start the propagation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set the propagator:&lt;br /&gt;
  propagator.setEphemerisMode();&lt;br /&gt;
  propagator.resetInitialState(new SpacecraftState(orbit));&lt;br /&gt;
  // Propagate:&lt;br /&gt;
  propagator.propagate(date0, dateF);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Combination of boolean phenomena ===&lt;br /&gt;
Sometimes an event (a zero of a g function) can be seen as a begin (passing zero from positive to negative or invert) or a end ( other way ) of a phenomena. For example the eclipse event can be the begin (detected when g function goes from positive to negative) or the end (when g function goes from negative to positive) of an eclipse. (cf. [MIS_ORB_Home#HEclipseDetectorandGenericEclipseDetector Eclipse detector].)&lt;br /&gt;
&lt;br /&gt;
One can choose to create an event as a combination of these phenomena, for example a station visibility outside an interference period. In this case a user can create a detector as a combination of existing detectors.&lt;br /&gt;
&lt;br /&gt;
The user simply has to provide the following parameters :&lt;br /&gt;
#First detector and the way to use it (g is positive or negative during the phenomena to combine)&lt;br /&gt;
#Second detector and the way to use it &lt;br /&gt;
#How to combine the phenomenom : both are during phenomena (will be detected as the minimum of the two g function) or at least one (will be detected as the maximum of the two g function) is during phenomena &lt;br /&gt;
&lt;br /&gt;
Once a new detector have been created in this way, it is possible to combine it with another one and so on.&lt;br /&gt;
&lt;br /&gt;
For example the [MIS_SENSORS_Home#HCentralBodyMaskCircularFOVDetector CentralBodyMaskCircularFOVDetector] detects when a target is in a circular field of view and outside of an eclipse, that is translated by :&lt;br /&gt;
&lt;br /&gt;
* Outside of eclipse : when EllipsoidEclipseDetecor g function is positive &lt;br /&gt;
* Inside circular field of view : when CircularFieldOfView g function is positive&lt;br /&gt;
&lt;br /&gt;
So the following code example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// EclipseDetector&lt;br /&gt;
final EclipseDetector eed = new EclipseDetector(targetPVP, targetRadius, spheroEarth, 1., MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// CircularFOVDetector&lt;br /&gt;
final CircularFieldOfViewDetector cfvd = new CircularFieldOfViewDetector(targetPVP, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CombinedPhenomenaDetector cbmcfovd2 = new CombinedPhenomenaDetector(eed, true, cfvd, true, true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is equivalent to CentralBodyMaskCircularFOVDetector :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CentralBodyMaskCircularFOVDetector cbmcfovd = &lt;br /&gt;
new CentralBodyMaskCircularFOVDetector(targetPVP, targetRadius, spheroEarth, false, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
==== Interfaces events detection ====&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.8}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/CodingEventDetector.html CodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiEventDetector&lt;br /&gt;
|This interface represents an event finder in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
==== Classes containing the general functions to detect events ====&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;
| AbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/AbstractDetector.html AbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiAbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiAbstractDetector.html MultiAbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedEventDetector&lt;br /&gt;
|This class adapts Patrius event detectors to math EventHandler object.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/AdaptedEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMonoEventDetector&lt;br /&gt;
|This class adapts Patrius mono event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMonoEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMultiEventDetector&lt;br /&gt;
|This class adapts Patrius multi event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMultiEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CombinedPhenomenaDetector&lt;br /&gt;
|This class handles events representing the combination of two boolean phenomena.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/CombinedPhenomenaDetector.html CombinedPhenomenaDetector]&lt;br /&gt;
|-&lt;br /&gt;
| NthOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a certain occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| IntervalOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a interval occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurrenceDetector.html IntervalOccurrenceDetector]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Classes for the generation of lists of events and phenomena ====&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;
| CodedEvent&lt;br /&gt;
|This class implements coded events (a light and simple representation of events as generated by Patrius event detectors ).&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/CodedEvent.html CodedEvent]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/CodedEventsList.html CodedEventsList]&lt;br /&gt;
|-&lt;br /&gt;
| Phenomenon&lt;br /&gt;
|This class implements the notion of a phenomenon : a state defined by a starting event and an ending event.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/Phenomenon.html Phenomenon]&lt;br /&gt;
|-&lt;br /&gt;
| PhenomenaList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/PhenomenaList.html PhenomenaList]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/CodedEventsLogger.html CodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| GenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/GenericCodingEventDetector.html GenericCodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiGenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface in multi propagation case, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.8}}/fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.8_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.7_Events_detection:_Presentation&amp;diff=3610</id>
		<title>User Manual 4.7 Events detection: Presentation</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.7_Events_detection:_Presentation&amp;diff=3610"/>
		<updated>2023-12-19T16:18:54Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes :&lt;br /&gt;
&lt;br /&gt;
* in a mono satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions that extend  event detection mechanism.&lt;br /&gt;
* in a multi satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions, copied from the mono satellite mechanism, that extend Patrius&#039;s event detection mechanism for multi satellite propagation.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The following packages are related to events detections in mono and multi propagation context:&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.7}}/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.7}}/fr/cnes/sirius/patrius/math/ode/events/package-summary.html Package fr.cnes.sirius.patrius.math.ode.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/package-summary.html Package fr.cnes.sirius.patrius.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/multi/package-summary.html Package fr.cnes.sirius.patrius.propagation.events.multi]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as 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 architecture of the events detection for mono and multi satellite propagation:&lt;br /&gt;
&lt;br /&gt;
[[File:EventsV3.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following diagram represents the mechanism used in the Patrius library in order to create the list of the events detected during the mono satellite propagation as well as the phenomena list :&lt;br /&gt;
&lt;br /&gt;
[[File:Events.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following classes are duplicated from mono satellite context in order to create a list of events detected : &lt;br /&gt;
* [{{JavaDoc4.7}}//fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.7}}//fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
* [{{JavaDoc4.7}}//fr/cnes/sirius/patrius/events/multi/MultiEventsLogger.html MultiEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.7}}//fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Event detection ===&lt;br /&gt;
&lt;br /&gt;
The events detection process can be used during mono or multi propagation propagation, when we need to know if some events occur and at what time (for instance when the satellite will be in eclipse, or if at a given date it will be visible or not from a ground station).&lt;br /&gt;
&lt;br /&gt;
In Patrius there is one class for every kind of event: the information related to an event is contained in this class, and it will be used by the mono satellite numerical or analytical propagator when extrapolating the orbit. The mechanism is similar for multi propagation.&lt;br /&gt;
&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are detected is the order in which they are added to the propagator.&lt;br /&gt;
&lt;br /&gt;
As of PATRIUS 4.5, detectors can optionally take into account signal propagation delay. Javadoc of each event detector indicates if signal propagation delay can be taken into account through a setter &amp;lt;code&amp;gt;setPropagationDelayType()&amp;lt;/code&amp;gt;. Delay type is of 2 types:&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.INSTANTANEOUS&amp;lt;/code&amp;gt;: signal propagation delay is not taken into account&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.LIGHT_SPEED&amp;lt;/code&amp;gt;: signal propagation delay is taken into account.&lt;br /&gt;
Signal propagation delay allows to detect events as it is exactly seen by a spacecraft, for instance a visibility between a satellite and a station.&lt;br /&gt;
All detectors involving a signal propagation and or sensors can take signal propagation delay into account (BetaAngleDetector, SensorVisibilityDetector, TargetInFieldOfViewDetector, etc.):&lt;br /&gt;
&lt;br /&gt;
By default signal propagation delay is not taken into account.&lt;br /&gt;
&lt;br /&gt;
A new detector class should implements  : &lt;br /&gt;
* [{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector interface] in case of [{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/Propagator.html mono satellite propagation] or [{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
* [{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector interface] in case of [{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Construction of a detector&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The action performed at event detection can be set by user at detector&#039;s construction. Several actions can be defined if several behavior are available (depending on state and/or on increasing/forward parameter). It is possible to specify at construction if the detector should be removed after event detection and thus not be detected any more. If a single action is available, a single boolean has to be provided by the user at construction. In the case where several actions are available, the same number of boolean has to be provided to determine if the detector has to be removed after event detection.&amp;lt;br&amp;gt;&lt;br /&gt;
Focusing on the &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt; for instance, two actions are possible at event detection :&lt;br /&gt;
&lt;br /&gt;
- action_at_ascending_node if an ascending node detection is done&amp;lt;br&amp;gt;&lt;br /&gt;
- action_at_descending_node if a descending node detection is performed&lt;br /&gt;
&lt;br /&gt;
If no actions are set, the user should be aware of the default implementation.&lt;br /&gt;
By default, event detectors are never removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of eventOccurred()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The returned action of the function eventOccurred could be set by user or defined by default.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function eventOccurred is common to all [{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector] classes (respectively [{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]) and its purpose is to handle an event and to choose what to do next ; this method is called when the integrator has accepted a step ending exactly on a sign change of the switching function, and it allows the user to choose which action will take place after the event (the simulation could be stopped, the propagator could reset its initial state or its initial derivative state ...).&lt;br /&gt;
Plus, this method is up to determine if the detector used has to be removed after the event detection : in the above example of &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt;, the action taking place after the event is set to action_at_raising_node in the case of an ascending node detection. If one has decided to remove the detector at such detection, the attribute shouldBeRemoved will be set to remove_at_ascending_node which is true by construction, the case of descending node is similar.&lt;br /&gt;
&lt;br /&gt;
Since the default implementation of eventOccurred could unfit the user needs in terms of propagation behaviour, it is recommended to check the content of the detector before using them and to change it if necessary by using a specific constructor which take as parameter the expected action(s).&lt;br /&gt;
&lt;br /&gt;
Note that the implementation of eventOccured must not contain any action. Even if the action does not impact the state vector, the action should be implemented in the resetState method.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of resetState() or resetStates()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If the event have an action, this action should be implemented in the resetState() method. In this case, the eventOccured() of the detector concerned should return a RESET_STATE action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Convergence threshold parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The convergence threshold represents the events detection precision; the following observations can help the user when choosing a value for this parameter:&lt;br /&gt;
&lt;br /&gt;
#if the convergence threshold increases, the execution time decreases (the precision becomes worst);&lt;br /&gt;
#if the convergence threshold is bigger than the max integration step, the events detection will fail.&lt;br /&gt;
&lt;br /&gt;
If the resetState(s) could modify others event detectors, the convergence threshold should be low in order to avoid any unpredictable behavior.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Max check interval parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The max check interval parameter represents the maximum interval in which the propagator checks for an event (i.e. for a sign change of the g switching function). When choosing this parameter, the user should keep in mind the following remarks:&lt;br /&gt;
&lt;br /&gt;
#if max check interval is smaller than the integration step, the execution time increases if the max check interval decreases (the events detection is more accurate);&lt;br /&gt;
#if max check interval is bigger than the max integration step, it will be replaced by the max integration step during the events detection process; in this case the max check interval is a useless parameter that will never be used by the propagator.&lt;br /&gt;
&lt;br /&gt;
In general, the user should always choose the max check interval value as a function of the integration step used during propagation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of the event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation start date, i.e if g() equal to zero, the event is processed. This case is extremely rare. Note that in some case however, due to numerical quality rounds-off, an event may not be detected at the propagation start date although it&#039;s theoritically supposed to occur. For example, starting propagation at periapsis with a periapsis detector may not detect periapsis since the g() function of PeriapsisDetector is based on position- velocity scalar product and due to rounds-off errors, its values may be around 1E-7 which is not exactly zero. &amp;lt;br&amp;gt;&lt;br /&gt;
Also, if at the propagation start date the g() function is not continuous but changes its sign (for example value-1 before event date, value 1 after), the event will also not be detected since the g() function value is not zero.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Ephemeris propagator event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one. Consequently, when propagating with a bounded propagator, if the last substep is larger than the real one then the real end date is exceeded, raising an exception. Therefore, in this case, it is recommended to &#039;&#039;&#039;propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the same date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are processed is the order in which they are added to the propagator. If the detected event stops the propagation, the other events occuring at the same date are not processed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the end date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation end date, the event is not processed.&lt;br /&gt;
&lt;br /&gt;
==== Available event detectors ====&lt;br /&gt;
Mono events detectors detect events applied on a specific state. These detectors can be used in mono or multi propagation case.&lt;br /&gt;
&lt;br /&gt;
The available mono events detectors are presented in specific pages: &lt;br /&gt;
&lt;br /&gt;
* [MIS_ORB_Home Orbit determination events]&lt;br /&gt;
* [MIS_SENSORS_Home Sensors events]&lt;br /&gt;
* [MIS_STASAT_Home Ground stations and satellites events]&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
It also exists multi events detectors applied on several states. These detectors can only be used in multi propagation case.&lt;br /&gt;
Notice that some detectors that implies several satellite coul be used in multi or mono satellite context ; ([{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/sensor/SatToSatMutualVisibilityDetector.html SatToSatMutualVisibilityDetector], [{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/ThreeBodiesAngleDetector.html ThreeBodiesAngleDetector] or [{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/ExtremaThreeBodiesAngleDetector.html ExtremaThreeBodiesAngleDetector])&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HMultiEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
The [{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector] is a detector that detects the nth occurrence of an underlying event detector.&amp;lt;br&amp;gt;&lt;br /&gt;
However the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every event of the underlying detector. As a result, the behaviour of this detector is the following:&lt;br /&gt;
* Before and after the nth occurrence, the eventOccurred() method returns &amp;lt;code&amp;gt;Action.CONTINUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
* At the nth occurrence, the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method returns the user-provided action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Warning&#039;&#039;&#039;&#039;&#039;: the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every occurrence of the underlying detector, not only at nth occurrence. Hence, overloading this detector should be performed carefully: in the overloaded &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method, the check &amp;lt;code&amp;gt;getCurrentOccurence() == getOccurence()&amp;lt;/code&amp;gt; should be performed first to ensure we are at nth occurrence before calling &amp;lt;code&amp;gt;super.eventOccurred()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== IntervalOccurenceDetector ====&lt;br /&gt;
This [{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurenceDetector.html IntervalOccurenceDetector ] is able for any EventDetector. It detects the &amp;lt;math&amp;gt;n^{th}&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;m^{th}&amp;lt;/math&amp;gt; event occurences by step of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; occurences. &lt;br /&gt;
Otherwise, if j event occurence, the &amp;lt;code&amp;gt;IntervalOccurenceDetector&amp;lt;/code&amp;gt; detects events as : &lt;br /&gt;
* &amp;lt;math&amp;gt;(j - n) % p = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n &amp;lt;= j &amp;lt;= m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The g switching function is the function of the event to detect.&lt;br /&gt;
&lt;br /&gt;
==== Mono Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
When a numerical propagation is performed, the event detection is done at the math level since the integration is realized by one of the numerical integrators. However, the event detectors are instanciated by the user at the Patrius level. Hence the necessity of an adapter to wrap a Patrius event detector object into a math event handler object whose interfaces provide basically the same kind of services. Once the event detectors are given to the numerical propagator, they are transformed into event handlers in order to give them to the math numerical integrator.&amp;lt;br&amp;gt;&lt;br /&gt;
The numerical integrator associates each event with another object which represents its state during the integration. At the end of each step, the method acceptStep() is systematically called and performs the event detection thanks to an interpolator, inside the current step. Thus the state of each event is updated. If an event is detected therefore the integration is either stopped or continued with or without state or derivative state resetting. It is also possible to remove the detector after the first event detection and the propagation is continued. An event is represented by a function, the function &amp;quot;g()&amp;quot;: the event occurs when the function sign changes and NOT when this function equals to zero. To find this root, in addition to the interpolator, a solver is used. By default, this solver is the Brent solver. The exception being at the beginning of the propagation where events are detected when the g() function equals exactly zero.&lt;br /&gt;
&lt;br /&gt;
===== Analytical propagator =====&lt;br /&gt;
&lt;br /&gt;
When an analytical propagation is performed, the event detection is done at the Patrius level directly. The process is basically the same than its math counterpart: the detectors are given to the propagator and associated to their states. The Patrius propagator has a method acceptStep() which is similar to the one of the math package.&lt;br /&gt;
&lt;br /&gt;
===== Ephemeris propagator =====&lt;br /&gt;
&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one which could be knotty when it comes to propagate with a bounded propagator. Indeed, if the last substep is larger than the real one then the real end date is exceeded. If the end date is equal to the ephemeris max date, an exception is raised when the interpolator sets the current date to a date exceeding the ephemeris max date. Therefore, in this case, &#039;&#039;&#039;it is recommended to propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Multi Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
The event detector process for multi satellite numerical propagation is equivalent to the process performed with single satellite numerical propagation. The multi event detection is wrapped into a math event handler object. The detector could be applied on a single satellite or on several satellites.&lt;br /&gt;
&lt;br /&gt;
=== Coded events and phenomena ===&lt;br /&gt;
==== Mono propagation ====&lt;br /&gt;
===== The coded event =====&lt;br /&gt;
&lt;br /&gt;
Patrius does detect events. This means :&lt;br /&gt;
&lt;br /&gt;
* Patrius triggers a method call on the corresponding EventDetector when the event occurs.&lt;br /&gt;
* Patrius logs the SpacecraftState and g function slope sign for the occuring event (through the EventsLogger).&lt;br /&gt;
&lt;br /&gt;
But this mechanism alone doesn&#039;t provide a programmatic representation for an &amp;quot;event&amp;quot;, which may be processed after the propagation.&lt;br /&gt;
&lt;br /&gt;
A new way of handling events as individual instances was thus designed : the &amp;quot;atomic event&amp;quot; or &amp;quot;coded event&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;coded event&amp;quot; has the following attributes :&lt;br /&gt;
&lt;br /&gt;
* an event &amp;quot;code&amp;quot; : a String identifying the category of the event, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* an event &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* an AbsoluteDate : the date at which the event occurred.&lt;br /&gt;
* a boolean, true when the event represents a &amp;quot;starting&amp;quot; event, or false when it represents an &amp;quot;ending&amp;quot; event (relative to a phenomenon, see below).&lt;br /&gt;
&lt;br /&gt;
The code and comment formats are free, they depend on the CodingEventDetector implementation (see below).&lt;br /&gt;
&lt;br /&gt;
A CodedEvent is supposed to be built by the CodedEventsLogger (see below).&lt;br /&gt;
&lt;br /&gt;
Moreover, when one of the boundaries of the phenomenon is ill-defined (e.g. unknown due to computational limits), it is an instance of CodedEvent, with the code &amp;quot;UNDEFINED_EVENT&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== The CodingEventDetector and MultiCodingEventDetector =====&lt;br /&gt;
&lt;br /&gt;
The CodingEventDetector (or MultiCodingEventDetector in MultiPropagator case) is an extension of the EventDetector type(respectively MultiEventDetector). A CodingEventDetector (or MultiCodingEventDetector) has the following requirements :&lt;br /&gt;
&lt;br /&gt;
* Providing a CodedEvent builder method, that creates a CodedEvent instance appropriate for the event (this is how the code and comment are determined).&lt;br /&gt;
* Providing a Phenomenon code if a Phenomenon makes sense in the context of the event, otherwise return null (see below).&lt;br /&gt;
* Providing a boolean telling which sign of the g() method means the Phenomenon is active (see below).&lt;br /&gt;
&lt;br /&gt;
===== The phenomenon =====&lt;br /&gt;
&lt;br /&gt;
The EventDetector provides a g() method whose sign change triggers an event. Sometimes the g() method can also be seen as conveying a &amp;quot;state&amp;quot; i.e. when g() is positive (resp. negative), a &amp;quot;phenomenon&amp;quot; is going on.&lt;br /&gt;
The clearest example would be the EclipseDetector :&lt;br /&gt;
&lt;br /&gt;
* g() going from positive to negative means that the spacecraft has entered the eclipse zone.&lt;br /&gt;
* g() going from negative to positive means that the spacecraft has exited the eclipse zone.&lt;br /&gt;
&lt;br /&gt;
The associated phenomenon would then be called &amp;quot;inside the eclipse zone&amp;quot;, bounded by the starting event &amp;quot;enter eclipse zone&amp;quot; and the ending event &amp;quot;exit eclipse zone&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This library provides a &amp;quot;phenomenon&amp;quot; abstraction, as a lightweight representation.&lt;br /&gt;
&lt;br /&gt;
A Phenomenon instance is an immutable object with the following attributes :&lt;br /&gt;
&lt;br /&gt;
* a phenomenon &amp;quot;code&amp;quot; : a String identifying the category of the phenomenon, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* a phenomenon &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* two &amp;quot;coded event&amp;quot; instances : the atomic events that represent the start and the end of the phenomenon.&lt;br /&gt;
&lt;br /&gt;
Also :&lt;br /&gt;
* it tells whether the start and end are &amp;quot;well-defined&amp;quot; : a well-defined boundary has a real event backing it. A not well-defined boundary is a boundary because of computational limits : it happens when, during a propagation, the ending event occurs, but the starting event did not (or, the opposite) because it was outside the boundaries of the propagation. In this case, an &amp;quot;UNDEFINED_EVENT&amp;quot; is given as the missing boundary (see above).&lt;br /&gt;
&lt;br /&gt;
A Phenomenon is built by the CodedEventsLogger, when the CodingEventDetector provides a non-null Phenomenon string code. The existence of this code proves the Phenomenon makes senses in the context of the CodingEventDetector. For instance :&lt;br /&gt;
&lt;br /&gt;
* for a &amp;quot;CodingEclipseDetector&amp;quot; built upon the EclipseDetector, a Phenomenon has meaning (the Phenomenon being &amp;quot;inside the eclipse&amp;quot;).&lt;br /&gt;
* for a &amp;quot;CodingApsideDetector&amp;quot; built upen the ApsideDetector, a Phenomenon has no meaning, since the events are : &amp;quot;the spacecraft is at the periapsis&amp;quot; and &amp;quot;the spacecraft is at the apoapsis&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Multi propagation ====&lt;br /&gt;
The same process exists. The corresponding classes are localized in the Patrius library.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting up a CodedEventsLogger or a MultiCodedEventsLogger ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent and Phenomenon instances are not meant to be produced by the CodingEventDetectors (or directly MultiCodedEventsLogger in MultiPropagator case) (but it could be possible if needed).&lt;br /&gt;
&lt;br /&gt;
Instead, the (Multi)CodedEventsLogger was created for this purpose.&lt;br /&gt;
&lt;br /&gt;
At first glance, a (Multi)CodedEventsLogger instance is very similar to the (Multi)EventsLogger.&lt;br /&gt;
The main difference is that the (Multi)EventsLogger instances have no inner representation of events, while the (Multi)CodedEventsLogger produces CodedEvent and Phenomenon lists.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how one uses the (Multi)CodedEventsLogger :&lt;br /&gt;
&lt;br /&gt;
* create a (Multi)CodedEventsLogger instance.&lt;br /&gt;
* create at least one (Multi)CodingEventProvider instance.&lt;br /&gt;
* call the &amp;lt;code&amp;gt;monitorDetector()&amp;lt;/code&amp;gt; method on the (Multi)CodedEventsLogger : it produces a &amp;quot;wrapper&amp;quot; of the (Multi)CodingEventProvider exposed as a regular EventProvider.&lt;br /&gt;
* pass this &amp;quot;wrapper&amp;quot; to a propagator (any kind works : those who do compute a propagation and those who replay an ephemeris).&lt;br /&gt;
* run the propagator.&lt;br /&gt;
&lt;br /&gt;
While the propagator runs, the &amp;quot;wrapper&amp;quot; calls both the (Multi)CodingEventProvider instance and the (Multi)CodedEventsLogger on each event. The (Multi)CodedEventsLogger instance uses the (Multi)CodingEventProvider to build and store all CodedEvent instances during the propagation.&lt;br /&gt;
&lt;br /&gt;
==== Getting the full coded events list ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;getCodedEventsList()&amp;lt;/code&amp;gt;.&lt;br /&gt;
It provides a list of all CodedEvents (for all the CodingEventDetectors passed to the propagator, without distinction).&lt;br /&gt;
&lt;br /&gt;
==== Getting the events list per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildCodedEventListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a CodedEventsList as value, this list only containing the events generated from the key.&amp;lt;br&amp;gt;&lt;br /&gt;
It is, therfore, the same data as the full events&#039; list, but rearranged per CodingEventProvider instance.&lt;br /&gt;
&lt;br /&gt;
==== Getting the phenomena per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildPhenomenaListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a PhenomenaList as value, this list only containing the Phenomenon instances generated from the key. The(Multi) CodingEventProvider instance provides the Phenomenon code.&lt;br /&gt;
&lt;br /&gt;
The (Multi)CodedEventsLogger only uses the (Multi)CodingEventProvider instances that provide a non-null Phenomenon code (null indicates that a Phenomenon has no meaning for this detector).&lt;br /&gt;
&lt;br /&gt;
==== N-th occurrence of a coded event, or a delayed event ====&lt;br /&gt;
&lt;br /&gt;
There are two ways to generate the n-th occurrence of an event or a delayed coded event from a detected event: the first one is using the post-processing classes, and the second one is to configure the CodingEventDetector in order to create the delayed or filtered coded events during the propagation (in addition to the &amp;quot;standard&amp;quot; coded events).&lt;br /&gt;
While the former can only be done after the propagation, the latter has to be set before the propagation and is possible thanks to the following methods in the class CodingEventDetector:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buildCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the standard CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildDelayedCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the delayed CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildOccurrenceCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the n-th occurrence CodedEvent (n will be a parameter chosen by the user)&lt;br /&gt;
&lt;br /&gt;
In order to use this feature, the delay value and/or the occurrence number must be given as input parameters of the constructor of the class implementing the CodingEventDetector class (for instance GenericCodingEventDetector). The CodedEventsLogger will then be able to read these parameters and handle the generation of standard and not-standard coded events.&lt;br /&gt;
&lt;br /&gt;
Note, in the GenericCodingEventDetector constructor (EventDetector, String, String, boolean, String, double, int), if both parameters delayIn and occurrenceIn are other than 0, the event is saved as a delayed event, not a &amp;quot;Nth occurence of&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== When to use Coded events and phenomena ===&lt;br /&gt;
* To build easier time lines of events&lt;br /&gt;
* To manipulate easier phenomena (for example between &amp;quot;starting&amp;quot; and &amp;quot;ending&amp;quot; events) and associate to them specific computations (for example the evolution of the illumination during an eclipse)&lt;br /&gt;
* To apply some [MIS_POSTP_Home post-processing filters]&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Using available events detectors ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
Example of propagation stopping at 3rd detected node with event detector overloading:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Initialization&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2003, 1, 1, TimeScalesFactory.getTAI());&lt;br /&gt;
final Orbit orbit = new KeplerianOrbit(7000000, 0.01, 0.1, 0.2, 0.3, 0.4, PositionAngle.TRUE, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
&lt;br /&gt;
// Node detector&lt;br /&gt;
final EventDetector nodeDetector = new NodeDetector(orbit, FramesFactory.getGCRF(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
// Stop at 3rd detected node&lt;br /&gt;
final NthOccurrenceDetector nthOccurrenceDetector = new NthOccurrenceDetector(nodeDetector, 3, Action.STOP) {&lt;br /&gt;
    @Override&lt;br /&gt;
    public Action eventOccurred(SpacecraftState s, boolean increasing, boolean forward) throws PatriusException {&lt;br /&gt;
        super.eventOccurred(s, increasing, forward);&lt;br /&gt;
        if (getCurrentOccurence() == getOccurence()) {&lt;br /&gt;
            return Action.STOP;&lt;br /&gt;
        } else {&lt;br /&gt;
            return Action.CONTINUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Propagation&lt;br /&gt;
final KeplerianPropagator propagator = new KeplerianPropagator(orbit);&lt;br /&gt;
propagator.addEventDetector(nthOccurrenceDetector);&lt;br /&gt;
propagator.propagate(orbit.getDate().shiftedBy(86400.));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generating coded events and phenomena ===&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent instances and Phenomenon instances are meant to be produced using :&amp;lt;br&amp;gt;&lt;br /&gt;
- CodingEventDetector implementations that provide information about events and phenomena,&amp;lt;br&amp;gt;&lt;br /&gt;
- a CodingEventsLogger, that uses the CodingEventDetector instances to build the events and phenomena.&lt;br /&gt;
&lt;br /&gt;
For example, if we want to create a list of CodedEvent objects using a detector of nodes (ascending and descending orbital nodes):&lt;br /&gt;
&lt;br /&gt;
1. Create a new EventDetector (in this case a NodeDetector):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set up the node detector:&lt;br /&gt;
  AbsoluteDate date = new AbsoluteDate(&amp;quot;2000-01-01T12:00:00Z&amp;quot;, TimeScalesFactory.getTT());&lt;br /&gt;
  AbsoluteDate dateF = date.shiftedBy(2* period);&lt;br /&gt;
  Orbit orbit = new KeplerianOrbit(7e6, 0, 0.2, 0, 0, 0.2, PositionAngle.MEAN, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
  NodeDetector node = new NodeDetector(orbit, FramesFactory.getEME2000(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Create a new generic coding event detector:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // standard event&lt;br /&gt;
  GenericCodingEventDetector nodeDet =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;);&lt;br /&gt;
  // third occurence of event&lt;br /&gt;
  GenericCodingEventDetector nodeDetOcc =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 0., 3);&lt;br /&gt;
  // delayed event (10 seconds here)&lt;br /&gt;
  GenericCodingEventDetector nodeDetDel =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 10., 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Create a new CodedEventsLogger and use the &amp;lt;code&amp;gt; monitorDetector &amp;lt;/code&amp;gt; function on the new CodedEventsLogger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  CodedEventsLogger logger = new CodedEventsLogger();&lt;br /&gt;
  // Create an EventDetector object so that event detection functions could be used:&lt;br /&gt;
  EventDetector d = logger.monitorDetector(nodeDet);&lt;br /&gt;
  EventDetector dOcc = logger.monitorDetector(nodeDetOcc);&lt;br /&gt;
  EventDetector dDel = logger.monitorDetector(nodeDetDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Add the EventDetector to the propagator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  propagator.addEventDetector(d);&lt;br /&gt;
  propagator.addEventDetector(dOcc);&lt;br /&gt;
  propagator.addEventDetector(dDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Start the propagation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set the propagator:&lt;br /&gt;
  propagator.setEphemerisMode();&lt;br /&gt;
  propagator.resetInitialState(new SpacecraftState(orbit));&lt;br /&gt;
  // Propagate:&lt;br /&gt;
  propagator.propagate(date0, dateF);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Combination of boolean phenomena ===&lt;br /&gt;
Sometimes an event (a zero of a g function) can be seen as a begin (passing zero from positive to negative or invert) or a end ( other way ) of a phenomena. For example the eclipse event can be the begin (detected when g function goes from positive to negative) or the end (when g function goes from negative to positive) of an eclipse. (cf. [MIS_ORB_Home#HEclipseDetectorandGenericEclipseDetector Eclipse detector].)&lt;br /&gt;
&lt;br /&gt;
One can choose to create an event as a combination of these phenomena, for example a station visibility outside an interference period. In this case a user can create a detector as a combination of existing detectors.&lt;br /&gt;
&lt;br /&gt;
The user simply has to provide the following parameters :&lt;br /&gt;
#First detector and the way to use it (g is positive or negative during the phenomena to combine)&lt;br /&gt;
#Second detector and the way to use it &lt;br /&gt;
#How to combine the phenomenom : both are during phenomena (will be detected as the minimum of the two g function) or at least one (will be detected as the maximum of the two g function) is during phenomena &lt;br /&gt;
&lt;br /&gt;
Once a new detector have been created in this way, it is possible to combine it with another one and so on.&lt;br /&gt;
&lt;br /&gt;
For example the [MIS_SENSORS_Home#HCentralBodyMaskCircularFOVDetector CentralBodyMaskCircularFOVDetector] detects when a target is in a circular field of view and outside of an eclipse, that is translated by :&lt;br /&gt;
&lt;br /&gt;
* Outside of eclipse : when EllipsoidEclipseDetecor g function is positive &lt;br /&gt;
* Inside circular field of view : when CircularFieldOfView g function is positive&lt;br /&gt;
&lt;br /&gt;
So the following code example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// EclipseDetector&lt;br /&gt;
final EclipseDetector eed = new EclipseDetector(targetPVP, targetRadius, spheroEarth, 1., MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// CircularFOVDetector&lt;br /&gt;
final CircularFieldOfViewDetector cfvd = new CircularFieldOfViewDetector(targetPVP, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CombinedPhenomenaDetector cbmcfovd2 = new CombinedPhenomenaDetector(eed, true, cfvd, true, true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is equivalent to CentralBodyMaskCircularFOVDetector :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CentralBodyMaskCircularFOVDetector cbmcfovd = &lt;br /&gt;
new CentralBodyMaskCircularFOVDetector(targetPVP, targetRadius, spheroEarth, false, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
==== Interfaces events detection ====&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.7}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/CodingEventDetector.html CodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiEventDetector&lt;br /&gt;
|This interface represents an event finder in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
==== Classes containing the general functions to detect events ====&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;
| AbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/AbstractDetector.html AbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiAbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiAbstractDetector.html MultiAbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedEventDetector&lt;br /&gt;
|This class adapts Patrius event detectors to math EventHandler object.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/AdaptedEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMonoEventDetector&lt;br /&gt;
|This class adapts Patrius mono event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMonoEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMultiEventDetector&lt;br /&gt;
|This class adapts Patrius multi event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMultiEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CombinedPhenomenaDetector&lt;br /&gt;
|This class handles events representing the combination of two boolean phenomena.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/CombinedPhenomenaDetector.html CombinedPhenomenaDetector]&lt;br /&gt;
|-&lt;br /&gt;
| NthOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a certain occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| IntervalOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a interval occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurrenceDetector.html IntervalOccurrenceDetector]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Classes for the generation of lists of events and phenomena ====&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;
| CodedEvent&lt;br /&gt;
|This class implements coded events (a light and simple representation of events as generated by Patrius event detectors ).&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/CodedEvent.html CodedEvent]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/CodedEventsList.html CodedEventsList]&lt;br /&gt;
|-&lt;br /&gt;
| Phenomenon&lt;br /&gt;
|This class implements the notion of a phenomenon : a state defined by a starting event and an ending event.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/Phenomenon.html Phenomenon]&lt;br /&gt;
|-&lt;br /&gt;
| PhenomenaList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/PhenomenaList.html PhenomenaList]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/CodedEventsLogger.html CodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| GenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/GenericCodingEventDetector.html GenericCodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiGenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface in multi propagation case, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.7}}/fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.7_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.6_Events_detection:_Presentation&amp;diff=3609</id>
		<title>User Manual 4.6 Events detection: Presentation</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.6_Events_detection:_Presentation&amp;diff=3609"/>
		<updated>2023-12-19T16:18:38Z</updated>

		<summary type="html">&lt;p&gt;Admin : &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
=== Scope ===&lt;br /&gt;
This section describes :&lt;br /&gt;
&lt;br /&gt;
* in a mono satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions that extend  event detection mechanism.&lt;br /&gt;
* in a multi satellite context : &lt;br /&gt;
** the events detection.&lt;br /&gt;
** the &amp;quot;coded event&amp;quot; and &amp;quot;phenomenon&amp;quot; notions, copied from the mono satellite mechanism, that extend Patrius&#039;s event detection mechanism for multi satellite propagation.&lt;br /&gt;
&lt;br /&gt;
=== Javadoc ===&lt;br /&gt;
The following packages are related to events detections in mono and multi propagation context:&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.6}}/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.6}}/fr/cnes/sirius/patrius/math/ode/events/package-summary.html Package fr.cnes.sirius.patrius.math.ode.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/package-summary.html Package fr.cnes.sirius.patrius.events]&lt;br /&gt;
|-&lt;br /&gt;
|Patrius &lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/multi/package-summary.html Package fr.cnes.sirius.patrius.propagation.events.multi]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Links ===&lt;br /&gt;
None as 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 architecture of the events detection for mono and multi satellite propagation:&lt;br /&gt;
&lt;br /&gt;
[[File:EventsV3.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following diagram represents the mechanism used in the Patrius library in order to create the list of the events detected during the mono satellite propagation as well as the phenomena list :&lt;br /&gt;
&lt;br /&gt;
[[File:Events.png|center]]&lt;br /&gt;
&lt;br /&gt;
The following classes are duplicated from mono satellite context in order to create a list of events detected : &lt;br /&gt;
* [{{JavaDoc4.6}}//fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.6}}//fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
* [{{JavaDoc4.6}}//fr/cnes/sirius/patrius/events/multi/MultiEventsLogger.html MultiEventsLogger]&lt;br /&gt;
* [{{JavaDoc4.6}}//fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
&lt;br /&gt;
== Features Description ==&lt;br /&gt;
=== Event detection ===&lt;br /&gt;
&lt;br /&gt;
The events detection process can be used during mono or multi propagation propagation, when we need to know if some events occur and at what time (for instance when the satellite will be in eclipse, or if at a given date it will be visible or not from a ground station).&lt;br /&gt;
&lt;br /&gt;
In Patrius there is one class for every kind of event: the information related to an event is contained in this class, and it will be used by the mono satellite numerical or analytical propagator when extrapolating the orbit. The mechanism is similar for multi propagation.&lt;br /&gt;
&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are detected is the order in which they are added to the propagator.&lt;br /&gt;
&lt;br /&gt;
As of PATRIUS 4.5, detectors can optionally take into account signal propagation delay. Javadoc of each event detector indicates if signal propagation delay can be taken into account through a setter &amp;lt;code&amp;gt;setPropagationDelayType()&amp;lt;/code&amp;gt;. Delay type is of 2 types:&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.INSTANTANEOUS&amp;lt;/code&amp;gt;: signal propagation delay is not taken into account&lt;br /&gt;
* &amp;lt;code&amp;gt;PropagationDelayType.LIGHT_SPEED&amp;lt;/code&amp;gt;: signal propagation delay is taken into account.&lt;br /&gt;
Signal propagation delay allows to detect events as it is exactly seen by a spacecraft, for instance a visibility between a satellite and a station.&lt;br /&gt;
All detectors involving a signal propagation and or sensors can take signal propagation delay into account (BetaAngleDetector, SensorVisibilityDetector, TargetInFieldOfViewDetector, etc.):&lt;br /&gt;
&lt;br /&gt;
By default signal propagation delay is not taken into account.&lt;br /&gt;
&lt;br /&gt;
A new detector class should implements  : &lt;br /&gt;
* [{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector interface] in case of [{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/Propagator.html mono satellite propagation] or [{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
* [{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector interface] in case of [{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/MultiPropagator.html multi satellite propagation].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Construction of a detector&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The action performed at event detection can be set by user at detector&#039;s construction. Several actions can be defined if several behavior are available (depending on state and/or on increasing/forward parameter). It is possible to specify at construction if the detector should be removed after event detection and thus not be detected any more. If a single action is available, a single boolean has to be provided by the user at construction. In the case where several actions are available, the same number of boolean has to be provided to determine if the detector has to be removed after event detection.&amp;lt;br&amp;gt;&lt;br /&gt;
Focusing on the &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt; for instance, two actions are possible at event detection :&lt;br /&gt;
&lt;br /&gt;
- action_at_ascending_node if an ascending node detection is done&amp;lt;br&amp;gt;&lt;br /&gt;
- action_at_descending_node if a descending node detection is performed&lt;br /&gt;
&lt;br /&gt;
If no actions are set, the user should be aware of the default implementation.&lt;br /&gt;
By default, event detectors are never removed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of eventOccurred()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The returned action of the function eventOccurred could be set by user or defined by default.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function eventOccurred is common to all [{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector] classes (respectively [{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]) and its purpose is to handle an event and to choose what to do next ; this method is called when the integrator has accepted a step ending exactly on a sign change of the switching function, and it allows the user to choose which action will take place after the event (the simulation could be stopped, the propagator could reset its initial state or its initial derivative state ...).&lt;br /&gt;
Plus, this method is up to determine if the detector used has to be removed after the event detection : in the above example of &amp;lt;code&amp;gt; NodeDetector &amp;lt;/code&amp;gt;, the action taking place after the event is set to action_at_raising_node in the case of an ascending node detection. If one has decided to remove the detector at such detection, the attribute shouldBeRemoved will be set to remove_at_ascending_node which is true by construction, the case of descending node is similar.&lt;br /&gt;
&lt;br /&gt;
Since the default implementation of eventOccurred could unfit the user needs in terms of propagation behaviour, it is recommended to check the content of the detector before using them and to change it if necessary by using a specific constructor which take as parameter the expected action(s).&lt;br /&gt;
&lt;br /&gt;
Note that the implementation of eventOccured must not contain any action. Even if the action does not impact the state vector, the action should be implemented in the resetState method.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of resetState() or resetStates()&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If the event have an action, this action should be implemented in the resetState() method. In this case, the eventOccured() of the detector concerned should return a RESET_STATE action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Convergence threshold parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The convergence threshold represents the events detection precision; the following observations can help the user when choosing a value for this parameter:&lt;br /&gt;
&lt;br /&gt;
#if the convergence threshold increases, the execution time decreases (the precision becomes worst);&lt;br /&gt;
#if the convergence threshold is bigger than the max integration step, the events detection will fail.&lt;br /&gt;
&lt;br /&gt;
If the resetState(s) could modify others event detectors, the convergence threshold should be low in order to avoid any unpredictable behavior.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Max check interval parametrisation&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
The max check interval parameter represents the maximum interval in which the propagator checks for an event (i.e. for a sign change of the g switching function). When choosing this parameter, the user should keep in mind the following remarks:&lt;br /&gt;
&lt;br /&gt;
#if max check interval is smaller than the integration step, the execution time increases if the max check interval decreases (the events detection is more accurate);&lt;br /&gt;
#if max check interval is bigger than the max integration step, it will be replaced by the max integration step during the events detection process; in this case the max check interval is a useless parameter that will never be used by the propagator.&lt;br /&gt;
&lt;br /&gt;
In general, the user should always choose the max check interval value as a function of the integration step used during propagation.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Initialisation of the event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation start date, i.e if g() equal to zero, the event is processed. This case is extremely rare. Note that in some case however, due to numerical quality rounds-off, an event may not be detected at the propagation start date although it&#039;s theoritically supposed to occur. For example, starting propagation at periapsis with a periapsis detector may not detect periapsis since the g() function of PeriapsisDetector is based on position- velocity scalar product and due to rounds-off errors, its values may be around 1E-7 which is not exactly zero. &amp;lt;br&amp;gt;&lt;br /&gt;
Also, if at the propagation start date the g() function is not continuous but changes its sign (for example value-1 before event date, value 1 after), the event will also not be detected since the g() function value is not zero.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Ephemeris propagator event detection&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one. Consequently, when propagating with a bounded propagator, if the last substep is larger than the real one then the real end date is exceeded, raising an exception. Therefore, in this case, it is recommended to &#039;&#039;&#039;propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the same date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
When two events occur at the same date, Patrius detects both of them, but the order in which they are processed is the order in which they are added to the propagator. If the detected event stops the propagation, the other events occuring at the same date are not processed.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Events occurring at the end date&#039;&#039;&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
If an event occurs exactly at the propagation end date, the event is not processed.&lt;br /&gt;
&lt;br /&gt;
==== Available event detectors ====&lt;br /&gt;
Mono events detectors detect events applied on a specific state. These detectors can be used in mono or multi propagation case.&lt;br /&gt;
&lt;br /&gt;
The available mono events detectors are presented in specific pages: &lt;br /&gt;
&lt;br /&gt;
* [MIS_ORB_Home Orbit determination events]&lt;br /&gt;
* [MIS_SENSORS_Home Sensors events]&lt;br /&gt;
* [MIS_STASAT_Home Ground stations and satellites events]&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
It also exists multi events detectors applied on several states. These detectors can only be used in multi propagation case.&lt;br /&gt;
Notice that some detectors that implies several satellite coul be used in multi or mono satellite context ; ([{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/sensor/SatToSatMutualVisibilityDetector.html SatToSatMutualVisibilityDetector], [{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/ThreeBodiesAngleDetector.html ThreeBodiesAngleDetector] or [{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/ExtremaThreeBodiesAngleDetector.html ExtremaThreeBodiesAngleDetector])&lt;br /&gt;
&lt;br /&gt;
All these event detectors can be used [MIS_EVT_Home#HMultiEventDetection directly] or as [MIS_EVT_Home#HGeneratingcodedeventsandphenomena coded events].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
The [{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector] is a detector that detects the nth occurrence of an underlying event detector.&amp;lt;br&amp;gt;&lt;br /&gt;
However the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every event of the underlying detector. As a result, the behaviour of this detector is the following:&lt;br /&gt;
* Before and after the nth occurrence, the eventOccurred() method returns &amp;lt;code&amp;gt;Action.CONTINUE&amp;lt;/code&amp;gt;.&lt;br /&gt;
* At the nth occurrence, the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method returns the user-provided action.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Warning&#039;&#039;&#039;&#039;&#039;: the &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method is triggered at every occurrence of the underlying detector, not only at nth occurrence. Hence, overloading this detector should be performed carefully: in the overloaded &amp;lt;code&amp;gt;eventOccurred()&amp;lt;/code&amp;gt; method, the check &amp;lt;code&amp;gt;getCurrentOccurence() == getOccurence()&amp;lt;/code&amp;gt; should be performed first to ensure we are at nth occurrence before calling &amp;lt;code&amp;gt;super.eventOccurred()&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== IntervalOccurenceDetector ====&lt;br /&gt;
This [{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurenceDetector.html IntervalOccurenceDetector ] is able for any EventDetector. It detects the &amp;lt;math&amp;gt;n^{th}&amp;lt;/math&amp;gt; to &amp;lt;math&amp;gt;m^{th}&amp;lt;/math&amp;gt; event occurences by step of &amp;lt;math&amp;gt;p&amp;lt;/math&amp;gt; occurences. &lt;br /&gt;
Otherwise, if j event occurence, the &amp;lt;code&amp;gt;IntervalOccurenceDetector&amp;lt;/code&amp;gt; detects events as : &lt;br /&gt;
* &amp;lt;math&amp;gt;(j - n) % p = 0&amp;lt;/math&amp;gt;&lt;br /&gt;
* &amp;lt;math&amp;gt;n &amp;lt;= j &amp;lt;= m&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The g switching function is the function of the event to detect.&lt;br /&gt;
&lt;br /&gt;
==== Mono Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
When a numerical propagation is performed, the event detection is done at the math level since the integration is realized by one of the numerical integrators. However, the event detectors are instanciated by the user at the Patrius level. Hence the necessity of an adapter to wrap a Patrius event detector object into a math event handler object whose interfaces provide basically the same kind of services. Once the event detectors are given to the numerical propagator, they are transformed into event handlers in order to give them to the math numerical integrator.&amp;lt;br&amp;gt;&lt;br /&gt;
The numerical integrator associates each event with another object which represents its state during the integration. At the end of each step, the method acceptStep() is systematically called and performs the event detection thanks to an interpolator, inside the current step. Thus the state of each event is updated. If an event is detected therefore the integration is either stopped or continued with or without state or derivative state resetting. It is also possible to remove the detector after the first event detection and the propagation is continued. An event is represented by a function, the function &amp;quot;g()&amp;quot;: the event occurs when the function sign changes and NOT when this function equals to zero. To find this root, in addition to the interpolator, a solver is used. By default, this solver is the Brent solver. The exception being at the beginning of the propagation where events are detected when the g() function equals exactly zero.&lt;br /&gt;
&lt;br /&gt;
===== Analytical propagator =====&lt;br /&gt;
&lt;br /&gt;
When an analytical propagation is performed, the event detection is done at the Patrius level directly. The process is basically the same than its math counterpart: the detectors are given to the propagator and associated to their states. The Patrius propagator has a method acceptStep() which is similar to the one of the math package.&lt;br /&gt;
&lt;br /&gt;
===== Ephemeris propagator =====&lt;br /&gt;
&lt;br /&gt;
Sometimes the event detection is performed on a substep a little larger than the real one which could be knotty when it comes to propagate with a bounded propagator. Indeed, if the last substep is larger than the real one then the real end date is exceeded. If the end date is equal to the ephemeris max date, an exception is raised when the interpolator sets the current date to a date exceeding the ephemeris max date. Therefore, in this case, &#039;&#039;&#039;it is recommended to propagate over an interval shorter than the interval of validity of the bounded propagator&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Multi Events detection process description ====&lt;br /&gt;
&lt;br /&gt;
===== Numerical propagator =====&lt;br /&gt;
&lt;br /&gt;
The event detector process for multi satellite numerical propagation is equivalent to the process performed with single satellite numerical propagation. The multi event detection is wrapped into a math event handler object. The detector could be applied on a single satellite or on several satellites.&lt;br /&gt;
&lt;br /&gt;
=== Coded events and phenomena ===&lt;br /&gt;
==== Mono propagation ====&lt;br /&gt;
===== The coded event =====&lt;br /&gt;
&lt;br /&gt;
Patrius does detect events. This means :&lt;br /&gt;
&lt;br /&gt;
* Patrius triggers a method call on the corresponding EventDetector when the event occurs.&lt;br /&gt;
* Patrius logs the SpacecraftState and g function slope sign for the occuring event (through the EventsLogger).&lt;br /&gt;
&lt;br /&gt;
But this mechanism alone doesn&#039;t provide a programmatic representation for an &amp;quot;event&amp;quot;, which may be processed after the propagation.&lt;br /&gt;
&lt;br /&gt;
A new way of handling events as individual instances was thus designed : the &amp;quot;atomic event&amp;quot; or &amp;quot;coded event&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A &amp;quot;coded event&amp;quot; has the following attributes :&lt;br /&gt;
&lt;br /&gt;
* an event &amp;quot;code&amp;quot; : a String identifying the category of the event, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* an event &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* an AbsoluteDate : the date at which the event occurred.&lt;br /&gt;
* a boolean, true when the event represents a &amp;quot;starting&amp;quot; event, or false when it represents an &amp;quot;ending&amp;quot; event (relative to a phenomenon, see below).&lt;br /&gt;
&lt;br /&gt;
The code and comment formats are free, they depend on the CodingEventDetector implementation (see below).&lt;br /&gt;
&lt;br /&gt;
A CodedEvent is supposed to be built by the CodedEventsLogger (see below).&lt;br /&gt;
&lt;br /&gt;
Moreover, when one of the boundaries of the phenomenon is ill-defined (e.g. unknown due to computational limits), it is an instance of CodedEvent, with the code &amp;quot;UNDEFINED_EVENT&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== The CodingEventDetector and MultiCodingEventDetector =====&lt;br /&gt;
&lt;br /&gt;
The CodingEventDetector (or MultiCodingEventDetector in MultiPropagator case) is an extension of the EventDetector type(respectively MultiEventDetector). A CodingEventDetector (or MultiCodingEventDetector) has the following requirements :&lt;br /&gt;
&lt;br /&gt;
* Providing a CodedEvent builder method, that creates a CodedEvent instance appropriate for the event (this is how the code and comment are determined).&lt;br /&gt;
* Providing a Phenomenon code if a Phenomenon makes sense in the context of the event, otherwise return null (see below).&lt;br /&gt;
* Providing a boolean telling which sign of the g() method means the Phenomenon is active (see below).&lt;br /&gt;
&lt;br /&gt;
===== The phenomenon =====&lt;br /&gt;
&lt;br /&gt;
The EventDetector provides a g() method whose sign change triggers an event. Sometimes the g() method can also be seen as conveying a &amp;quot;state&amp;quot; i.e. when g() is positive (resp. negative), a &amp;quot;phenomenon&amp;quot; is going on.&lt;br /&gt;
The clearest example would be the EclipseDetector :&lt;br /&gt;
&lt;br /&gt;
* g() going from positive to negative means that the spacecraft has entered the eclipse zone.&lt;br /&gt;
* g() going from negative to positive means that the spacecraft has exited the eclipse zone.&lt;br /&gt;
&lt;br /&gt;
The associated phenomenon would then be called &amp;quot;inside the eclipse zone&amp;quot;, bounded by the starting event &amp;quot;enter eclipse zone&amp;quot; and the ending event &amp;quot;exit eclipse zone&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
This library provides a &amp;quot;phenomenon&amp;quot; abstraction, as a lightweight representation.&lt;br /&gt;
&lt;br /&gt;
A Phenomenon instance is an immutable object with the following attributes :&lt;br /&gt;
&lt;br /&gt;
* a phenomenon &amp;quot;code&amp;quot; : a String identifying the category of the phenomenon, as chosen by the library user (no actual code is provided yet).&lt;br /&gt;
* a phenomenon &amp;quot;comment&amp;quot; : also a String that can be chosen by the library user.&lt;br /&gt;
* two &amp;quot;coded event&amp;quot; instances : the atomic events that represent the start and the end of the phenomenon.&lt;br /&gt;
&lt;br /&gt;
Also :&lt;br /&gt;
* it tells whether the start and end are &amp;quot;well-defined&amp;quot; : a well-defined boundary has a real event backing it. A not well-defined boundary is a boundary because of computational limits : it happens when, during a propagation, the ending event occurs, but the starting event did not (or, the opposite) because it was outside the boundaries of the propagation. In this case, an &amp;quot;UNDEFINED_EVENT&amp;quot; is given as the missing boundary (see above).&lt;br /&gt;
&lt;br /&gt;
A Phenomenon is built by the CodedEventsLogger, when the CodingEventDetector provides a non-null Phenomenon string code. The existence of this code proves the Phenomenon makes senses in the context of the CodingEventDetector. For instance :&lt;br /&gt;
&lt;br /&gt;
* for a &amp;quot;CodingEclipseDetector&amp;quot; built upon the EclipseDetector, a Phenomenon has meaning (the Phenomenon being &amp;quot;inside the eclipse&amp;quot;).&lt;br /&gt;
* for a &amp;quot;CodingApsideDetector&amp;quot; built upen the ApsideDetector, a Phenomenon has no meaning, since the events are : &amp;quot;the spacecraft is at the periapsis&amp;quot; and &amp;quot;the spacecraft is at the apoapsis&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== Multi propagation ====&lt;br /&gt;
The same process exists. The corresponding classes are localized in the Patrius library.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Setting up a CodedEventsLogger or a MultiCodedEventsLogger ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent and Phenomenon instances are not meant to be produced by the CodingEventDetectors (or directly MultiCodedEventsLogger in MultiPropagator case) (but it could be possible if needed).&lt;br /&gt;
&lt;br /&gt;
Instead, the (Multi)CodedEventsLogger was created for this purpose.&lt;br /&gt;
&lt;br /&gt;
At first glance, a (Multi)CodedEventsLogger instance is very similar to the (Multi)EventsLogger.&lt;br /&gt;
The main difference is that the (Multi)EventsLogger instances have no inner representation of events, while the (Multi)CodedEventsLogger produces CodedEvent and Phenomenon lists.&lt;br /&gt;
&lt;br /&gt;
Here&#039;s how one uses the (Multi)CodedEventsLogger :&lt;br /&gt;
&lt;br /&gt;
* create a (Multi)CodedEventsLogger instance.&lt;br /&gt;
* create at least one (Multi)CodingEventProvider instance.&lt;br /&gt;
* call the &amp;lt;code&amp;gt;monitorDetector()&amp;lt;/code&amp;gt; method on the (Multi)CodedEventsLogger : it produces a &amp;quot;wrapper&amp;quot; of the (Multi)CodingEventProvider exposed as a regular EventProvider.&lt;br /&gt;
* pass this &amp;quot;wrapper&amp;quot; to a propagator (any kind works : those who do compute a propagation and those who replay an ephemeris).&lt;br /&gt;
* run the propagator.&lt;br /&gt;
&lt;br /&gt;
While the propagator runs, the &amp;quot;wrapper&amp;quot; calls both the (Multi)CodingEventProvider instance and the (Multi)CodedEventsLogger on each event. The (Multi)CodedEventsLogger instance uses the (Multi)CodingEventProvider to build and store all CodedEvent instances during the propagation.&lt;br /&gt;
&lt;br /&gt;
==== Getting the full coded events list ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;getCodedEventsList()&amp;lt;/code&amp;gt;.&lt;br /&gt;
It provides a list of all CodedEvents (for all the CodingEventDetectors passed to the propagator, without distinction).&lt;br /&gt;
&lt;br /&gt;
==== Getting the events list per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildCodedEventListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a CodedEventsList as value, this list only containing the events generated from the key.&amp;lt;br&amp;gt;&lt;br /&gt;
It is, therfore, the same data as the full events&#039; list, but rearranged per CodingEventProvider instance.&lt;br /&gt;
&lt;br /&gt;
==== Getting the phenomena per (Multi)CodingEventProvider ====&lt;br /&gt;
&lt;br /&gt;
Call the method &amp;lt;code&amp;gt;buildPhenomenaListMap()&amp;lt;/code&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
It builds a &amp;lt;code&amp;gt;java.util.Map&amp;lt;/code&amp;gt;, with CodingEventProvider instances as keys, and a PhenomenaList as value, this list only containing the Phenomenon instances generated from the key. The(Multi) CodingEventProvider instance provides the Phenomenon code.&lt;br /&gt;
&lt;br /&gt;
The (Multi)CodedEventsLogger only uses the (Multi)CodingEventProvider instances that provide a non-null Phenomenon code (null indicates that a Phenomenon has no meaning for this detector).&lt;br /&gt;
&lt;br /&gt;
==== N-th occurrence of a coded event, or a delayed event ====&lt;br /&gt;
&lt;br /&gt;
There are two ways to generate the n-th occurrence of an event or a delayed coded event from a detected event: the first one is using the post-processing classes, and the second one is to configure the CodingEventDetector in order to create the delayed or filtered coded events during the propagation (in addition to the &amp;quot;standard&amp;quot; coded events).&lt;br /&gt;
While the former can only be done after the propagation, the latter has to be set before the propagation and is possible thanks to the following methods in the class CodingEventDetector:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;buildCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the standard CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildDelayedCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the delayed CodedEvent&lt;br /&gt;
* &amp;lt;code&amp;gt;buildOccurrenceCodedEvent(SpacecraftState, boolean)&amp;lt;/code&amp;gt; to generate the n-th occurrence CodedEvent (n will be a parameter chosen by the user)&lt;br /&gt;
&lt;br /&gt;
In order to use this feature, the delay value and/or the occurrence number must be given as input parameters of the constructor of the class implementing the CodingEventDetector class (for instance GenericCodingEventDetector). The CodedEventsLogger will then be able to read these parameters and handle the generation of standard and not-standard coded events.&lt;br /&gt;
&lt;br /&gt;
Note, in the GenericCodingEventDetector constructor (EventDetector, String, String, boolean, String, double, int), if both parameters delayIn and occurrenceIn are other than 0, the event is saved as a delayed event, not a &amp;quot;Nth occurence of&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
=== When to use Coded events and phenomena ===&lt;br /&gt;
* To build easier time lines of events&lt;br /&gt;
* To manipulate easier phenomena (for example between &amp;quot;starting&amp;quot; and &amp;quot;ending&amp;quot; events) and associate to them specific computations (for example the evolution of the illumination during an eclipse)&lt;br /&gt;
* To apply some [MIS_POSTP_Home post-processing filters]&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
=== Using available events detectors ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Nth occurrence detector ====&lt;br /&gt;
&lt;br /&gt;
Example of propagation stopping at 3rd detected node with event detector overloading:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Initialization&lt;br /&gt;
final AbsoluteDate date = new AbsoluteDate(2003, 1, 1, TimeScalesFactory.getTAI());&lt;br /&gt;
final Orbit orbit = new KeplerianOrbit(7000000, 0.01, 0.1, 0.2, 0.3, 0.4, PositionAngle.TRUE, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
&lt;br /&gt;
// Node detector&lt;br /&gt;
final EventDetector nodeDetector = new NodeDetector(orbit, FramesFactory.getGCRF(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
// Stop at 3rd detected node&lt;br /&gt;
final NthOccurrenceDetector nthOccurrenceDetector = new NthOccurrenceDetector(nodeDetector, 3, Action.STOP) {&lt;br /&gt;
    @Override&lt;br /&gt;
    public Action eventOccurred(SpacecraftState s, boolean increasing, boolean forward) throws PatriusException {&lt;br /&gt;
        super.eventOccurred(s, increasing, forward);&lt;br /&gt;
        if (getCurrentOccurence() == getOccurence()) {&lt;br /&gt;
            return Action.STOP;&lt;br /&gt;
        } else {&lt;br /&gt;
            return Action.CONTINUE;&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// Propagation&lt;br /&gt;
final KeplerianPropagator propagator = new KeplerianPropagator(orbit);&lt;br /&gt;
propagator.addEventDetector(nthOccurrenceDetector);&lt;br /&gt;
propagator.propagate(orbit.getDate().shiftedBy(86400.));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Generating coded events and phenomena ===&lt;br /&gt;
&lt;br /&gt;
==== Examples ====&lt;br /&gt;
&lt;br /&gt;
The CodedEvent instances and Phenomenon instances are meant to be produced using :&amp;lt;br&amp;gt;&lt;br /&gt;
- CodingEventDetector implementations that provide information about events and phenomena,&amp;lt;br&amp;gt;&lt;br /&gt;
- a CodingEventsLogger, that uses the CodingEventDetector instances to build the events and phenomena.&lt;br /&gt;
&lt;br /&gt;
For example, if we want to create a list of CodedEvent objects using a detector of nodes (ascending and descending orbital nodes):&lt;br /&gt;
&lt;br /&gt;
1. Create a new EventDetector (in this case a NodeDetector):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set up the node detector:&lt;br /&gt;
  AbsoluteDate date = new AbsoluteDate(&amp;quot;2000-01-01T12:00:00Z&amp;quot;, TimeScalesFactory.getTT());&lt;br /&gt;
  AbsoluteDate dateF = date.shiftedBy(2* period);&lt;br /&gt;
  Orbit orbit = new KeplerianOrbit(7e6, 0, 0.2, 0, 0, 0.2, PositionAngle.MEAN, FramesFactory.getGCRF(), date, Constants.EGM96_EARTH_MU);&lt;br /&gt;
  NodeDetector node = new NodeDetector(orbit, FramesFactory.getEME2000(), NodeDetector.ASCENDING_DESCENDING);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
2. Create a new generic coding event detector:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // standard event&lt;br /&gt;
  GenericCodingEventDetector nodeDet =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;);&lt;br /&gt;
  // third occurence of event&lt;br /&gt;
  GenericCodingEventDetector nodeDetOcc =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 0., 3);&lt;br /&gt;
  // delayed event (10 seconds here)&lt;br /&gt;
  GenericCodingEventDetector nodeDetDel =&lt;br /&gt;
    new GenericCodingEventDetector(node, &amp;quot;Ascending node&amp;quot;, &amp;quot;Descending node&amp;quot;, true, &amp;quot;Nodes&amp;quot;, 10., 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
3. Create a new CodedEventsLogger and use the &amp;lt;code&amp;gt; monitorDetector &amp;lt;/code&amp;gt; function on the new CodedEventsLogger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  CodedEventsLogger logger = new CodedEventsLogger();&lt;br /&gt;
  // Create an EventDetector object so that event detection functions could be used:&lt;br /&gt;
  EventDetector d = logger.monitorDetector(nodeDet);&lt;br /&gt;
  EventDetector dOcc = logger.monitorDetector(nodeDetOcc);&lt;br /&gt;
  EventDetector dDel = logger.monitorDetector(nodeDetDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
4. Add the EventDetector to the propagator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  propagator.addEventDetector(d);&lt;br /&gt;
  propagator.addEventDetector(dOcc);&lt;br /&gt;
  propagator.addEventDetector(dDel);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
5. Start the propagation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
  // Set the propagator:&lt;br /&gt;
  propagator.setEphemerisMode();&lt;br /&gt;
  propagator.resetInitialState(new SpacecraftState(orbit));&lt;br /&gt;
  // Propagate:&lt;br /&gt;
  propagator.propagate(date0, dateF);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Combination of boolean phenomena ===&lt;br /&gt;
Sometimes an event (a zero of a g function) can be seen as a begin (passing zero from positive to negative or invert) or a end ( other way ) of a phenomena. For example the eclipse event can be the begin (detected when g function goes from positive to negative) or the end (when g function goes from negative to positive) of an eclipse. (cf. [MIS_ORB_Home#HEclipseDetectorandGenericEclipseDetector Eclipse detector].)&lt;br /&gt;
&lt;br /&gt;
One can choose to create an event as a combination of these phenomena, for example a station visibility outside an interference period. In this case a user can create a detector as a combination of existing detectors.&lt;br /&gt;
&lt;br /&gt;
The user simply has to provide the following parameters :&lt;br /&gt;
#First detector and the way to use it (g is positive or negative during the phenomena to combine)&lt;br /&gt;
#Second detector and the way to use it &lt;br /&gt;
#How to combine the phenomenom : both are during phenomena (will be detected as the minimum of the two g function) or at least one (will be detected as the maximum of the two g function) is during phenomena &lt;br /&gt;
&lt;br /&gt;
Once a new detector have been created in this way, it is possible to combine it with another one and so on.&lt;br /&gt;
&lt;br /&gt;
For example the [MIS_SENSORS_Home#HCentralBodyMaskCircularFOVDetector CentralBodyMaskCircularFOVDetector] detects when a target is in a circular field of view and outside of an eclipse, that is translated by :&lt;br /&gt;
&lt;br /&gt;
* Outside of eclipse : when EllipsoidEclipseDetecor g function is positive &lt;br /&gt;
* Inside circular field of view : when CircularFieldOfView g function is positive&lt;br /&gt;
&lt;br /&gt;
So the following code example :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// EclipseDetector&lt;br /&gt;
final EclipseDetector eed = new EclipseDetector(targetPVP, targetRadius, spheroEarth, 1., MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// CircularFOVDetector&lt;br /&gt;
final CircularFieldOfViewDetector cfvd = new CircularFieldOfViewDetector(targetPVP, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CombinedPhenomenaDetector cbmcfovd2 = new CombinedPhenomenaDetector(eed, true, cfvd, true, true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
is equivalent to CentralBodyMaskCircularFOVDetector :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;java&amp;quot;&amp;gt;&lt;br /&gt;
// Detector in field of view and outside eclipse&lt;br /&gt;
final CentralBodyMaskCircularFOVDetector cbmcfovd = &lt;br /&gt;
new CentralBodyMaskCircularFOVDetector(targetPVP, targetRadius, spheroEarth, false, fovDir, halfAp, MAXCHK, THRS);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Contents ==&lt;br /&gt;
=== Interfaces ===&lt;br /&gt;
==== Interfaces events detection ====&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.6}}/fr/cnes/sirius/patrius/propagation/events/EventDetector.html EventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/CodingEventDetector.html CodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiEventDetector&lt;br /&gt;
|This interface represents an event finder in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiEventDetector.html MultiEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodingEventDetector&lt;br /&gt;
|This interface is an extended event finder, that is needed to create CodedEvent and Phenomenon instances in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/multi/MultiCodingEventDetector.html MultiCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Classes ===&lt;br /&gt;
==== Classes containing the general functions to detect events ====&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;
| AbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/AbstractDetector.html AbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiAbstractDetector&lt;br /&gt;
|This class contains the methods shared by all events detectors in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/multi/MultiAbstractDetector.html MultiAbstractDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedEventDetector&lt;br /&gt;
|This class adapts Patrius event detectors to math EventHandler object.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/AdaptedEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMonoEventDetector&lt;br /&gt;
|This class adapts Patrius mono event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMonoEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| AdaptedMultiEventDetector&lt;br /&gt;
|This class adapts Patrius multi event detectors to math EventHandler object in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/multi/AdaptedMultiEventDetector.html AdaptedEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| CombinedPhenomenaDetector&lt;br /&gt;
|This class handles events representing the combination of two boolean phenomena.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/CombinedPhenomenaDetector.html CombinedPhenomenaDetector]&lt;br /&gt;
|-&lt;br /&gt;
| NthOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a certain occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/NthOccurrenceDetector.html NthOccurrenceDetector]&lt;br /&gt;
|-&lt;br /&gt;
| IntervalOccurrenceDetector&lt;br /&gt;
|This class represents an event detector that will detect a interval occurrence of a specified event.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/propagation/events/IntervalOccurrenceDetector.html IntervalOccurrenceDetector]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Classes for the generation of lists of events and phenomena ====&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;
| CodedEvent&lt;br /&gt;
|This class implements coded events (a light and simple representation of events as generated by Patrius event detectors ).&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/CodedEvent.html CodedEvent]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/CodedEventsList.html CodedEventsList]&lt;br /&gt;
|-&lt;br /&gt;
| Phenomenon&lt;br /&gt;
|This class implements the notion of a phenomenon : a state defined by a starting event and an ending event.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/Phenomenon.html Phenomenon]&lt;br /&gt;
|-&lt;br /&gt;
| PhenomenaList&lt;br /&gt;
|This class implements a list of coded events.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/PhenomenaList.html PhenomenaList]&lt;br /&gt;
|-&lt;br /&gt;
| CodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/CodedEventsLogger.html CodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| MultiCodedEventsLogger&lt;br /&gt;
|This class builds instances of CodedEventsList and PhenomenaList during a propagation in multi propagation case.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/multi/MultiCodedEventsLogger.html MultiCodedEventsLogger]&lt;br /&gt;
|-&lt;br /&gt;
| GenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/GenericCodingEventDetector.html GenericCodingEventDetector]&lt;br /&gt;
|-&lt;br /&gt;
| MultiGenericCodingEventDetector&lt;br /&gt;
|This class is a generic implementation of the CodingEventDetector interface in multi propagation case, mainly for testing purposes - but it is usable as is.&lt;br /&gt;
|[{{JavaDoc4.6}}/fr/cnes/sirius/patrius/events/multi/MultiGenericCodingEventDetector.html MultiGenericCodingEventDetector]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.6_Mission]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
	<entry>
		<id>https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Matrices&amp;diff=3608</id>
		<title>User Manual 4.13 Matrices</title>
		<link rel="alternate" type="text/html" href="https://patrius.cnes.fr/index.php?title=User_Manual_4.13_Matrices&amp;diff=3608"/>
		<updated>2023-12-19T16:11:57Z</updated>

		<summary type="html">&lt;p&gt;Admin : &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.13}}/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.13}}/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;
&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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/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.13}}/fr/cnes/sirius/patrius/math/linear/SingularValueDecomposition.html ...]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[Category:User_Manual_4.13_Mathematics]]&lt;/div&gt;</summary>
		<author><name>Admin</name></author>
	</entry>
</feed>