User Interface to Make a Model Rocket

Let's make a rocket!

For the sake of clarity, assume all units are in base SI units. The main simple struct is the rocket_simple struct:

TrajOptSOCPs.rocket_simpleType
rocket_simple(mass, isp, grav, deltaTime)

Barebones "spherical" rocket. This is to say, this struct only holds the mass and the isp (specific impulse) of the rocket.

source

Below is an example of how you make the most basic rocket. To obtain the best results, we set the mass to 1 (hence all relevant units would be in "per rocket mass" units). The gravity vector should match the problem dimensionality. In the example below, the gravity vector is two dimensional and pointed in the negative "y" direction.

mass = 1
isp = 1
grav = [0; -9.81]
deltaTime = 1
rocket = rocket_simple(mass, isp, grav, deltaTime)
rocket_simple(1, 1, [0.0, -9.81], 1)

Guess a trajectory!

Now that we have a rocket, we specify the starting point (where the rocket is right now) and the end point (where you want the rocket to land). Note that the state x denotes the combined position and velocity vector: [s; v].

In the example below, we start the rocket at (2.0, 20.0) and expect it to land at (0.0, 0.0). Moreover, we start the rocket in a freefall with velocity of (0.0, -15.0) and expect it to softly land with zero velocity (0.0, 0.0).

const rocketStart = [2.0; 20.0; 0.0; -15.0]
const rocketEnd = [0.0; 0.0; 0.0; 0.0]

We can also initialize a base thrust, which is most simply the hover thrust.

uHover = mass * grav

Lastly, we specify the number of steps in the simulation (combined with the deltaTime parameter above, this implies an a priori flight time).

# Number of time steps to discretize the trajectory
const NSteps = 60

With the information above, we now have the information to build a guess trajectory:

initTraj = initializeTraj(rocketStart, rocketEnd, uHover, uHover, NSteps)
364×1 Array{Float64,2}:
   2.0                
  20.0                
   0.0                
 -15.0                
   0.0                
 -10.0                
   1.9666666666666666 
  19.666666666666664  
   0.0                
 -14.75               
   ⋮                  
   0.33333333333333437
   0.0                
  -0.2500000000000008 
   0.0                
 -10.0                
   0.0                
   0.0                
   0.0                
   0.0                

For more details, see below:

TrajOptSOCPs.initializeTrajFunction
initializeTraj(x0::Array{Float64, 1}, xN::Array{Float64, 1}, NSteps::Int64)

Initializes the full XU vector (see example below) using a linear interpolation from the initial point x0 to the final point xN.

Take x0 = [s0; v0] and xN = [sN; vN] to be of size (2n×1). The full XU vector size is (3Nn + 2n)×1.

For example, take a 2D system: x0 = [sx0; sy0; vx0; vy0] and xN = [sxN; syN; vxN, vyN].

The controls are uk = [uxk; uyk]. Thus, for N = 4

XU vector = [x0; u0; x1; u1; x2; u2; x3; u3; x4]

which is of size ((4 + 2) + (4 + 2) + (4 + 2) + (4 + 2) + (4)) = 28 or equivalently 3Nn + 2n = 3(4)(2) + 2(2) = 24 + 4 = 28, as desired.

source
initializeTraj(x0::Array{Float64, 1}, xN::Array{Float64, 1},
           u0::Array{Float64, 1}, uN::Array{Float64, 1},
           NSteps::Int64)

Initializes the full XU vector (see example below) using a linear interpolation from the initial point x0 to the final point xN.

Take x0 = [s0; v0] and xN = [sN; vN] to be of size (2n×1). The full XU vector size is (3Nn + 2n)×1.

For example, take a 2D system: x0 = [sx0; sy0; vx0; vy0] and xN = [sxN; syN; vxN, vyN].

The controls are uk = [uxk; uyk]. Thus, for N = 4

XU vector = [x0; u0; x1; u1; x2; u2; x3; u3; x4]

which is of size ((4 + 2) + (4 + 2) + (4 + 2) + (4 + 2) + (4)) = 28 or equivalently 3Nn + 2n = 3(4)(2) + 2(2) = 24 + 4 = 28, as desired.

source