Linear Covariance Analysis

This example is a simple implementation of linear covariance analysis [1] to evaluate closed-loop guidance, navigation, and control performance by propagating navigation errors and trajectory dispersions through a single simulation pass rather than simulating many realizations as in a Monte Carlo analysis.

We’ll use the Clohessy-Wiltshire equations to simulate the relative motion between a target vehicle in circular orbit and a chaser vehicle.

import casadi as ca
import numpy as np

import condor as co
from condor.backend import operators as ops

I6 = ops.eye(6)
Z6 = ops.zeros((6, 6))
W = ops.concat([I6, Z6], axis=0)

I3 = ops.eye(3)
Z3 = ops.zeros((3, 3))
V = ops.concat([Z3, I3, ops.zeros((6, 3))], axis=0)

The core of the analysis is an ODE system that represents the true state the follows the CW equations.

class LinCovCW(co.ODESystem):
    omega = parameter()
    scal_w = parameter(shape=6)

    x = state(shape=6)
    C = state(shape=(12, 12), symmetric=True)

    initial[x] = parameter(shape=x.shape, name="initial_x")
    initial[C] = parameter(shape=C.shape, name="initial_C")

    # [0, 0, 0,            1, 0, 0],
    # [0, 0, 0,            0, 1, 0],
    # [0, 0, 0,            0, 0, 1],
    # [0, 0, 0,            0, 0, 2*omega],
    # [0, -omega**2, 0,    0, 0, 0],
    # [0, 0, 3*omega**2,   -2*omega, 0, 0]
    Acw = ops.zeros((6, 6))
    Acw[:3, 3:] = ops.eye(3)
    Acw[3, 5] = 2 * omega
    Acw[4, 1] = -(omega**2)
    Acw[5, 2] = 3 * omega**2
    Acw[5, 3] = -2 * omega

    Scal_w = ops.diag(scal_w)
    Cov_prop_offset = W @ Scal_w @ W.T

    Fcal = ops.zeros((12, 12))
    Fcal[:6, :6] = Acw
    Fcal[6:, 6:] = Acw

    dot[x] = Acw @ x
    dot[C] = Fcal @ C + C @ Fcal.T + Cov_prop_offset

A discrete targeting maneuver can be implemented as an event on the ODE system that instantaneously updates the relative velocity as well as the augmented covariance.

class MajorBurn(LinCovCW.Event):
    #: Target position
    rd = parameter(shape=3)
    #: Time ignition
    tig = parameter()
    #: Time end maneuver
    tem = parameter()

    scal_v = parameter(shape=3)

    Delta_v_mag = state()
    Delta_v_disp = state()

    at_time = tig
    td = tem - tig

    stm = ops.zeros((6, 6))
    stm[0, 0] = 1
    stm[0, 2] = 6 * omega * td - 6 * ops.sin(omega * td)
    stm[0, 3] = -3 * td + 4 * ops.sin(omega * td) / omega
    stm[0, 5] = 2 * (1 - ops.cos(omega * td)) / omega
    stm[1, 1] = ops.cos(omega * td)
    stm[1, 4] = ops.sin(omega * td) / omega
    stm[2, 2] = 4 - 3 * ops.cos(omega * td)
    stm[2, 3] = 2 * (ops.cos(omega * td) - 1) / omega
    stm[2, 5] = ops.sin(omega * td) / omega
    stm[3, 2] = 6 * omega * (1 - ops.cos(omega * td))
    stm[3, 3] = 4 * ops.cos(omega * td) - 3
    stm[3, 5] = 2 * ops.sin(omega * td)
    stm[4, 1] = -omega * ops.sin(omega * td)
    stm[4, 4] = ops.cos(omega * td)
    stm[5, 2] = 3 * omega * ops.sin(omega * td)
    stm[5, 3] = -2 * ops.sin(omega * td)
    stm[5, 5] = ops.cos(omega * td)

    T_pp = stm[:3, :3]
    T_pv = stm[:3, 3:]
    T_pv_inv = ca.solve(T_pv, ops.eye(3))

    Delta_v = (T_pv_inv @ rd - T_pv_inv @ T_pp @ x[:3, 0]) - x[3:, 0]

    update[Delta_v_mag] = Delta_v_mag + ca.norm_2(Delta_v)
    update[x] = x + ops.concat([ops.zeros((3, 1)), Delta_v])

    DG = ca.vertcat(ops.zeros((3, 6)), ca.horzcat(-(T_pv_inv @ T_pp), -I3))
    Dcal = ca.vertcat(
        ca.horzcat(I6, DG),
        ca.horzcat(Z6, I6 + DG),
    )

    Scal_v = ops.diag(scal_v)

    update[C] = Dcal @ C @ Dcal.T + V @ Scal_v @ V.T

    Mc = DG @ ops.concat([Z6, I6], axis=1)
    sigma_Dv__2 = ca.trace(Mc @ C @ Mc.T)

    update[Delta_v_disp] = Delta_v_disp + ca.sqrt(sigma_Dv__2)

