Getting pretty close on the final review

This commit is contained in:
Connor
2022-03-13 23:34:38 -06:00
parent 7fcdb26ab7
commit e36b99b84c
22 changed files with 2386 additions and 623 deletions

View File

@@ -1,61 +1,57 @@
\chapter{Trajectory Optimization} \label{traj_optimization}
\section{Solving Boundary Value Problems}
\section{Optimization of Boundary Value Problems}
This section probably needs more work.
An approach is necessary, in trajectory optimization and many other fields, to optimize
highly non-linear, unpredictable systems such as this. The field that developed to
approach this problem is known as Non-Linear Programming (NLP) Optimization.
\section{Optimization}
\subsection{Non-Linear Problem Optimization}
Now we can consider the formulation of the problem in a more useful way. For instance, given a
desired final state in position and velocity we can relatively easily determine the initial
state necessary to end up at that desired state over a pre-defined period of time by solving
Kepler's equation. In fact, this is often how impulsive trajectories are calculated since,
other than the impulsive thrusting event itself, the trajectory is entirely natural.
However, often in trajectory design we want to consider a number of other inputs. For
instance, a low thrust profile, a planetary flyby, the effects of rotating a solar panel on
solar radiation pressure, etc. Once these inputs have been accepted as part of the model, the
system is generally no longer analytically solvable, or, if it is, is too complex to calculate
directly.
Therefore an approach is needed, in trajectory optimization and many other fields, to optimize
highly non-linear, unpredictable systems such as this. The field that developed to approach
this problem is known as Non-Linear Problem (NLP) Optimization.
A Non-Linear Programming Problem is defined by an attempt to optimize a function
$f(\vec{x})$, subject to constraints $\vec{g}(\vec{x}) \le 0$ and $\vec{h}(\vec{x}) = 0$
where $n$ is a positive integer, $x$ is any subset of $R^n$, $g$ and $h$ can be vector
valued functions of any size, and at least one of $f$, $g$, and $h$ must be non-linear.
There are, however, two categories of approaches to solving an NLP. The first category,
indirect methods, involve declaring a set of necessary and/or sufficient conditions for declaring
the solution optimal. These conditions then allow the non-linear problem (generally) to be
reformulated as a two point boundary value problem. Solving this boundary value problem can
provide a control law for the optimal path. Indirect approaches for spacecraft trajectory
indirect methods, involve declaring a set of necessary and/or sufficient conditions for
optimality. These conditions then allow the problem to be reformulated as a two point
boundary value problem. Solving this boundary value problem involves determining a
control law for the optimal path. Indirect approaches for spacecraft trajectory
optimization have given us the Primer Vector Theory\cite{jezewski1975primer}.
The other category is the direct methods. In a direct optimization problem, the cost
function itself is calculated to provide the optimal solution. The problem is usually
thought of as a collection of dynamics and controls. Then these controls can be modified
to minimize the cost function. A number of tools have been developed to optimize NLPs
via this direct method in the general case. For this particular problem, direct
approaches were used as the low-thrust interplanetary system dynamics adds too much
complexity to quickly optimize indirectly and the individual optimization routines
needed to proceed as quickly as possible.
function itself provides a value that an iterative numerical optimizer can measure
itself against. The optimal solution is then found by varying the inputs $x$ until the
cost function is reduced to a minimum value, often determined by its derivative
jacobian. A number of tools have been developed to optimize NLPs via this direct method
in the general case.
Both of these methods have been applied to the problem of low-thrust interplanetary
trajectory optimization \cite{Casalino2007IndirectOM} to find local optima over
low-thrust control laws. It has often been found that indirect methods are more
difficult to converge and require a better initial guess than the direct methods.
However, they also require less parameters to describe the trajectory, since the
solution of a boundary value problem doesn't require discretization of the control
states.
In this implementation, robustness is incredibly valuable, as the Monotonic Basin
Hopping algorithm, discussed later, is leveraged to attempt to find all minima basins in
the solution space by ``hopping'' around with different initial guesses. It is,
therefore, important that the optimization routine be robust to poor initial guesses.
Therefore, a direct optimization method was leveraged by transcribing the problem into
an NLP and using IPOPT to find the local minima.
\subsubsection{Non-Linear Solvers}
For these types of non-linear, constrained problems, a number of tools have been developed
that act as frameworks for applying a large number of different algorithms. This allows for
simple testing of many different algorithms to find what works best for the nuances of the
problem in question.
One of the most common of these NLP optimizers is SNOPT\cite{gill2005snopt}, which
is a proprietary package written primarily using a number of Fortran libraries by
the Systems Optimization Laboratory at Stanford University. It uses a sparse
sequential quadratic programming approach.
One of the most common packages for the optimization of NLP problems is
SNOPT\cite{gill2005snopt}, which is a proprietary package written primarily using a
number of Fortran libraries by the Systems Optimization Laboratory at Stanford
University. It uses a sparse sequential quadratic programming algorithm as its
back-end optimization scheme.
Another common NLP optimization packages (and the one used in this implementation)
is the Interior Point Optimizer or IPOPT\cite{wachter2006implementation}. It can be
used in much the same way as SNOPT and uses an Interior Point Linesearch Filter
Method and was developed as an open-source project by the organization COIN-OR under
the Eclipse Public License.
is the Interior Point Optimizer or IPOPT\cite{wachter2006implementation}. It uses
an Interior Point Linesearch Filter Method and was developed as an open-source
project by the organization COIN-OR under the Eclipse Public License.
Both of these methods utilize similar approaches to solve general constrained non-linear
problems iteratively. Both of them can make heavy use of derivative Jacobians and Hessians
@@ -67,14 +63,14 @@
libraries that port these are quite modular in the sense that multiple algorithms can be
tested without changing much source code.
\subsubsection{Linesearch Method}
\subsubsection{Interior Point Linesearch Method}
As mentioned above, this project utilized IPOPT which leveraged an Interior Point
Linesearch method. A linesearch algorithm is one which attempts to find the optimum
of a non-linear problem by first taking an initial guess $x_k$. The algorithm then
determines a step direction (in this case through the use of either automatic
differentiation or finite differencing to calculate the derivatives of the
non-linear problem) and a step length. The linesearch algorithm then continues to
cost function) and a step length. The linesearch algorithm then continues to
step the initial guess, now labeled $x_{k+1}$ after the addition of the ``step''
vector and iterates this process until predefined termination conditions are met.
@@ -83,15 +79,42 @@
was sufficient merely that the non-linear constraints were met, therefore optimization (in
the particular step in which IPOPT was used) was unnecessary.
\subsubsection{Multiple-Shooting Algorithms}
\subsubsection{Shooting Schemes for Solving a Two-Point Boundary Value Problem}
Now that we have software defined to optimize non-linear problems, what remains is
determining the most effective way to define the problem itself. The most simple
form of a trajectory optimization might employ a single shooting algorithm, which
propagates a state, given some control variables forward in time to the epoch of
interest. The controls over this time period are then modified in an iterative
process, using the NLP optimizer, until the target state and the propagated state
matches. This technique can be visualized in Figure~\ref{single_shoot_fig}.
One straightforward approach to trajectory corrections is a single shooting
algorithm, which propagates a state, given some control variables forward in time to
the epoch of interest. The controls over this time period are then modified in an
iterative process, using the correction scheme, until the target state and the
propagated state matches.
As an example, we can consider the Two-Point Boundary Value Problem (TPBVP) defined
by:
\begin{equation}
y''(t) = f(t, y(t), y'(t)), y(t_0) = y_0, y(t_f) = y_f
\end{equation}
\noindent
We can then redefine the problem as an initial-value problem:
\begin{equation}
y''(t) = f(t, y(t), y'(t)), y(t_0) = y_0, y'(t_0) = x
\end{equation}
\noindent
With $y(t,x)$ as a solution to that problem. Furthermore, if $y(t_f, x) = y_f$, then
the solution to the initial-value problem is also the solution to the TPBVP as well.
Therefore, we can use a root-finding algorithm, such as the bisection method,
Newton's Method, or even Laguerre's method, to find the roots of:
\begin{equation}
F(x) = y(t_f, x) - y_f
\end{equation}
\noindent
To find the solution to the IVP at $x_0$, $y(t_f, x_0)$ which also provides a
solution to the TPBVP. This technique for solving a Two-Point Boundary Value
Problem can be visualized in Figure~\ref{single_shoot_fig}.
\begin{figure}[H]
\centering
@@ -108,15 +131,15 @@
as this one.
However, some problems require the use of a more flexible algorithm. In these cases,
sometimes a multiple-shooting algorithm can provide that flexibility and allow the
NLP solver to find the optimal control faster. In a multiple shooting algorithm,
rather than having a single target point at which the propagated state is compared,
the target orbit is broken down into multiple arcs, then end of each of which can be
seen as a separate target. At each of these points we can then define a separate
control. The end state of each arc and the beginning state of the next must then be
equal for a valid arc, as well as the final state matching the target final state.
This changes the problem to have far more constraints, but also increased freedom
due to having more control variables.
sometimes a multiple-shooting algorithm can provide that flexibility and reduced
sensitivity. In a multiple shooting algorithm, rather than having a single target
point at which the propagated state is compared, the target orbit is broken down
into multiple arcs, then end of each of which can be seen as a separate target. At
each of these points we can then define a separate control, which may include the
states themselves. The end state of each arc and the beginning state of the next
must then be equal for a valid arc (with the exception of velocity discontinuities
if allowed for maneuvers at that point), as well as the final state matching the
target final state.
\begin{figure}[H]
\centering
@@ -136,81 +159,21 @@
\section{Monotonic Basin Hopping Algorithms}
% TODO: This needs to be rewritten to be general, then add the appropriate specific
% implementation details to the approach chapter
The techniques discussed thus far are useful for finding local optima. However, we would
also like to traverse the search space in an attempt to determine the global optima over the
entire search space. One approach to this would be to discretize the search space and test
each point as an input to a local optimization scheme. In order to achieve sufficient
coverage of the search space, however, this often requires long processing times in a
high-dimensional environment.
The aim of a monotonic basin hopping algorithm is to provide an efficient method for
completely traversing a large search space and providing many seed values within the
space for an ''inner loop`` solver or optimizer. These solutions are then perturbed
slightly, in order to provide higher fidelity searching in the space near valid
solutions in order to fully explore the vicinity of discovered local minima. This
makes it an excellent algorithm for problems with a large search space, including
several clusters of local minima, such as this application.
The algorithm contains two loops, the size of each of which can be independently
modified (generally by specifying a ''patience value``, or number of loops to
perform, for each) to account for trade-offs between accuracy and performance depending on
mission needs and the unique qualities of a certain search space.
The first loop, the ''search loop``, first calls the random mission generator. This
generator produces two random missions as described in
Section~\ref{random_gen_section} that differ only in that one contains random flyby
velocities and control thrusts and the other contains Lambert's-solved flyby
velocities and zero control thrusts. For each of these guesses, the NLP solver is
called. If either of these mission guesses have converged onto a valid solution, the
lower loop, the ''drill loop`` is entered for the valid solution. After the
convergence checks and potentially drill loops are performed, if a valid solution
has been found, this solution is stored in an archive. If the solution found is
better than the current best solution in the archive (as determined by a
user-provided cost function of fuel usage, $C_3$ at launch, and $v-\infty$ at
arrival) then the new solution replaces the current best solution and the loop is
repeated. Taken by itself, the search loop should quickly generate enough random
mission guesses to find all ''basins`` or areas in the solution space with valid
trajectories, but never attempts to more thoroughly explore the space around valid
solutions within these basins.
The drill loop, then, is used for this purpose. For the first step of the drill
loop, the current solution is saved as the ''basin solution``. If it's better than
the current best, it also replaces the current best solution. Then, until the
stopping condition has been met (generally when the ''drill counter`` has reached
the ''drill patience`` value) the current solution is perturbed slightly by adding
or subtracting a small random value to the components of the mission.
The performance of this perturbation in terms of more quickly converging upon the
true minimum of that particular basin, as described in detail by
Englander\cite{englander2014tuning}, is highly dependent on the distribution
function used for producing these random perturbations. While the intuitive choice
of a simple Gaussian distribution would make sense to use, it has been found that a
long-tailed distribution, such as a Cauchy distribution or a Pareto distribution is
more robust in terms of well chose boundary conditions and initial seed solutions as
well as more performant in time required to converge upon the minimum for that basin.
Because of this, the perturbation used in this implementation follows a
bi-directional, long-tailed Pareto distribution generated by the following
probability density function:
\begin{equation}
1 +
\left[ \frac{s}{\epsilon} \right] \cdot
\left[ \frac{\alpha - 1}{\frac{\epsilon}{\epsilon + r}^{-\alpha}} \right]
\end{equation}
Where $s$ is a random array of signs (either plus one or minus one) with dimension
equal to the perturbed variable and bounds of -1 and 1, $r$ is a uniformly
distributed random array with dimension equal to the perturbed variable and bounds
of 0 and 1, $\epsilon$ is a small value (nominally set to $1e-10$), and $\alpha$ is
a tuning parameter to determine the size of the tails and width of the distribution
set to $1.01$, but easily tunable.
The perturbation function then steps through each parameter of the mission,
generating a new guess with the parameters modified by the Pareto distribution.
After this perturbation, the NLP solver is then called again to find a valid
solution in the vicinity of this new guess. If the solution is better than the
current basin solution, it replaces that value and the drill counter is reset to
zero. If it is better than the current total best, it replaces that value as well.
Otherwise, the drill counter increments and the process is repeated. Therefore, the
drill patience allows the mission designer to determine a maximum number of
iterations to perform without improvement in a row before ending the drill loop.
This process can be repeated essentially ''search patience`` number of times in
order to fully traverse all basins.
To solve this problem, a technique was described by Wales and Doye in 1997
\cite{wales1997global} called a basin-hopping algorithm. This algorithm performs a random
perturbation of the input states, optimizes using a local optimizer, then either accepts the
new coordinates and performs a further perturbation, or rejects them and tests a new set of
randomly-generated inputs.
This allows the algorithm to test many different regions of the search space in order to
determine which ``basins'' contain local optima. If these local optima are found, the
algorithm can attempt to improve the local optima based on parameters defined by the
algorithm designer (by perturbation and re-applying the local optimization scheme) or search
for a new basin in the search space.