Files
thesis/LaTeX/trajectory_optimization.tex
2022-03-09 21:22:36 -07:00

217 lines
13 KiB
TeX

\chapter{Trajectory Optimization} \label{traj_optimization}
\section{Solving Boundary Value Problems}
This section probably needs more work.
\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.
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
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.
\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.
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.
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
to improve the convergence speed and both have been ported for use in a number of
programming languages, including in Julia, which was used for this project.
This is by no means an exhaustive list, as there are a number of other optimization
libraries that utilize a massive number of different algorithms. For the most part, the
libraries that port these are quite modular in the sense that multiple algorithms can be
tested without changing much source code.
\subsubsection{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
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.
In this case, the IPOPT algorithm was used, not as an optimizer, but as a solver. For
reasons that will be explained in the algorithm description in Section~\ref{algorithm} it
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}
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}.
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{fig/single_shoot}
\caption{Visualization of a single shooting technique over a trajectory arc}
\label{single_shoot_fig}
\end{figure}
In this example, the initial trajectory is the green arc, which contains a certain
control thrust $\Delta V_{init}$ and is propagated for a certain amount of time and
results in the end state $x_{init}$. The target state $x_{final}$ can be achieved by
varying the control and propagating forward in time until this final state is
achieved. This type of shooting algorithm can be quite useful for simple cases such
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.
\begin{figure}[H]
\centering
\includegraphics[width=\textwidth]{fig/multiple_shoot}
\caption{Visualization of a multiple shooting technique over a trajectory arc}
\label{multiple_shoot_fig}
\end{figure}
In this example, it can be seen that there are now more constraints (places where
the states need to match up, creating an $x_{error}$ term) as well as control
variables (the $\Delta V$ terms in the figure). This technique actually lends itself
very well to low-thrust arcs and, in fact, Sims-Flanagan Transcribed low-thrust arcs
in particular, because there actually are control thrusts to be optimized at a
variety of different points along the orbit. This is, however, not an exhaustive
description of ways that multiple shooting can be used to optimize a trajectory,
simply the most convenient for low-thrust arcs.
\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 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.