Moon Lander

Moon Lander

First setup the packages that will be used:

using NLOptControl

Where, the object n is the object for the entire optimal control problem including: |setting | keys | descriptions | | –––––––––– | –––––- | ––––––––––– | |n.s.integrationMethod | :tm | time marching | | :ps | pseudospectral methods | n.s for settings n.r for results n.mpc for mpc data

Next define the basic differential equation used to model the system:

de=[:(x2[j]),:(u1[j]-1.625)]

Most of this code is boiler-plate and should be copied directly. The important things to note are thatu is the control variable matrix and x is the state variable matrix. So, in the above example the only thing that the user needs to modify is the right hand side of the dx[] expressions. The indecies for the number of the state or control variable are in the columns. For instance, x[:,2] represents the entire vector for second state variable.

NOTE: eventually most of this code will be pushed to a lower level.

Now that the dynamic constraint equations have been established, the next step is to define the problem:

n=define!(de;numStates=2,numControls=1,X0=[10.,-2],XF=[0.,0.],XL=[NaN,NaN],XU=[NaN,NaN],CL=[0.],CU=[3.]);

To do this the user passes n, and defines the stateEquations to be the dynamic constraint equations defined in MoonLander().

Basics: numStates = number of state variables numControls = number of control variables X0 = intial sttae TODO-> mention XL etc.

There are several different ways to ensure that the stateEquations are satisfied that are set using the keys :integrationMethod and :integrationScheme. In this example the hp-Gaussian Quadrature Collocation Method is used with Radau Nodes. Finally, the final time may be either fixed and set before hand or it can be a variable. This option is set using the :finalTimeDV key and it is set to true in this example.

configure!(n,Ni=4,Nck=[10,10,10,10];(:integrationMethod=>:ps),(:integrationScheme=> :lgrExplicit),(:finalTimeDV=>true));

The next parts are optional.

  1. Names and descriptions may be added to both the control and state variables as follows:

names=[:h,:v]; descriptions = ["h(t)","v(t)"]; stateNames!(n,names,descriptions);

NOTE: The names will show up in the results data and the descriptions will show up in the graphs

The object r stores all of the results as well as both the control and state variables. For instance r.x[:,1] should now be used to access the entire vector for the first state.

For generality, integrate!() will also be demonstrated in this example. integrate!() is used to add terms to the cost function that need to be integrated. Currently there are several forms that these integrals can take (more can be added). In this example the first control variable r.u[:,1] and sets up this variable to be integrated over the entire time of the control problem with the following line of code:

obj=integrate!(n,n.r.u[:,1];C=1.0,(:variable=>:control),(:integrand=>:default));

Next the cost function can be defined as:

@NLobjective(n.mdl, Min, obj);

At this stage, the optimal control problem can be solved with:

optimize!(n);

Then, in order to quickly visualize the problem, functionality is also provided for automated visualization.

The next part is optional:

The plot settings can be modified from the default using the following code:

using PrettyPlots
plotSettings(;(:mpc_lines =>[(4.0,:blue,:solid)]),(:size=>(700,700)));

Finally, in order to plot all of the states and controls call:

allPlots(n);
0 1 2 3 4 0 5 10 time (s) h(t) mpc 0 1 2 3 4 -4 -3 -2 -1 0 time (s) v(t) mpc 0 1 2 3 4 0 1 2 3 time (s) u1 max min mpc