/* Copyright 2002-2017 CS Systèmes d'Information
* Licensed to CS Systèmes d'Information (CS) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* CS licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
*
* This package provides classes to represent orbits.
*
* <p>
* It builds the base of all the other space mechanics tools.
* It provides an abstract class, {@link org.orekit.orbits.Orbit}, extended
* in four different ways corresponding to the different possible representations
* of orbital parameters. As of version 3.0, {@link org.orekit.orbits.KeplerianOrbit
* keplerian}, {@link org.orekit.orbits.CircularOrbit circular}, {@link
* org.orekit.orbits.EquinoctialOrbit equinoctial} and {@link
* org.orekit.orbits.CartesianOrbit cartesian} representations are supported.
* </p>
*
* <h3>Design History</h3>
* <p>
* Early designs for the orbit package were much more complex than the current design.
* Looking back at these designs, they tried to do far too much in a single class and
* resulted in huge systems which were both difficult to understand, difficult to
* use, difficult to maintain and difficult to reuse. They mixed several different notions:
* <ul>
* <li>representation (keplerian, cartesian ...)</li>
* <li>kinematics (parameters) and dynamics (propagation)</li>
* <li>physical models (complete or simplified force models, often implicitly assumed with no real reference)</li>
* <li>filtering (osculating and centered or mean parameters, related to some models)</li>
* </ul>
* <p> They also often forgot all frames issues.
*
* <p>
* The current design has been reached by progressively removing spurious layers and
* setting them apart in dedicated packages. All these notions are now still handled,
* but all in different classes that are cleanly linked to each other. Without knowing
* it, we have followed Antoine de Saint Exupéry's saying:
* </p>
* <p>
* <i>It seems that perfection is reached not when there is nothing left to add, but
* when there is nothing left to take away</i>.
* </p>
*
* <p>
* The current design is not perfect, of course, but it is easy to understand, easy to use,
* easy to maintain and reusable.
* </p>
*
* <h3>Current state versus evolving state</h3>
* <p>
* From the early design, the various orbit classes retained only the kinematical
* notions at a single time. They basically represent the current state, and
* serve as data holder. Most of methods provided by these orbits classes are
* getters. Some of them (the non-ambiguous ones that must be always available) are
* defined in the top {@link org.orekit.orbits.Orbit Orbit} abstract class
* ({@link org.orekit.orbits.Orbit#getA() Orbit.getA()}, {@link
* org.orekit.orbits.Orbit#getDate() Orbit.getDate()}, {@link
* org.orekit.orbits.Orbit#getPVCoordinates() Orbit.getPVCoordinates()} ...). The
* more specific ones depending on the type of representation are only defined
* in the corresponding class ({@link
* org.orekit.orbits.CircularOrbit#getCircularEx() CircularOrbit.getCircularEx()}
* for example).
* </p>
*
* <p>
* It is important to note that some parameters are available even if they seem
* out of place with regard to the representation. For example the semi-major axis is
* available even in cartesian representation and the position/velocity even in
* non-cartesian representation. This choice is a pragmatic one. These parameters
* are really used in many places in algorithms, for computation related to
* period (setting a convergence threshold or a search interval) or geometry
* (computing swath or lighting). A side-effect of this choice is that all orbits
* do include a value for μ, the acceleration coefficient of the central body.
* This value is only used for the representation of the parameters and for conversion
* purposes, it is <em>not</em> always the same as the value used for propagation (but
* of course, using different values should be done with care).
* </p>
*
* <p>
* Orbits also include a reference to a defining frame. This allows transparent
* conversions to other frames without having to externally preserve a mapping
* between orbits and their frame: it is already done. As an example, getting
* the position and velocity of a satellite given by a circular orbit in a ground
* station frame is simply a matter of calling <tt>orbit.getPVCoordinates(stationFrame)</tt>,
* regardless of the frame in which the orbit is defined (GCRF, EME2000, ...).
* </p>
*
* <p>
* Since orbits are used everywhere in space dynamics applications and since we
* have chosen to restrict them to a simple state holder, all orbit classes are
* guaranteed to be immutable. They are small objects and they are shared by
* many parts. This change was done in 2006 and tremendously simplified the
* library and the users applications that were previously forced to copy orbits
* as an application of defensive programming, and that were plagued by difficult
* to find bugs when they forgot to copy.
* </p>
*
* <p>
* For orbit evolution computation, this package is not sufficient. There is a
* need to include notions of dynamics, forces models, propagation algorithms ...
* The entry point for this is the {@link org.orekit.propagation.Propagator Propagator}
* interface.
* </p>
*
* <h3>Representations Conversions</h3>
* <p>
* All representations can be converted into all other ones. No error is triggered
* if some conversion is ambiguous (like converting a perfectly circular orbit from
* cartesian representation to keplerian representation, with an ambiguity on the
* perigee argument). This design choice is the result of <strong>many</strong>
* different attempts and pragmatic considerations. The rationale is that from a
* physical point of view, there is no singularity. The singularity is only introduced
* by a choice of <em>representations</em>. Even considering this, it appears that
* rather than having a parameter with <em>no</em> realistic value, there is an
* <em>infinite</em> possible number of values that all represent the same physical
* orbit. Orekit simply does an arbitrary choice, often choosing simply the value 0.
* In our example case, we would then get a converted orbit with a 0 perigee argument.
* This choice is valid, just as any other choice (π/2, π, whatever ...) would
* have been valid, in the sense that it <i>does</i> represent correctly the orbit
* and when converted back to the original non-ambiguous representation it does give
* the right result.
* </p>
*
* <p>
* We therefore consider it is the responsibility of the user to be aware of the correct
* definition of the different representations and of the singularities relative to each
* one of them. If the user really needs to do some conversion (for example to provide
* an orbit as Two-Lines Elements later on, remembering than TLE do use keplerian-like
* parameters), then he can do so.
* </p>
*
* <p>
* The way conversion is handled in OREKIT is very simple and allows easy and transparent
* processing. All four parameters type extend the abstract class {@link org.orekit.orbits.Orbit},
* and every propagation algorithm, be it analytical or numerical, use this abstract class as a
* parameter, even if internally it relies on a specific representation. As an example, the
* {@link org.orekit.propagation.analytical.EcksteinHechlerPropagator Eckstein-Hechler propagator}
* is defined in terms of {@link org.orekit.orbits.CircularOrbit circular orbit} only. So
* there is an implicit conversion done at propagator initialization time.
* </p>
*
* @author Luc Maisonobe
* @author Fabien Maussion
* @author Véronique Pommier-Maurussane
*
*/
package org.orekit.orbits;