A Terminating event at the end of the maneuver

class Terminate(LinCovCW.Event):
    terminate = True
    at_time = MajorBurn.tem

Trajectory analysis to simulate the system

class Sim(LinCovCW.TrajectoryAnalysis):
    # TODO: add final burn Delta v (assume final relative v is 0, can get magnitude and
    # dispersion)
    tot_Delta_v_mag = trajectory_output(Delta_v_mag)
    tot_Delta_v_disp = trajectory_output(Delta_v_disp)

    # tf = parameter()

    Mr = ca.horzcat(I3, ca.MX(3, 9))
    sigma_r__2 = ca.trace(Mr @ C @ Mr.T)
    final_pos_disp = trajectory_output(ca.sqrt(sigma_r__2))

Simulate

def make_C0(sigma_p, sigma_v, rho, sigma_p_nav=None, sigma_v_nav=None, rho_nav=None):
    D0 = np.zeros((6, 6))
    D0[:3, :3] = np.eye(3) * (sigma_p**2)
    D0[2, 3] = rho * sigma_p * sigma_v
    D0[3, 2] = rho * sigma_p * sigma_v
    D0[3:, 3:] = np.eye(3) * (sigma_v**2)

    sigma_p_nav = sigma_p_nav or sigma_p
    sigma_v_nav = sigma_v_nav or sigma_v
    rho_nav = rho_nav or rho

    P0 = np.zeros((6, 6))
    P0[:3, :3] = np.eye(3) * (sigma_p_nav**2)
    P0[2, 3] = rho_nav * sigma_p_nav * sigma_v_nav
    P0[3, 2] = rho_nav * sigma_p_nav * sigma_v_nav
    P0[3:, 3:] = np.eye(3) * (sigma_v_nav**2)

    C = np.concat(
        (np.concat((D0, D0), axis=1), np.concat((D0, D0 + P0), axis=1)), axis=0
    )
    return C


initial_C = make_C0(100 / 3, 0.11 / 3, 0.9, 10 / 3, 0.011 / 3, 0.9)

sim_kwargs = dict(
    omega=0.00114,
    scal_w=[0.0] * 3 + [4.8e-10] * 3,
    scal_v=[2.5e-7] * 3,
    initial_x=[-2000.0, 0.0, 1000.0, 1.71, 0.0, 0.0],
    initial_C=make_C0(100 / 3, 0.11 / 3, 0.9, 10 / 3, 0.011 / 3, 0.9),
    rd=[500.0, 0.0, 0.0],
)

out = Sim(**sim_kwargs, tig=156.7, tem=156.7 + 15 * 60)

print(out.final_pos_disp)
[11.03987383]
import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse


