# MatthewPeterKelly/OptimTraj

Fix small error in the user guide for OptimTraj

There were two instances in the user guide where the order of the
equality and inequality constraints were swapped. This commit
fixes the two mistakes.

This commit also removes some whitespace in the .tex files and
adds a reference to my primary tutorial paper at the end of the
user guide.
 @@ -10,7 +10,7 @@ \subsection{Notation} \texttt{size($t$) = [1, $N_t$]}, \\ \texttt{size($\bm{x}$) = [$N_x$, $N_t$]}, \\ \texttt{size($\bm{u}$) = [$N_u$, $N_t$]}, \\ \texttt{size($\bm{x}_0$) = size($\bm{x}_F$) = [$N_x$, 1]}. \texttt{size($\bm{x}_0$) = size($\bm{x}_F$) = [$N_x$, 1]}. \subsection{Constructing the Input to OptimTraj} @@ -35,64 +35,64 @@ \subsubsection*{\tc{problem}.\hc{func}} \item \tc{problem.}\hc{func.pathCst} ${\bm: \quad \to \quad }$ \tc{$[\bm{C}_P^a, \bm{C}_P^b ]$ = }\hc{pathCst}\tc{($t$,$\bm{x}$,$\bm{u}$)} \\ where $\bm{C}_P^a=\bm{0}$ is path equality constraint, and $\bm{C}_P^b \leq \bm{0}$ is the path inequality constraint. Either may be left empty \texttt{[ ]}. The number of columns in each must equal that of time, but the number of rows in each is arbitrary (it just must be consistent between function calls). \\ where $\bm{C}_P^a\leq\bm{0}$ is path inequality constraint, and $\bm{C}_P^b = \bm{0}$ is the path equality constraint. Either may be left empty \texttt{[ ]}. The number of columns in each must equal that of time, but the number of rows in each is arbitrary (it just must be consistent between function calls). \item \tc{problem.}\hc{func.bndObj} ${\bm: \quad \to \quad }$ \tc{$J_B$ = }\hc{bndObj}\tc{($t_0$,$\bm{x}_0$,$t_F$,$\bm{x}_F$)} \\ where $J_B$ is a scalar cost associated with the boundary points of the trajectory. \\ where $J_B$ is a scalar cost associated with the boundary points of the trajectory. \item \tc{problem.}\hc{func.bndCst} ${\bm: \quad \to \quad }$ \tc{$[\bm{C}_B^a, \bm{C}_B^b]$ = }\hc{bndCst}\tc{($t_0$,$\bm{x}_0$,$t_F$,$\bm{x}_F$)} \\ where $\bm{C_B^a}=\bm{0}$ is boundary equality constraint, and $\bm{C}_B^b \leq \bm{0}$ is the boundary inequality constraint. Either may be left empty \texttt{[]}. Each is a column vector of arbitrary length, provided that it is consistent between function calls. \\ where $\bm{C_B^a}\leq\bm{0}$ is boundary inequality constraint, and $\bm{C}_B^b = \bm{0}$ is the boundary equality constraint. Either may be left empty \texttt{[]}. Each is a column vector of arbitrary length, provided that it is consistent between function calls. \end{itemize} \subsubsection*{\tc{problem}.\hc{bounds}} The bounds struct provides constant bounds on the state and control along the trajectory, as well as the time and state on the boundaries. All fields are either scalar or a column vector, and can be omitted (or left empty) if not needed. If you need to include a bound on only part of the state or control, then set the remaining entries to $\pm\infty$. For example: \hc{bounds.state.low}\tc{ = [0;-inf;0;-inf];} sets a bound only for the first and third element of the state vector. All entries relating to time are scalar, entries relating to state $\bm{x}$ are column vectors of length $N_x$, and entries relating to control $\bm{u}$ are column vectors of length $N_u$. \begin{itemize} \setlength\itemsep{-0.1em} \item \tc{problem.}\hc{bounds.initialTime.low}\tc{ = }$t_0^-$ \item \tc{problem.}\hc{bounds.initialTime.upp}\tc{ = }$t_0^+$ \item \tc{problem.}\hc{bounds.finalTime.low}\tc{ = }$t_F^-$ \item \tc{problem.}\hc{bounds.finalTime.upp}\tc{ = }$t_F^+$ \item \tc{problem.}\hc{bounds.initialState.low}\tc{ = }$\bm{x}_0^-$ \item \tc{problem.}\hc{bounds.initialState.upp}\tc{ = }$\bm{x}_0^+$ \item \tc{problem.}\hc{bounds.finalState.low}\tc{ = }$\bm{x}_F^-$ \item \tc{problem.}\hc{bounds.finalState.upp}\tc{ = }$\bm{x}_F^+$ \item \tc{problem.}\hc{bounds.state.low}\tc{ = }$\bm{x}^-$ \item \tc{problem.}\hc{bounds.state.upp}\tc{ = }$\bm{x}^+$ \item \tc{problem.}\hc{bounds.control.low}\tc{ = }$\bm{u}^-$ \item \tc{problem.}\hc{bounds.control.upp}\tc{ = }$\bm{u}^+$ \item \tc{problem.}\hc{bounds.initialTime.low}\tc{ = }$t_0^-$ \item \tc{problem.}\hc{bounds.initialTime.upp}\tc{ = }$t_0^+$ \item \tc{problem.}\hc{bounds.finalTime.low}\tc{ = }$t_F^-$ \item \tc{problem.}\hc{bounds.finalTime.upp}\tc{ = }$t_F^+$ \item \tc{problem.}\hc{bounds.initialState.low}\tc{ = }$\bm{x}_0^-$ \item \tc{problem.}\hc{bounds.initialState.upp}\tc{ = }$\bm{x}_0^+$ \item \tc{problem.}\hc{bounds.finalState.low}\tc{ = }$\bm{x}_F^-$ \item \tc{problem.}\hc{bounds.finalState.upp}\tc{ = }$\bm{x}_F^+$ \item \tc{problem.}\hc{bounds.state.low}\tc{ = }$\bm{x}^-$ \item \tc{problem.}\hc{bounds.state.upp}\tc{ = }$\bm{x}^+$ \item \tc{problem.}\hc{bounds.control.low}\tc{ = }$\bm{u}^-$ \item \tc{problem.}\hc{bounds.control.upp}\tc{ = }$\bm{u}^+$ \end{itemize} \subsubsection*{\tc{problem}.\hc{guess}} The guess struct provides the optimization with an initialization. All fields are mandatory. Internally, \texttt{optimTraj} uses the guess struct to determine the dimension of the state and control. The number of grid points in the guess struct does not correspond to the number of grid points in the solution. Instead, \texttt{optimTraj} constructs the solution grid using information from the options struct, and then uses interpolation of the data in guess to evaluate the initial value of the solution grid. \begin{itemize} \setlength\itemsep{-0.1em} \item \tc{problem.}\hc{guess.time}\tc{ = }$t_g \qquad$ \texttt{size($t_g$) = [1, $N_g$]} \item \tc{problem.}\hc{guess.state}\tc{ = }$\bm{x}_g \qquad$ \texttt{size($\bm{x}_g$) = [$N_x$, $N_g$]} \item \tc{problem.}\hc{guess.time}\tc{ = }$t_g \qquad$ \texttt{size($t_g$) = [1, $N_g$]} \item \tc{problem.}\hc{guess.state}\tc{ = }$\bm{x}_g \qquad$ \texttt{size($\bm{x}_g$) = [$N_x$, $N_g$]} \item \tc{problem.}\hc{guess.control}\tc{ = }$\bm{u}_g \qquad$ \texttt{size($\bm{u}_g$) = [$N_u$, $N_g$]} \end{itemize} \subsubsection*{\tc{problem}.\hc{options}} The options struct provides options for both \texttt{optimTraj} and \texttt{fmincon}, which is called by \texttt{optimTraj} to solve the underlying nonlinear program. All fields, including \hc{options} itself may be omitted. If \tc{problem}.\hc{options} is a struct array, then \texttt{optimTraj} will run a sequence of trajectory optimizations, one for each element of the options struct array. The solution to each sub-problem is used to initialize the following. This is used for manual mesh refinement, and is illustrated in several of the example problems in the \texttt{demo/} directory. The options struct provides options for both \texttt{optimTraj} and \texttt{fmincon}, which is called by \texttt{optimTraj} to solve the underlying nonlinear program. All fields, including \hc{options} itself may be omitted. If \tc{problem}.\hc{options} is a struct array, then \texttt{optimTraj} will run a sequence of trajectory optimizations, one for each element of the options struct array. The solution to each sub-problem is used to initialize the following. This is used for manual mesh refinement, and is illustrated in several of the example problems in the \texttt{demo/} directory. \par The \texttt{trapezoid}, \texttt{hermiteSimpson}, and \texttt{rungeKutta} methods work without any external dependencies. The \texttt{chebyshev} method is written entirely in \texttt{optimTraj}, but relies on ChebFun\cite{Driscoll2014} for computing some of the low-level implementation details for the orthogonal polynomials. ChebFun is easy to download and install from \texttt{https://github.com/chebfun/chebfun}. The final method, \texttt{gpops} is actually just a wrapper for the professional software GPOPS-II\cite{Patterson2013}, for which a license can be obtained from \texttt{http://www.gpops2.com/}. \par Each method has a single field devoted to it in the options struct. The options in each of these fields are used exclusively by the method for which they are named. This allows for method-specific options, like the number of sub-steps in the multiple shooting method. The field \tc{problem}.\hc{options.gpops} is passed to GPOPS-II as the \tc{setup} struct, allowing the user to specify low-level options in GPOPS-II. \par Each method has a single field devoted to it in the options struct. The options in each of these fields are used exclusively by the method for which they are named. This allows for method-specific options, like the number of sub-steps in the multiple shooting method. The field \tc{problem}.\hc{options.gpops} is passed to GPOPS-II as the \tc{setup} struct, allowing the user to specify low-level options in GPOPS-II. \begin{itemize} \setlength\itemsep{-0.1em} \item \tc{problem.}\hc{options.nlpOpt} = a struct of options that are passed directly to fmincon \item \tc{problem.}\hc{options.verbose} = how much detail to provide? \\ $0\to$ no printing, $1\to$ default, $2\to$ extra warnings, $3\to$ debug. $0\to$ no printing, $1\to$ default, $2\to$ extra warnings, $3\to$ debug. \item \tc{problem.}\hc{options.defaultAccuracy} = used to set the default settings for all methods \\ possible values: \texttt{ 'low' } $\quad$ \texttt{ 'medium' } $\quad$ \texttt{'high'} \item \tc{problem.}\hc{options.method} = a string, specifying which method to use. \item \tc{problem.}\hc{options.method} = a string, specifying which method to use. \begin{itemize} \setlength\itemsep{-0.1em} \item \hc{'trapezoid'} $\quad \to \quad$ trapezoidal direct collocation \item \hc{'hermiteSimpson'} $\quad \to \quad$ Hermite--Simpson direct collocation @@ -101,8 +101,8 @@ \subsubsection*{\tc{problem}.\hc{options}} \item \hc{'gpops'} $\quad \to \quad$ wrapper for calling GPOPS-II \end{itemize} \item \tc{problem.}\hc{options.trapezoid.nGrid} = number of grid-points in \texttt{trapezoid} \item \tc{problem.}\hc{options.hermiteSimpson.nSegment} = number of segments in \texttt{hermiteSimpson} \item \tc{problem.}\hc{options.chebyshev.nColPts} = number of collocation points in \texttt{chebyshev} \item \tc{problem.}\hc{options.hermiteSimpson.nSegment} = number of segments in \texttt{hermiteSimpson} \item \tc{problem.}\hc{options.chebyshev.nColPts} = number of collocation points in \texttt{chebyshev} \item \tc{problem.}\hc{options.rungeKutta.nSegment} = number of segments in \texttt{rungeKutta} \item \tc{problem.}\hc{options.rungeKutta.nSubStep} = number of sub-steps per segment in \texttt{rungeKutta} \item \tc{problem.}\hc{options.gpops} = low-level options for \texttt{gpops} (passed like \texttt{setup}) @@ -117,8 +117,8 @@ \section{Details for the Output of OptimTraj} \subsubsection*{\tc{soln}.\hc{grid}} The grid struct contains trajectory evaluated at the grid-points used by the transcriptions algorithm. The spacing and number of the grid-points is dependent on the transcription method and options that were passed to it. \begin{itemize} \setlength\itemsep{-0.1em} \item \tc{soln.}\hc{grid.time}\tc{ = }$t \qquad$ \texttt{size($t$) = [1, $N_t$]} \item \tc{soln.}\hc{grid.state}\tc{ = }$\bm{x} \qquad$ \texttt{size($\bm{x}$) = [$N_x$, $N_t$]} \item \tc{soln.}\hc{grid.time}\tc{ = }$t \qquad$ \texttt{size($t$) = [1, $N_t$]} \item \tc{soln.}\hc{grid.state}\tc{ = }$\bm{x} \qquad$ \texttt{size($\bm{x}$) = [$N_x$, $N_t$]} \item \tc{soln.}\hc{grid.control}\tc{ = }$\bm{u} \qquad$ \texttt{size($\bm{u}$) = [$N_u$, $N_t$]} \end{itemize} @@ -152,11 +152,11 @@ \subsubsection*{\tc{soln}.\hc{info}} \item \tc{soln.}\hc{info.nlpTime} = total time spent in the nonlinear programming solver. \item \tc{soln.}\hc{info.exitFlag} = exit flag returned by the nonlinear programmign solver. \item \tc{soln.}\hc{info.objVal} = value of the objective function \item \tc{soln.}\hc{info.*} = all fields from the \texttt{fmincon problem struct} \item \tc{soln.}\hc{info.error} = integral of absolute error in collocation constraint along each segment of the trajectory. Currently only available for the \texttt{trapezoid} and \texttt{hermiteSimpson} methods. \item \tc{soln.}\hc{info.*} = all fields from the \texttt{fmincon problem struct} \item \tc{soln.}\hc{info.error} = integral of absolute error in collocation constraint along each segment of the trajectory. Currently only available for the \texttt{trapezoid} and \texttt{hermiteSimpson} methods. \item \tc{soln.}\hc{info.maxError} = \texttt{max(max(\tc{soln.}\hc{info.error}))} \end{itemize} \subsubsection*{\tc{soln}.\hc{problem}} The problem struct is similar to the problem struct that was passed in, but \texttt{optimTraj} fills in all omitted fields with the defaults that were actually used by the program. The problem struct is similar to the problem struct that was passed in, but \texttt{optimTraj} fills in all omitted fields with the defaults that were actually used by the program.