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