def plot_traj(sim, x_idx=0, y_idx=2):
    """create relative motion plot in the vertical plane"""
    fig, ax = plt.subplots(constrained_layout=True)
    ax.invert_xaxis()
    ax.set_xlabel("V-bar (m)")
    ax.invert_yaxis()
    ax.set_ylabel("R-bar (m)")
    ax.grid(True)
    ax.set_aspect("equal")
    plt.xlim(1000, -2500)
    plt.ylim(1500, -500)
    fig.set_size_inches(7.4, 4.2)

    sim_color = "C0"
    plt.plot([0.0], [0.0], "ok")
    xs = sim.x[x_idx].squeeze()
    ys = sim.x[y_idx].squeeze()
    ax.plot(xs, ys, "o-", color=sim_color)
    ax.plot(xs[0], ys[0], "og")

    n_std = 3

    for pos_vel, cov in zip(sim.x.T.squeeze(), sim.C.T):
        pos = pos_vel[[x_idx, y_idx]]
        C = cov[[x_idx, y_idx]][:, [x_idx, y_idx]]
        lambda_, v = np.linalg.eig(C)
        lambda_ = np.sqrt(lambda_)

        ellipse = Ellipse(
            pos,
            width=lambda_[0] * n_std * 2,
            height=lambda_[1] * n_std * 2,
            angle=np.degrees(np.arctan2(*v[:, 0][::-1])),
            edgecolor=sim_color,
            facecolor="none",
        )
        ax.add_patch(ellipse)
    return ax


plot_traj(out)

# TODO
# DV_idx = Sim.trajectory_output.flat_index(Sim.tot_Delta_v_mag)
# tig_idx = Sim.parameter.flat_index(Sim.tig)
# tem_idx = Sim.parameter.flat_index(Sim.tem)
# init_jac = Sim.implementation.callback.jac_callback(Sim.implementation.callback.p, [])
# print("init grad  wrt tig", init_jac[DV_idx, tig_idx])
# print("init grad  wrt tem", init_jac[DV_idx, tem_idx])
# """
# init grad  wrt tig 0.0209833
# init grad  wrt tem -0.0260249
# """
orbital 1
<Axes: xlabel='V-bar (m)', ylabel='R-bar (m)'>
class Hohmann(co.OptimizationProblem):
    tig = variable(initializer=200.0)
    tem = variable(initializer=500.0)

    sim = Sim(tig=tig, tem=tem, **sim_kwargs)

    objective = sim.tot_Delta_v_mag

    constraint(tem > tig + 30)
    constraint(tig > 0.1)

    class Options:
        # TODO
        # __implementation__ = co.implementations.ScipyTrustConstr
        exact_hessian = False


from time import perf_counter

hoh_start = perf_counter()
hohmann = Hohmann()
hoh_stop = perf_counter()

print(hohmann._stats)
print((hohmann.tem - hohmann.tig) * hohmann.sim.omega * 180 / np.pi)

# TODO
# opt_jac = Sim.implementation.callback.jac_callback(Sim.implementation.callback.p, [])
# print("opt grad  wrt tig", opt_jac[DV_idx, tig_idx])
# print("opt grad  wrt tem", opt_jac[DV_idx, tem_idx])
# """
# opt grad  wrt tig -4.48258e-09
# opt grad  wrt tem -1.47125e-09
# """
This is Ipopt version 3.14.11, running with linear solver MUMPS 5.4.1.

Number of nonzeros in equality constraint Jacobian...:        0
Number of nonzeros in inequality constraint Jacobian.:        3
Number of nonzeros in Lagrangian Hessian.............:        0

Total number of variables............................:        2
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        0
                     variables with only upper bounds:        0
