\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.