Total number of equality constraints.................:        0
Total number of inequality constraints...............:        2
        inequality constraints with only lower bounds:        2
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        0

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  6.4936391e+00 0.00e+00 2.60e-02   0.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  6.4925217e+00 0.00e+00 1.46e-02  -6.6 4.70e-02    -  9.90e-01 1.00e+00f  1
   2  4.1522436e+00 0.00e+00 6.51e-03  -2.8 1.47e+02    -  9.84e-01 1.00e+00f  1
   3  3.1748709e+00 0.00e+00 4.05e-03  -4.8 1.15e+02    -  1.00e+00 1.00e+00f  1
   4  2.2263549e+00 0.00e+00 2.21e-03  -5.7 1.86e+02    -  1.00e+00 1.00e+00f  1
   5  1.5484505e+00 0.00e+00 1.38e-03  -6.5 2.22e+02    -  1.00e+00 1.00e+00f  1
   6  1.1046691e+00 0.00e+00 9.48e-04  -7.0 2.93e+02    -  1.00e+00 7.15e-01f  1
   7  6.1851591e-01 0.00e+00 4.91e-04  -6.0 3.99e+02    -  4.14e-03 1.00e+00f  1
   8  3.8428264e-01 0.00e+00 2.04e-04  -6.6 4.13e+02    -  1.00e+00 1.00e+00f  1
   9  3.2279045e-01 0.00e+00 7.42e-05  -6.6 2.92e+02    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  2.9923153e-01 0.00e+00 4.12e-05  -7.6 2.44e+02    -  1.00e+00 1.00e+00f  1
  11  2.8667982e-01 0.00e+00 1.61e-05 -11.0 3.09e+02    -  1.00e+00 1.00e+00f  1
  12  2.8516474e-01 0.00e+00 4.61e-06  -8.4 9.54e+01    -  1.00e+00 1.00e+00f  1
  13  2.8500540e-01 0.00e+00 7.76e-07  -9.4 3.64e+01    -  1.00e+00 1.00e+00f  1
  14  2.8500011e-01 0.00e+00 1.72e-07 -11.0 8.69e+00    -  1.00e+00 1.00e+00f  1
  15  2.8500003e-01 0.00e+00 9.59e-08 -11.0 7.39e-01    -  1.00e+00 1.00e+00f  1
  16  2.8500000e-01 0.00e+00 5.46e-11 -11.0 2.81e-01    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 16

                                   (scaled)                 (unscaled)
Objective...............:   2.8500000000002523e-01    2.8500000000002523e-01
Dual infeasibility......:   5.4600501196373501e-11    5.4600501196373501e-11
Constraint violation....:   0.0000000000000000e+00    0.0000000000000000e+00
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   9.9999999167391752e-12    9.9999999167391752e-12
Overall NLP error.......:   5.4600501196373501e-11    5.4600501196373501e-11


Number of objective function evaluations             = 17
Number of objective gradient evaluations             = 17
Number of equality constraint evaluations            = 0
Number of inequality constraint evaluations          = 17
Number of equality constraint Jacobian evaluations   = 0
Number of inequality constraint Jacobian evaluations = 17
Number of Lagrangian Hessian evaluations             = 0
Total seconds in IPOPT                               = 3.535

EXIT: Optimal Solution Found.
{'iter_count': 16, 'iterations': {'alpha_du': [0.0, 0.9898285295685858, 0.9842402293560555, 1.0, 1.0, 1.0, 1.0, 0.004140027452292917, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], 'alpha_pr': [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.7149778955287908, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], 'd_norm': [0.0, 0.04700771427236512, 147.0343393040177, 115.44642648212835, 186.41902166571953, 221.9326066411802, 292.9552687947239, 399.49156752841947, 413.03084327256175, 291.56535502963817, 244.33777326276436, 308.7385371689279, 95.41495081615221, 36.41536802920983, 8.690722845600636, 0.7389692851209383, 0.28148098240986763], 'inf_du': [0.026024879059342105, 0.014605956528173522, 0.006505450906661856, 0.0040476207149814, 0.00220898995347599, 0.0013759448721080239, 0.0009482486871725277, 0.0004911213979005004, 0.00020364975153507164, 7.418601739019045e-05, 4.1238876684231294e-05, 1.6056230256091602e-05, 4.606922850215797e-06, 7.761787402831366e-07, 1.719536451262994e-07, 9.587813839220988e-08, 5.46005011963735e-11], 'inf_pr': [0.0, 0.0, 5.684341886080802e-14, 1.1368683772161603e-13, 1.1368683772161603e-13, 0.0, 0.0, 2.2737367544323206e-13, 2.2737367544323206e-13, 4.547473508864641e-13, 4.547473508864641e-13, 0.0, 4.547473508864641e-13, 4.547473508864641e-13, 0.0, 4.547473508864641e-13, 4.547473508864641e-13], 'mu': [1.0, 2.3495000001000001e-07, 0.0014545402508683457, 1.5658669865842725e-05, 2.093876447410522e-06, 3.1758246357022486e-07, 9.878583835498034e-08, 1.0564209597778857e-06, 2.5408339995710536e-07, 2.3511341809476054e-07, 2.6468653562476205e-08, 1e-11, 3.773980300584271e-09, 3.898525625933994e-10, 1e-11, 1e-11, 1e-11], 'obj': [6.493639138134979, 6.492521733862819, 4.1522436029850045, 3.174870894093014, 2.2263548730449343, 1.548450524063878, 1.1046690573928997, 0.6185159065573307, 0.38428263659915207, 0.3227904451096955, 0.2992315271794575, 0.2866798222756138, 0.28516473560253824, 0.28500540412278463, 0.2850001073857912, 0.2850000346414181, 0.28500000000002523], 'regularization_size': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]}, 'n_call_callback_fun': 0, 'n_call_nlp_f': 17, 'n_call_nlp_g': 17, 'n_call_nlp_grad': 0, 'n_call_nlp_grad_f': 18, 'n_call_nlp_jac_g': 18, 'return_status': 'Solve_Succeeded', 'success': True, 't_proc_callback_fun': 0.0, 't_proc_nlp_f': 1.58444, 't_proc_nlp_g': 0.00020200000000000003, 't_proc_nlp_grad': 0.0, 't_proc_nlp_grad_f': 8.218545, 't_proc_nlp_jac_g': 0.000152, 't_wall_callback_fun': 0.0, 't_wall_nlp_f': 0.545384529, 't_wall_nlp_g': 0.000121345, 't_wall_nlp_grad': 0.0, 't_wall_nlp_grad_f': 2.957861413, 't_wall_nlp_jac_g': 0.000146705, 'unified_return_status': 'SOLVER_RET_SUCCESS'}
[179.99997662]
[93543.09121237]
[42980.59515077]
[84.09660115] [2839.87927261]
time: 3.5427948549999826
plot_traj(hohmann_sim)
orbital 1
<Axes: xlabel='V-bar (m)', ylabel='R-bar (m)'>
class TotalDeltaV(co.OptimizationProblem):
    tig = variable(initializer=200.0)
    tem = variable(initializer=500.0)
    constraint(tem - tig, lower_bound=30.0)
    constraint(tig, lower_bound=0.0)
    sim = Sim(tig=tig, tem=tem, **sim_kwargs)

    # TODO: adding a parameter and constraint to existing problem SHOULD be done by
    # inheritance... I suppose the originally Hohmann model could easily be written to
    # include more parameters to solve all permutations of this problem... weights for
    # each output, upper bounds for each output (and combinations?)
    # what about including a default for a paremter at a model level? no, just make a
    # dict like unbounded_kwargs to fill in with a large number/inf
    pos_disp_max = parameter()
    constraint(sim.final_pos_disp - pos_disp_max, upper_bound=0.0)

    objective = sim.tot_Delta_v_mag + 3 * sim.tot_Delta_v_disp

    class Options:
        exact_hessian = False


total_delta_v = TotalDeltaV(pos_disp_max=1000)
This is Ipopt version 3.14.11, running with linear solver MUMPS 5.4.1.

Number of nonzeros in equality constraint Jacobian...:        0
Number of nonzeros in inequality constraint Jacobian.:        5
Number of nonzeros in Lagrangian Hessian.............:        0

Total number of variables............................:        2
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        0
                     variables with only upper bounds:        0
Total number of equality constraints.................:        0
Total number of inequality constraints...............:        3
        inequality constraints with only lower bounds:        2
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        1

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  7.1721180e+00 0.00e+00 2.79e-02   0.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  7.1707977e+00 0.00e+00 1.58e-02  -6.3 5.12e-02    -  9.90e-01 1.00e+00f  1
   2  4.6314943e+00 0.00e+00 1.28e-02  -2.8 1.47e+02    -  9.99e-01 1.00e+00f  1
   3  3.5748124e+00 0.00e+00 8.14e-03  -4.9 1.16e+02    -  9.99e-01 1.00e+00f  1
   4  2.5573172e+00 0.00e+00 4.64e-03  -6.0 1.88e+02    -  1.00e+00 1.00e+00f  1
   5  2.1303875e+00 0.00e+00 3.47e-03  -2.6 2.23e+02    -  1.00e+00 5.34e-01f  1
   6  1.3896162e+00 0.00e+00 1.87e-03  -3.9 2.90e+02    -  7.65e-01 1.00e+00f  1
   7  9.2343203e-01 0.00e+00 9.86e-04  -9.6 3.38e+02    -  5.86e-01 1.00e+00h  1
   8  6.5880088e-01 0.00e+00 3.97e-04  -4.1 4.10e+02    -  1.00e+00 1.00e+00h  1
   9  5.9556262e-01 0.00e+00 9.33e-05  -5.0 2.73e+02    -  9.70e-01 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  5.9214434e-01 0.00e+00 2.49e-05  -7.1 8.68e+01    -  1.00e+00 1.00e+00h  1
  11  5.9201333e-01 0.00e+00 2.46e-06  -6.8 1.30e+01    -  9.99e-01 1.00e+00h  1
  12  5.9200809e-01 0.00e+00 8.58e-07 -11.0 2.16e+00    -  1.00e+00 1.00e+00h  1
  13  5.9200750e-01 0.00e+00 4.37e-09 -11.0 1.05e+00    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 13

                                   (scaled)                 (unscaled)
Objective...............:   5.9200749529483088e-01    5.9200749529483088e-01
Dual infeasibility......:   4.3674765216242987e-09    4.3674765216242987e-09
Constraint violation....:   0.0000000000000000e+00    0.0000000000000000e+00
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   1.0003863375195823e-11    1.0003863375195823e-11
Overall NLP error.......:   4.3674765216242987e-09    4.3674765216242987e-09


Number of objective function evaluations             = 14
Number of objective gradient evaluations             = 14
Number of equality constraint evaluations            = 0
Number of inequality constraint evaluations          = 14
Number of equality constraint Jacobian evaluations   = 0
Number of inequality constraint Jacobian evaluations = 14
Number of Lagrangian Hessian evaluations             = 0
Total seconds in IPOPT                               = 5.091

EXIT: Optimal Solution Found.
tot_delta_v_sim = Sim(**sim_kwargs, tig=total_delta_v.tig, tem=total_delta_v.tem)
plot_traj(tot_delta_v_sim)
orbital 1
<Axes: xlabel='V-bar (m)', ylabel='R-bar (m)'>
total_delta_v_constrained = TotalDeltaV(pos_disp_max=10.0)
This is Ipopt version 3.14.11, running with linear solver MUMPS 5.4.1.

Number of nonzeros in equality constraint Jacobian...:        0
Number of nonzeros in inequality constraint Jacobian.:        5
Number of nonzeros in Lagrangian Hessian.............:        0

Total number of variables............................:        2
                     variables with only lower bounds:        0
                variables with lower and upper bounds:        0
                     variables with only upper bounds:        0
Total number of equality constraints.................:        0
Total number of inequality constraints...............:        3
        inequality constraints with only lower bounds:        2
   inequality constraints with lower and upper bounds:        0
        inequality constraints with only upper bounds:        1

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  5.9200750e-01 2.16e+01 1.00e-03   0.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  5.9200750e-01 2.16e+01 2.14e+00  -6.1 2.16e+01    -  9.90e-01 4.58e-04h  1
   2  1.2228222e+00 3.62e+00 7.92e-04  -1.2 9.87e+02    -  1.00e+00 1.00e+00h  1
   3  1.7561268e+00 4.26e-01 1.00e-03  -2.5 2.71e+02    -  1.00e+00 1.00e+00h  1
   4  1.8678722e+00 0.00e+00 1.40e-04  -2.5 4.38e+01    -  1.00e+00 9.99e-01h  1
   5  1.8655032e+00 9.04e-05 2.26e-04  -3.7 8.88e-01    -  1.00e+00 9.83e-01h  1
   6  1.8653259e+00 0.00e+00 4.41e-07  -9.8 1.48e-01    -  1.00e+00 1.00e+00h  1
   7  1.8653256e+00 1.77e-07 6.53e-11 -11.0 2.08e-04    -  1.00e+00 9.99e-01h  1
   8  1.8653257e+00 3.71e-09 5.16e-12 -11.0 1.83e-05    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 8

                                   (scaled)                 (unscaled)
Objective...............:   1.8653256701834278e+00    1.8653256701834278e+00
Dual infeasibility......:   5.1613787029058944e-12    5.1613787029058944e-12
Constraint violation....:   3.7053692839117500e-09    3.7053692839117500e-09
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   1.0007858846440985e-11    1.0007858846440985e-11
Overall NLP error.......:   3.7053692839117500e-09    3.7053692839117500e-09


Number of objective function evaluations             = 9
Number of objective gradient evaluations             = 9
Number of equality constraint evaluations            = 0
Number of inequality constraint evaluations          = 9
Number of equality constraint Jacobian evaluations   = 0
Number of inequality constraint Jacobian evaluations = 9
Number of Lagrangian Hessian evaluations             = 0
Total seconds in IPOPT                               = 3.344

EXIT: Optimal Solution Found.
tot_delta_v_constrained_sim = Sim(
    **sim_kwargs, tig=total_delta_v_constrained.tig, tem=total_delta_v_constrained.tem
)
plot_traj(tot_delta_v_constrained_sim)
orbital 1
<Axes: xlabel='V-bar (m)', ylabel='R-bar (m)'>
 unconstrained Delta v
{'iter_count': 13, 'iterations': {'alpha_du': [0.0, 0.9898141549346541, 0.9989278174798525, 0.9990960213085416, 1.0, 1.0, 0.7648596964406856, 0.5862474784081099, 1.0, 0.9697500890827727, 1.0, 0.9992803183413812, 0.999730792435811, 1.0], 'alpha_pr': [0.0, 1.0, 1.0, 1.0, 1.0, 0.5339668186920494, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0], 'd_norm': [0.0, 0.05118226403964429, 147.31055370906319, 115.9030963785144, 187.7307422406854, 222.85632685767274, 289.9825004267278, 338.1023341474204, 410.30625790258506, 272.9966005936474, 86.7514026881369, 13.026263618110319, 2.1579846814235597, 1.0512703158552346], 'inf_du': [0.02790119311111404, 0.015815194559341193, 0.012774754882013146, 0.008137855209943404, 0.004635016915627543, 0.00346838177267059, 0.001865019991076233, 0.0009862330287145002, 0.0003968806797413072, 9.334584411958396e-05, 2.4910941790117898e-05, 2.460104947922069e-06, 8.583286196174579e-07, 4.367476521624299e-09], 'inf_pr': [0.0, 4.360686034488026e-09, 0.03827253453391677, 0.028469932938151032, 0.0916000178693821, 0.09143869225079015, 0.504690568855608, 0.654219996834172, 0.816749143628158, 0.26204794649061114, 0.014750287883089186, 7.302732888092578e-05, 1.0747301985247759e-05, 2.520303382880229e-06], 'mu': [1.0, 4.877296677568146e-07, 0.0014972410914916795, 1.3109105651092832e-05, 9.418225541706091e-07, 0.0024587055752338387, 0.00012123606688100062, 2.4710280014104476e-10, 8.115076356398707e-05, 1.005939225662401e-05, 7.416463910006809e-08, 1.7263629772068547e-07, 1e-11, 1e-11], 'obj': [7.17211796170742, 7.170797695051909, 4.631494345636032, 3.57481241849663, 2.5573171734478692, 2.13038750389673, 1.3896162137529395, 0.9234320342547346, 0.6588008797889437, 0.5955626221096694, 0.5921443437405733, 0.5920133330973244, 0.5920080922567432, 0.5920074952948309], 'regularization_size': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]}, 'n_call_callback_fun': 0, 'n_call_nlp_f': 14, 'n_call_nlp_g': 14, 'n_call_nlp_grad': 0, 'n_call_nlp_grad_f': 15, 'n_call_nlp_jac_g': 15, 'return_status': 'Solve_Succeeded', 'success': True, 't_proc_callback_fun': 0.0, 't_proc_nlp_f': 0.0019140000000000003, 't_proc_nlp_g': 1.4388120000000002, 't_proc_nlp_grad': 0.0, 't_proc_nlp_grad_f': 6.550837999999999, 't_proc_nlp_jac_g': 7.561986999999999, 't_wall_callback_fun': 0.0, 't_wall_nlp_f': 0.0014354359999999998, 't_wall_nlp_g': 0.427427727, 't_wall_nlp_grad': 0.0, 't_wall_nlp_grad_f': 2.282310342, 't_wall_nlp_jac_g': 2.357267798, 'unified_return_status': 'SOLVER_RET_SUCCESS'}
[141.41273551]
[31.59576929]


 constrained Delta v
{'iter_count': 8, 'iterations': {'alpha_du': [0.0, 0.9900018897466567, 1.0, 1.0, 1.0, 1.0, 0.9996268012042545, 1.0, 1.0], 'alpha_pr': [0.0, 0.0004582329793298304, 1.0, 1.0, 0.9994936327994016, 0.9830114834329401, 1.0, 0.9991980560682624, 1.0], 'd_norm': [0.0, 21.60473044624338, 987.2174903416433, 270.604063877841, 43.784350825985435, 0.88782206324506, 0.1475963083607423, 0.0002075639437303516, 1.8250048221303496e-05], 'inf_du': [0.001, 2.137965788523227, 0.0007916274745348199, 0.0010007425567115336, 0.00014046987840786538, 0.00022595345100623332, 4.4122064773543905e-07, 6.530280179453674e-11, 5.161378702905894e-12], 'inf_pr': [21.605769282246474, 21.595868806222196, 3.6514809624529843, 0.42851534272920383, 0.01171158463192223, 0.00020366313871320388, 1.2360041218611366e-07, 1.7664496531441501e-07, 3.739342611887318e-09], 'mu': [1.0, 7.416902494414024e-07, 0.07074735738619545, 0.003465881807236856, 0.003538173208019528, 0.00020039387938700507, 1.44963112998512e-10, 1e-11, 1.000785830098696e-11], 'obj': [0.5920074952948309, 0.5920074952949033, 1.222822205246997, 1.756126803238427, 1.8678722024772674, 1.8655031920393472, 1.8653259329125786, 1.865325618137415, 1.8653256701834278], 'regularization_size': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]}, 'n_call_callback_fun': 0, 'n_call_nlp_f': 9, 'n_call_nlp_g': 9, 'n_call_nlp_grad': 0, 'n_call_nlp_grad_f': 10, 'n_call_nlp_jac_g': 10, 'return_status': 'Solve_Succeeded', 'success': True, 't_proc_callback_fun': 0.0, 't_proc_nlp_f': 0.003979, 't_proc_nlp_g': 0.8663569999999999, 't_proc_nlp_grad': 0.0, 't_proc_nlp_grad_f': 4.531675000000001, 't_proc_nlp_jac_g': 4.800182, 't_wall_callback_fun': 0.0, 't_wall_nlp_f': 0.000981068, 't_wall_nlp_g': 0.237523443, 't_wall_nlp_grad': 0.0, 't_wall_nlp_grad_f': 1.530496932, 't_wall_nlp_jac_g': 1.5610772720000001, 'unified_return_status': 'SOLVER_RET_SUCCESS'}
[62.33473703]
[10.00000001]

References

Total running time of the script: (0 minutes 13.273 seconds)

Gallery generated by Sphinx-Gallery