示例#1
0
 def create_nlp(self, var, par, obj, con, options):
     jit = options['codegen']
     if options['verbose'] >= 2:
         print 'Building nlp ... ',
         if jit['jit']:
             print('[jit compilation with flags %s]' %
                   (','.join(jit['jit_options']['flags']))),
     t0 = time.time()
     nlp = MXFunction('nlp', nlpIn(x=var, p=par), nlpOut(f=obj, g=con))
     solver = NlpSolver('solver', 'ipopt', nlp, options['solver'])
     grad_f, jac_g = nlp.gradient('x', 'f'), nlp.jacobian('x', 'g')
     hess_lag = solver.hessLag()
     var, par = struct_symSX(var), struct_symSX(par)
     nlp = SXFunction('nlp', [var, par], nlp([var, par]), jit)
     grad_f = SXFunction('grad_f', [var, par], grad_f([var, par]), jit)
     jac_g = SXFunction('jac_g', [var, par], jac_g([var, par]), jit)
     lam_f, lam_g = SX.sym('lam_f'), SX.sym('lam_g', con.size)
     hess_lag = SXFunction('hess_lag', [var, par, lam_f, lam_g],
                           hess_lag([var, par, lam_f, lam_g]), jit)
     options['solver'].update({'grad_f': grad_f, 'jac_g': jac_g,
                               'hess_lag': hess_lag})
     problem = NlpSolver('solver', 'ipopt', nlp, options['solver'])
     t1 = time.time()
     if options['verbose'] >= 2:
         print 'in %5f s' % (t1-t0)
     return problem, (t1-t0)
示例#2
0
文件: system.py 项目: mg-meth/awebox
def generate_system_parameters(options, architecture):

    parameters_dict = {}

    # extract parametric options
    parametric_options = options['params']
    parameters_dict['theta0'] = struct_op.generate_nested_dict_struct(parametric_options)

    # optimization parameters
    parameters_dict['phi'] = generate_optimization_parameters()

    # define vortex induction linearization parameters
    use_vortex_linearization = options['aero']['vortex']['use_linearization']
    if use_vortex_linearization:
        vortex_linearization_list, _ = generate_structure(options, architecture)
        vortex_linearization_params, _ = struct_op.generate_variable_struct(vortex_linearization_list)
        parameters_dict['lin'] = vortex_linearization_params

    # generate nested casadi structure for system parameters
    if use_vortex_linearization:
        parameters = cas.struct_symSX([
            cas.entry('theta0', struct=parameters_dict['theta0']),
            cas.entry('phi', struct=parameters_dict['phi']),
            cas.entry('lin', struct=parameters_dict['lin'])
        ])
    else:
        parameters = cas.struct_symSX([
            cas.entry('theta0', struct= parameters_dict['theta0']),
            cas.entry('phi', struct= parameters_dict['phi'])
        ])

    return parameters, parameters_dict
示例#3
0
    def get_collocation_variables_struct(self, variables_dict):

        if 'xl' in list(variables_dict.keys()):
            coll_var = cas.struct_symSX([
                cas.entry('xd', struct=variables_dict['xd']),
                cas.entry('xa', struct=variables_dict['xa']),
                cas.entry('xl', struct=variables_dict['xl'])
            ])
        else:
            coll_var = cas.struct_symSX([
                cas.entry('xd', struct=variables_dict['xd']),
                cas.entry('xa', struct=variables_dict['xa']),
            ])

        return coll_var
示例#4
0
文件: admm.py 项目: jgillis/omg-tools
 def construct_upd_z(self):
     # check if we have linear equality constraints
     self._lineq_updz, A, b = self._check_for_lineq()
     if not self._lineq_updz:
         self._construct_upd_z_nlp()
     x_i = struct_symSX(self.q_i_struct)
     x_j = struct_symSX(self.q_ij_struct)
     l_i = struct_symSX(self.q_i_struct)
     l_ij = struct_symSX(self.q_ij_struct)
     t = SX.sym('t')
     T = SX.sym('T')
     rho = SX.sym('rho')
     par = struct_symSX(self.par_struct)
     inp = [x_i.cat, l_i.cat, l_ij.cat, x_j.cat, t, T, rho, par.cat]
     t0 = t/T
     # put symbols in SX structs (necessary for transformation)
     x_i = self.q_i_struct(x_i)
     x_j = self.q_ij_struct(x_j)
     l_i = self.q_i_struct(l_i)
     l_ij = self.q_ij_struct(l_ij)
     # transform spline variables: only consider future piece of spline
     tf = lambda cfs, basis: shift_knot1_fwd(cfs, basis, t0)
     self._transform_spline([x_i, l_i], tf, self.q_i)
     self._transform_spline([x_j, l_ij], tf, self.q_ij)
     # fill in parameters
     A = A([par])[0]
     b = b([par])[0]
     # build KKT system
     E = rho*SX.eye(A.shape[1])
     l, x = vertcat([l_i.cat, l_ij.cat]), vertcat([x_i.cat, x_j.cat])
     f = -(l + rho*x)
     G = vertcat([horzcat([E, A.T]),
                  horzcat([A, SX.zeros(A.shape[0], A.shape[0])])])
     h = vertcat([-f, b])
     z = solve(G, h)
     l_qi = self.q_i_struct.shape[0]
     l_qij = self.q_ij_struct.shape[0]
     z_i_new = self.q_i_struct(z[:l_qi])
     z_ij_new = self.q_ij_struct(z[l_qi:l_qi+l_qij])
     # transform back
     tf = lambda cfs, basis: shift_knot1_bwd(cfs, basis, t0)
     self._transform_spline(z_i_new, tf, self.q_i)
     self._transform_spline(z_ij_new, tf, self.q_ij)
     out = [z_i_new.cat, z_ij_new.cat]
     # create problem
     prob, compile_time = self.father.create_function(
         'upd_z', inp, out, self.options)
     self.problem_upd_z = prob
示例#5
0
def generate_nested_dict_struct(v):

    # empty entry list
    entry_list = []

    # iterate over all dict values
    for k1, v1 in v.items():

        if isinstance(v1, dict):

            # if value is a dict, recursively generate subdict struct
            substruct = generate_nested_dict_struct(v1)
            entry_list.append(cas.entry(k1, struct=substruct))

        else:
            if isinstance(v1, float) or isinstance(v1, int):
                shape = (1, 1)
            else:
                shape = v1.shape
            # append value to entry list
            entry_list.append(cas.entry(k1, shape=shape))

    # make overall structure
    subdict_struct = cas.struct_symSX(entry_list)

    return subdict_struct
示例#6
0
    def _defineOptimizationVariablesAndBounds(self):

        # definition of constraints on x and u

        lb_x = 20 * np.array([-3, -2, -2, -2, -2, -2])
        ub_x = 20 * np.array([3, 2, 2, 2, 2, 2])

        lb_u = -4 * np.ones((self.nu, 1))
        ub_u = 4 * np.ones((self.nu, 1))

        opt_x = struct_symSX([
            entry('x', shape=self.nx, repeat=[self.N + 1, self.K + 1]),
            entry('u', shape=self.nu, repeat=[self.N])
        ])

        # initialize bounds with all zero according to opt_x structure
        lb_opt_x = opt_x(0)
        ub_opt_x = opt_x(0)

        # set bounds
        lb_opt_x['x'] = lb_x
        ub_opt_x['x'] = ub_x
        lb_opt_x['u'] = lb_u
        ub_opt_x['u'] = ub_u

        return opt_x, lb_opt_x, ub_opt_x
示例#7
0
def create_plan_fc(b0, N_sim):
    # Degrees of freedom for the optimizer
    V = cat.struct_symSX([
            (
                cat.entry('X',repeat=N_sim+1,struct=belief),
                cat.entry('U',repeat=N_sim,struct=control)
            )
        ])
    
    # Objective function
    m_bN = V['X',N_sim,'m',ca.veccat,['x_b','y_b']]
    m_cN = V['X',N_sim,'m',ca.veccat,['x_c','y_c']]
    dm_bc = m_bN - m_cN
    J = 1e2 * ca.mul(dm_bc.T, dm_bc) # m_cN -> m_bN
    J += 1e-1 * ca.trace(V['X',N_sim,'S']) # Sigma -> 0
    # Regularize controls
    J += 1e-2 * ca.sum_square(ca.veccat(V['U'])) * dt # prevent bang-bang
    
    # Multiple shooting constraints and running costs
    g = []
    for k in range(N_sim):
        # Multiple shooting
        [x_next] = BF([V['X',k], V['U',k]])
        g.append(x_next - V['X',k+1])
        
        # Penalize uncertainty
        J += 1e-1 * ca.trace(V['X',k,'S']) * dt
    g = ca.vertcat(g)
    
    # log-probability, doesn't work with full collocation
    #Sb = V['X',N_sim,'S',['x_b','y_b'], ['x_b','y_b']]
    #J += ca.mul([ dm_bc.T, ca.inv(Sb + 1e-8 * ca.SX.eye(2)), dm_bc ]) + \
    #     ca.log(ca.det(Sb + 1e-8 * ca.SX.eye(2)))
    
    # Formulate the NLP
    nlp = ca.SXFunction('nlp', ca.nlpIn(x=V), ca.nlpOut(f=J,g=g))
    
    # Create solver
    opts = {}
    opts['linear_solver'] = 'ma97'
    #opts['hessian_approximation'] = 'limited-memory'
    solver = ca.NlpSolver('solver', 'ipopt', nlp, opts)
    
    # Define box constraints
    lbx = V(-ca.inf)
    ubx = V(ca.inf)
    
    # 0 <= v <= v_max
    lbx['U',:,'v'] = 0; ubx['U',:,'v'] = v_max
    # -w_max <= w <= w_max
    lbx['U',:,'w'] = -w_max; ubx['U',:,'w'] = w_max
    
    # m(t=0) = m0
    lbx['X',0,'m'] = ubx['X',0,'m'] = b0['m']
    # S(t=0) = S0
    lbx['X',0,'S'] = ubx['X',0,'S'] = b0['S']
    
    # Solve the NLP
    sol = solver(x0=0, lbg=0, ubg=0, lbx=lbx, ubx=ubx)
    return V(sol['x'])
示例#8
0
def generate_variable_struct(variable_list):

    structs = {}
    for name in list(variable_list.keys()):
        structs[name] = cas.struct_symSX([
            cas.entry(variable_list[name][i][0],
                      shape=variable_list[name][i][1])
            for i in range(len(variable_list[name]))
        ])

    variable_struct = cas.struct_symSX([
        cas.entry(name, struct=structs[name])
        for name in list(variable_list.keys())
    ])

    return variable_struct, structs
示例#9
0
def setup_constraint_structure(nlp_numerics_options, model, formulation):

    constraints_entry_list = make_constraints_entry_list(nlp_numerics_options, formulation.constraints, model)

    # Constraints structure
    g_struct = cas.struct_symSX(constraints_entry_list)

    return g_struct
示例#10
0
def setup_nlp_p_fix(V, model):

    # fixed system parameters
    p_fix = cas.struct_symSX([(
        cas.entry('ref', struct=V),  # tracking reference for cost function
        cas.entry('weights',
                  struct=model.variables)  # weights for cost function
    )])

    return p_fix
示例#11
0
    def create_belief_plan(cls, model, warm_start=False,
                           x0=0, lam_x0=0, lam_g0=0):
        # Degrees of freedom for the optimizer
        V = cat.struct_symSX([
            (
                cat.entry('X', repeat=model.n+1, struct=model.x),
                cat.entry('U', repeat=model.n, struct=model.u)
            )
        ])

        # Box constraints
        [lbx, ubx] = cls._create_box_constraints(model, V)

        # Non-linear constraints
        [g, lbg, ubg] = cls._create_belief_nonlinear_constraints(model, V)

        # Objective function
        J = cls._create_belief_objective_function(model, V)

        # Formulate non-linear problem
        nlp = ca.SXFunction('nlp', ca.nlpIn(x=V), ca.nlpOut(f=J, g=g))
        op = {# Linear solver
              #'linear_solver':              'ma57',
              # Warm start
              # 'warm_start_init_point':      'yes',
              # Termination
              'max_iter':                   1500,
              'tol':                        1e-6,
              'constr_viol_tol':            1e-5,
              'compl_inf_tol':              1e-4,
              # Acceptable termination
              'acceptable_tol':             1e-3,
              'acceptable_iter':            5,
              'acceptable_obj_change_tol':  1e-2,
              # NLP
              # 'fixed_variable_treatment':   'make_constraint',
              # Quasi-Newton
              'hessian_approximation':      'limited-memory',
              'limited_memory_max_history': 5,
              'limited_memory_max_skipping': 1}

        if warm_start:
            op['warm_start_init_point'] = 'yes'
            op['fixed_variable_treatment'] = 'make_constraint'

        # Initialize solver
        solver = ca.NlpSolver('solver', 'ipopt', nlp, op)

        # Solve
        if warm_start:
            sol = solver(x0=x0, lbx=lbx, ubx=ubx, lbg=lbg, ubg=ubg,
                         lam_x0=lam_x0, lam_g0=lam_g0)
        else:
            sol = solver(x0=x0, lbx=lbx, ubx=ubx, lbg=lbg, ubg=ubg)
        return V(sol['x']), sol['lam_x'], sol['lam_g']
示例#12
0
    def get_structure(self, cstr_type):

        cstr_list = self.get_list(cstr_type)

        entry_list = []
        for cstr in cstr_list:
            joined_name = cstr.name
            local = cas.entry(joined_name, shape=cstr.expr.shape)
            entry_list.append(local)

        return cas.struct_symSX(entry_list)
示例#13
0
def make_stage_constraint_struct(model):

    # make entry list to check if not empty
    entry_list = [cas.entry('collocation', shape =model.dynamics(model.variables, model.parameters).size())]
    if list(model.constraints.keys()):  # check if not empty
        entry_list.append(cas.entry('path_constraints', struct = model.constraints))

    # stage constraints structure -- necessary for interleaving
    stage_constraints = cas.struct_symSX(entry_list)

    return stage_constraints
示例#14
0
文件: admm.py 项目: jgillis/omg-tools
 def construct_upd_l(self):
     # create parameters
     x_i = struct_symSX(self.q_i_struct)
     z_i = struct_symSX(self.q_i_struct)
     z_ij = struct_symSX(self.q_ij_struct)
     l_i = struct_symSX(self.q_i_struct)
     l_ij = struct_symSX(self.q_ij_struct)
     x_j = struct_symSX(self.q_ij_struct)
     t = SX.sym('t')
     T = SX.sym('T')
     rho = SX.sym('rho')
     t0 = t/T
     inp = [x_i, z_i, z_ij, l_i, l_ij, x_j, t, T, rho]
     # put symbols in SX structs (necessary for transformation)
     x_i = self.q_i_struct(x_i)
     z_i = self.q_i_struct(z_i)
     z_ij = self.q_ij_struct(z_ij)
     l_i = self.q_i_struct(l_i)
     l_ij = self.q_ij_struct(l_ij)
     x_j = self.q_ij_struct(x_j)
     # transform spline variables: only consider future piece of spline
     tf = lambda cfs, basis: shift_knot1_fwd(cfs, basis, t0)
     self._transform_spline([x_i, z_i, l_i], tf, self.q_i)
     self._transform_spline([x_j, z_ij, l_ij], tf, self.q_ij)
     # update lambda
     l_i_new = self.q_i_struct(l_i.cat + rho*(x_i.cat - z_i.cat))
     l_ij_new = self.q_ij_struct(l_ij.cat + rho*(x_j.cat - z_ij.cat))
     tf = lambda cfs, basis: shift_knot1_bwd(cfs, basis, t0)
     self._transform_spline(l_i_new, tf, self.q_i)
     self._transform_spline(l_ij_new, tf, self.q_ij)
     out = [l_i_new, l_ij_new]
     # create problem
     prob, compile_time = self.father.create_function(
         'upd_l', inp, out, self.options)
     self.problem_upd_l = prob
示例#15
0
def get_phase_fix_theta(variables_dict):

    entry_list = []
    for name in list(variables_dict['theta'].keys()):
        if name == 't_f':
            entry_list.append(cas.entry('t_f', shape=(2, 1)))
        else:
            entry_list.append(
                cas.entry(name, shape=variables_dict['theta'][name].shape))

    theta = cas.struct_symSX(entry_list)

    return theta
示例#16
0
def make_entry_list(eqs_dict, ineqs_dict):

    # make entry list for all non-empty dicts
    entry_list = []
    if eqs_dict:  # check if not empty

        # equality constraint struct
        eq_struct = cas.struct_symSX([
            cas.entry(name, shape=eqs_dict[name].size())
            for name in list(eqs_dict.keys())
        ])
        entry_list.append(cas.entry('equality', struct=eq_struct))

    if ineqs_dict:  # check if not empty

        # inequality constraint struct
        ineq_struct = cas.struct_symSX([
            cas.entry(name, shape=ineqs_dict[name].size())
            for name in list(ineqs_dict.keys())
        ])
        entry_list.append(cas.entry('inequality', struct=ineq_struct))

    return entry_list
示例#17
0
def setup_nlp_cost():

    cost = cas.struct_symSX([
        (cas.entry('tracking'), cas.entry('u_regularisation'),
         cas.entry('ddq_regularisation'),
         cas.entry('gamma'), cas.entry('iota'), cas.entry('psi'),
         cas.entry('tau'), cas.entry('eta'), cas.entry('nu'),
         cas.entry('upsilon'), cas.entry('fictitious'), cas.entry('power'),
         cas.entry('t_f'), cas.entry('theta_regularisation'),
         cas.entry('nominal_landing'), cas.entry('compromised_battery'),
         cas.entry('transition'), cas.entry('slack'))
    ])

    return cost
示例#18
0
def create_simple_plan(x0, N_sim):
    # Degrees of freedom for the optimizer
    V = cat.struct_symSX([
            (
                cat.entry('X',repeat=N_sim+1,struct=state),
                cat.entry('U',repeat=N_sim,struct=control)
            )
        ])

    # Objective function
    x_bN = V['X',N_sim,ca.veccat,['x_b','y_b']]
    x_cN = V['X',N_sim,ca.veccat,['x_c','y_c']]
    dx_bc = x_bN - x_cN
    J = 1e1 * ca.mul(dx_bc.T, dx_bc) # x_cN -> x_bN
    
    # Regularize controls
    J += 1e-1 * ca.sum_square(ca.veccat(V['U'])) * dt # prevent bang-bang

    # Multiple shooting constraints and non-linear control constraints
    g = []
    for k in range(N_sim):
        # Multiple shooting
        [x_next] = F([V['X',k], V['U',k], dt])
        g.append(x_next - V['X',k+1])        
    g = ca.vertcat(g)

    # Formulate the NLP
    nlp = ca.SXFunction('nlp', ca.nlpIn(x=V), ca.nlpOut(f=J,g=g))

    opts = {}
    #opts['hessian_approximation'] = 'limited-memory'
    opts['linear_solver'] = 'ma57'
    # Create a solver
    solver = ca.NlpSolver('solver', 'ipopt', nlp, opts)
    
    # Define box constraints
    lbx = V(-ca.inf)
    ubx = V(ca.inf)
    
    # 0 <= v <= v_max
    lbx['U',:,'v'] = 0; ubx['U',:,'v'] = v_max
    # -w_max <= w <= w_max
    lbx['U',:,'w'] = -w_max; ubx['U',:,'w'] = w_max
    
    # m(t=0) = m0
    lbx['X',0] = ubx['X',0] = x0
    
    # Solve the NLP
    sol = solver(x0=0, lbg=0, ubg=0, lbx=lbx, ubx=ubx)
    return V(sol['x'])
def __get_sstruct(dictionary):
    """Convert a dictionary to a casadi struct with the same structure and entries for 0th, 1st and 2nd derivatives

    :type dictionary: dict
    :param dictionary: variables to be put into the struct

    :rtype: casadi.struct_symSX
    """

    struct_list = []

    for key in list(dictionary.keys()):
        if key[0] != 'd':
            struct_list += [(key, dictionary[key].shape)]

    sub_struct = ct.struct_symSX([
        ct.entry(struct_list[i][0], shape=struct_list[i][1])
        for i in range(len(struct_list))
    ])

    dsub_struct = ct.struct_symSX([
        ct.entry('d' + struct_list[i][0], shape=struct_list[i][1])
        for i in range(len(struct_list))
    ])

    ddsub_struct = ct.struct_symSX([
        ct.entry('dd' + struct_list[i][0], shape=struct_list[i][1])
        for i in range(len(struct_list))
    ])

    sstruct = ct.struct_symSX([
        ct.entry('var', struct=sub_struct),
        ct.entry('dvar', struct=dsub_struct),
        ct.entry('ddvar', struct=ddsub_struct)
    ])

    return sstruct
示例#20
0
文件: system.py 项目: wuyou33/awebox
def generate_system_parameters(options):

    # extract parametric options
    parametric_options = options['params']

    parameters_dict = {}
    # generate nested casadi structure for system parameters
    parameters_dict['theta0'] = struct_op.generate_nested_dict_struct(parametric_options)
    parameters_dict['phi'] = generate_optimization_parameters()

    parameters = cas.struct_symSX([
        cas.entry('theta0', struct= parameters_dict['theta0']),
        cas.entry('phi', struct= parameters_dict['phi'])]
    )

    return parameters, parameters_dict
示例#21
0
文件: system.py 项目: wuyou33/awebox
def generate_optimization_parameters():

    # variable system parameters
    p_dec = cas.struct_symSX([(
        cas.entry('gamma'), # force homotopy variable
        cas.entry('tau'),   # tether drag homotopy variable
        cas.entry('iota'),  # induction homotopy variable
        cas.entry('psi'),    # power homotopy variable
        cas.entry('eta'),  # nominal landing homotopy variable
        cas.entry('nu'),  # compromised landing homotopy variable
        cas.entry('upsilon'),  # transition homotopy variable
    )])

    optimization_parameters = p_dec

    return optimization_parameters
示例#22
0
def test_affine_constraint():
    var = struct_symSX([entry('x', shape=(2, 1))])
    linear_coefficient = np.eye(2) * 2
    affine_coefficient = np.ones((2, ))
    lower_bound = np.zeros((2, 1))
    upper_bound = np.ones((2, 1))

    constr = AffineConstraint.gen(var, linear_coefficient, affine_coefficient,
                                  lower_bound, upper_bound)

    g, lb, ub = constr[0]

    assert (lb == (lower_bound - affine_coefficient)).all()
    assert (ub == (upper_bound - affine_coefficient)).all()
    assert '@1=2, [(@1*x_0), (@1*x_1)]' == str(g)
    assert np.equal(Function('g_fun', [var['x']], [g])([2, 2]), [4, 4]).all()
示例#23
0
def gen(NX, NU, M):
    """gen Generates a casadi struct containing the symbolic optimization parameters
    x_cur (the initial state), x_ref (the reference states) and u_cur (the reference controls).
    x_cur is a <NX>x<1> vector, x_ref is a <NX>x<M+1> matrix, u_ref is a <NU>x<M> matrix

    :param NX: Number of reference state variables
    :param NU: Number of reference control variables
    :param M: Prediction horizon length

    :returns: A casadi struct_symSX object
    """

    params = struct_symSX([
        entry('x_cur', shape=NX),
        entry('x_ref', shape=(NX, M + 1)),
        entry('u_ref', shape=(NU, M))
    ])

    return params
示例#24
0
    def create_plan(cls, model, warm_start=False,
                    x0=0, lam_x0=0, lam_g0=0):
        # Degrees of freedom for the optimizer
        V = cat.struct_symSX([
            (
                cat.entry('X', repeat=model.n+1, struct=model.x),
                cat.entry('U', repeat=model.n, struct=model.u)
            )
        ])

        # Box constraints
        [lbx, ubx] = cls._create_box_constraints(model, V)

        # Force the catcher to always look forward
        # lbx['U', :, 'theta'] = ubx['U', :, 'theta'] = 0

        # Non-linear constraints
        [g, lbg, ubg] = cls._create_nonlinear_constraints(model, V)

        # Objective function
        J = cls._create_objective_function(model, V, warm_start)

        # Formulate non-linear problem
        nlp = ca.SXFunction('nlp', ca.nlpIn(x=V), ca.nlpOut(f=J, g=g))
        op = {# Linear solver
              #'linear_solver':              'ma57',
              # Acceptable termination
              'acceptable_iter':            5}

        if warm_start:
            op['warm_start_init_point'] = 'yes'
            op['fixed_variable_treatment'] = 'make_constraint'

        # Initialize solver
        solver = ca.NlpSolver('solver', 'ipopt', nlp, op)

        # Solve
        if warm_start:
            sol = solver(x0=x0, lbx=lbx, ubx=ubx, lbg=lbg, ubg=ubg,
                         lam_x0=lam_x0, lam_g0=lam_g0)
        else:
            sol = solver(x0=x0, lbx=lbx, ubx=ubx, lbg=lbg, ubg=ubg)
        return V(sol['x']), sol['lam_x'], sol['lam_g']
示例#25
0
def setup_output_structure(nlp_numerics_options, model_outputs, form_outputs):
    # create outputs
    # n_o_t_e: !!! outputs are defined at nodes where both state and algebraic variables
    # are defined. In the radau case, algebraic variables are not defined on the interval
    # nodes, note however that algebraic variables might be discontinuous so the same
    # holds for the outputs!!!
    nk = nlp_numerics_options['n_k']

    entry_tuple = ()
    if nlp_numerics_options['discretization'] == 'direct_collocation':

        # extract collocation parameters
        d = nlp_numerics_options['collocation']['d']
        scheme = nlp_numerics_options['collocation']['scheme']

        if scheme != 'radau':

            # define outputs on interval and collocation nodes
            entry_tuple += (
                cas.entry('outputs', repeat=[nk], struct=model_outputs),
                cas.entry('coll_outputs', repeat=[nk, d],
                          struct=model_outputs),
            )

        else:

            # define outputs on collocation nodes
            entry_tuple += (cas.entry('coll_outputs',
                                      repeat=[nk, d],
                                      struct=model_outputs), )

    elif nlp_numerics_options['discretization'] == 'multiple_shooting':

        # define outputs on interval nodes
        entry_tuple += (cas.entry('outputs', repeat=[nk],
                                  struct=model_outputs), )

    Outputs = cas.struct_symSX([entry_tuple] +
                               [cas.entry('final', struct=form_outputs)])

    return Outputs
示例#26
0
def get_costs_struct(V):

    costs_struct = cas.struct_symSX([
        cas.entry("tracking_cost"),
        cas.entry("ddq_regularisation_cost"),
        cas.entry("u_regularisation_cost"),
        cas.entry("fictitious_cost"),
        cas.entry("theta_regularisation_cost"),
        cas.entry("slack_cost")
    ] + [cas.entry(name + '_cost') for name in struct_op.subkeys(V, 'phi')] + [
        cas.entry("time_cost"),
        cas.entry("power_cost"),
        cas.entry("nominal_landing_cost"),
        cas.entry("transition_cost"),
        cas.entry("compromised_battery_cost"),
        cas.entry("tracking_problem_cost"),
        cas.entry("power_problem_cost"),
        cas.entry("general_problem_cost"),
        cas.entry("objective")
    ])

    return costs_struct
示例#27
0
def gen(NX, NU, M, stateBounds=None, controlBounds=None):
    """gen Generates a casadi struct containing the symbolic optimization variables required
    for direct multiple shooting. x is a <NX>x<M+1> matrix, u is a <NU>x<M> matrix.

    :param NX: Number of state variables
    :param NU: Number of control variables
    :param M: Prediction horizon length

    :returns: A casadi struct_symSX object
    """

    # decision (free) variables
    variables = struct_symSX(
        [entry('x', shape=(NX, M + 1)),
         entry('u', shape=(NU, M))])

    # symbolic bounds
    bx = ca.SX.sym('bx', NX)
    bu = ca.SX.sym('bu', NU)

    # bounds struct, must be identical to variables struct in dimensions and keys
    bounds = struct_SX([
        entry('x', expr=ca.repmat(bx, 1, M + 1)),
        entry('u', expr=ca.repmat(bu, 1, M))
    ])
    boundsFun = ca.Function('varBoundsFun', [bx, bu], [bounds.cat])

    if stateBounds is None:
        stateBounds = np.multiply(np.ones((2, NX)),
                                  np.array((-np.inf, np.inf), ndmin=2).T)

    if controlBounds is None:
        controlBounds = np.multiply(np.ones((2, NU)),
                                    np.array((-np.inf, np.inf), ndmin=2).T)

    lbw = boundsFun(stateBounds[0, :], controlBounds[0, :])
    ubw = boundsFun(stateBounds[1, :], controlBounds[1, :])

    return variables, lbw, ubw
示例#28
0
def create_simple_plan(x0, F, dt, N_sim):
    # Degrees of freedom for the optimizer
    V = cat.struct_symSX([
            (
                cat.entry('X',repeat=N_sim+1,struct=state),
                cat.entry('U',repeat=N_sim,struct=control)
            )
        ])

    # Final position
    x_bN = V['X',N_sim,ca.veccat,['x_b','y_b']]
    x_cN = V['X',N_sim,ca.veccat,['x_c','y_c']]
    dx_bc = x_bN - x_cN
    
    # Final velocity
    v_bN = V['X',N_sim,ca.veccat,['vx_b','vy_b']]
    v_cN = V['X',N_sim,ca.veccat,['vx_c','vy_c']]
    dv_bc = v_bN - v_cN
    
    # Angle between gaze and ball velocity
    theta = V['X',N_sim,'theta']
    phi = V['X',N_sim,'phi']
    d = ca.veccat([ ca.cos(theta)*ca.cos(phi), ca.cos(theta)*ca.sin(phi), ca.sin(theta) ])
    r = V['X',N_sim,ca.veccat,['vx_b','vy_b','vz_b']]
示例#29
0
def shift_trajectory(state, u):
    ##########################################################
    ## state and u in form (state, N)
    state_ = np.concatenate((state.T[1:], state.T[-1:]))
    u_ = np.concatenate((u.T[1:], u.T[-1:]))
    return u_, state_


if __name__ == '__main__':
    T = 0.2  # sampling time [s]
    N = 100  # prediction horizon
    rob_diam = 0.3  # [m]
    v_max = 0.6
    omega_max = np.pi / 4.0

    states = ca_tools.struct_symSX([(ca_tools.entry('x'), ca_tools.entry('y'),
                                     ca_tools.entry('theta'))])
    x, y, theta = states[...]
    n_states = states.size

    controls = ca_tools.struct_symSX([(ca_tools.entry('v'),
                                       ca_tools.entry('omega'))])
    v, omega = controls[...]
    n_controls = controls.size

    ## rhs
    rhs = ca_tools.struct_SX(states)
    rhs['x'] = v * ca.cos(theta)
    rhs['y'] = v * ca.sin(theta)
    rhs['theta'] = omega

    ## function
#xlb = np.array([0.5, 0.8, 0])
#xub = np.array([2.5, 2.0, 400])
#<<ENDCHUNK>>

# Make optimizers.
x0 = np.array([.05 * cs, .75 * Ts, .5 * hs])
u0 = np.array([Tcs, Fs])
umax = np.array([.05 * Tcs, .15 * Fs])
dumax = .2 * umax
xlb = np.array([-np.inf, -np.inf, -np.inf])
xub = np.array([np.inf, np.inf, np.inf])

# Create variables struct.
var = ctools.struct_symSX([(
    ctools.entry("x", shape=(Nx, ), repeat=Nt + 1),
    ctools.entry("u", shape=(Nu, ), repeat=Nt),
    ctools.entry("Du", shape=(Nu, ), repeat=Nt),
)])
varlb = var(-np.inf)
varub = var(np.inf)
varguess = var(0)

# Create parameters struct.
par = ctools.struct_symSX([
    ctools.entry("x_sp", shape=(Nx, ), repeat=Nt + 1),
    ctools.entry("u_sp", shape=(Nu, ), repeat=Nt),
    ctools.entry("uprev", shape=(Nu, 1)),
    ctools.entry("Ad", repeat=Nt, shape=(Nx, Nx)),
    ctools.entry("Bd", repeat=Nt, shape=(Nx, Nu)),
    ctools.entry("fd", repeat=Nt, shape=(Nx, 1))
])
示例#31
0
from casadi import *
from casadi.tools import struct_symSX, struct_SX, entry

a = struct_symSX([
    entry('a', shape=(3, 1)),
    entry('b', shape=(3, 3)),
    entry('c', shape=(3, 1))
])

b = struct_symSX([entry('a_struct', struct=a)])
示例#32
0
    t = t0 + T
    u_end = ca.horzcat(u[:, 1:], u[:, -1])

    return t, st, u_end

if __name__ == '__main__':
    T = 0.2 # sampling time [s]
    N = 100 # prediction horizon
    rob_diam = 0.3 # [m]
    v_max = 0.6
    omega_max = np.pi/4.0

    states = ca_tools.struct_symSX([
        (
            ca_tools.entry('x'),
            ca_tools.entry('y'),
            ca_tools.entry('theta')
        )
    ])
    x, y, theta = states[...]
    n_states = states.size

    controls  = ca_tools.struct_symSX([
        (
            ca_tools.entry('v'),
            ca_tools.entry('omega')
        )
    ])
    v, omega = controls[...]
    n_controls = controls.size
示例#33
0
def create_plan_pc(b0, BF, dt, N_sim):
    # Degrees of freedom for the optimizer
    V = cat.struct_symSX([
            (
                cat.entry('X',repeat=N_sim+1,struct=state),
                cat.entry('U',repeat=N_sim,struct=control)
            )
        ])
    
    # Final coordinate
    x_bN = V['X',N_sim,ca.veccat,['x_b','y_b']]
    x_cN = V['X',N_sim,ca.veccat,['x_c','y_c']]
    dx_bc = x_bN - x_cN
    
    # Final velocity
    v_bN = V['X',N_sim,ca.veccat,['vx_b','vy_b']]
    v_cN = V['X',N_sim,ca.veccat,['vx_c','vy_c']]
    dv_bc = v_bN - v_cN
    
    # Angle between gaze and ball velocity
    theta = V['X',N_sim,'theta']
    phi = V['X',N_sim,'phi']
    d = ca.veccat([ ca.cos(theta)*ca.cos(phi), ca.cos(theta)*ca.sin(phi), ca.sin(theta) ])
    r = V['X',N_sim,ca.veccat,['vx_b','vy_b','vz_b']]
    r_unit = r / (ca.norm_2(r) + 1e-2)
    d_gaze = d - r_unit
    
    
    # Regularize controls
    J = 1e-2 * ca.sum_square(ca.veccat(V['U'])) * dt # prevent bang-bang
    
    # Multiple shooting constraints and running costs
    bk = cat.struct_SX(belief)
    bk['S'] = b0['S']
    g, lbg, ubg = [], [], []
    for k in range(N_sim):
        # Belief propagation
        bk['m'] = V['X',k]
        [bk_next] = BF([ bk, V['U',k] ])
        bk_next = belief(bk_next) # simplify indexing
        
        # Multiple shooting
        g.append(bk_next['m'] - V['X',k+1])
        lbg.append(ca.DMatrix.zeros(nx))
        ubg.append(ca.DMatrix.zeros(nx))

        # Control constraints
        g.append(V['U',k,'F'] - a - b * ca.cos(V['U',k,'psi']))
        lbg.append(-ca.inf)
        ubg.append(ca.DMatrix([0]))
        
        # Advance time
        bk = bk_next
    g = ca.vertcat(g)
    lbg = ca.veccat(lbg)
    ubg = ca.veccat(ubg)
    
    # Simple cost
    J += 1e1 * ca.mul(dx_bc.T, dx_bc) # coordinate
    J += 1e0 * ca.mul(dv_bc.T, dv_bc) # velocity
    #J += 1e0 * ca.mul(d_gaze.T, d_gaze) # gaze antialigned with ball velocity
    J += 1e1 * ca.trace(bk_next['S']) # uncertainty
    
    # log-probability cost
    #Sb = bk_next['S', ['x_b','y_b'], ['x_b','y_b']]
    #J += 1e1 * (ca.mul([ dm_bc.T, ca.inv(Sb), dm_bc ]) + ca.log(ca.det(Sb)))
    
    # Formulate the NLP
    nlp = ca.SXFunction('nlp', ca.nlpIn(x=V), ca.nlpOut(f=J,g=g))
    
    # Create solver
    opts = {}
    opts['linear_solver'] = 'ma97'
    #opts['hessian_approximation'] = 'limited-memory'
    solver = ca.NlpSolver('solver', 'ipopt', nlp, opts)
    
    # Define box constraints
    lbx = V(-ca.inf)
    ubx = V(ca.inf)
    
    # State constraints
    # catcher can look within the upper hemisphere
    lbx['X',:,'theta'] = 0; ubx['X',:,'theta'] = theta_max
    
    # Control constraints
    # 0 <= F
    lbx['U',:,'F'] = 0
    # -w_max <= w <= w_max
    lbx['U',:,'w'] = -w_max; ubx['U',:,'w'] = w_max
    # -pi <= psi <= pi
    lbx['U',:,'psi'] = -ca.pi; ubx['U',:,'psi'] = ca.pi
    
    # m(t=0) = m0
    lbx['X',0] = ubx['X',0] = b0['m']
    
    # Take care of the time
    #lbx['X',:,'T'] = 0.5; ubx['X',:,'T'] = ca.inf
    # Simulation ends when the ball touches the ground
    #lbx['X',N_sim,'z_b'] = ubx['X',N_sim,'z_b'] = 0
    
    # Solve the NLP
    sol = solver(x0=0, lbg=lbg, ubg=ubg, lbx=lbx, ubx=ubx)
    return V(sol['x'])
示例#34
0
N_ctrl = 2         # mpc replan horizon
N_delay = 3        # delay in perception

# Model
nx, nu, nz = 7, 2, 5
v_max = 10 # max speed
w_max = 1  # max rotation speed
a, b = 7.5, 2.5 # max speed restriction constants


# %% =========================================================================
#                               Variables
# ============================================================================

# State
state = cat.struct_symSX(['x_b','y_b','vx_b','vy_b',
                          'x_c','y_c','phi'])

# Control
control = cat.struct_symSX(['v','w'])

# Observation
observation = cat.struct_SX([
            cat.entry('x_b', expr = state['x_b']),
            cat.entry('y_b', expr = state['y_b']),
            cat.entry('x_c', expr = state['x_c']),
            cat.entry('y_c', expr = state['y_c']),
            cat.entry('phi', expr = state['phi'])
        ])

# Belief state (mu, Sigma)
belief = cat.struct_symSX([
示例#35
0
N_ctrl = 2  # mpc replan horizon
N_delay = 3  # delay in perception

# Model
nx, nu, nz = 9, 3, 6
w_max = 1  # max rotation speed
a, b = 4, 2  # max force restriction constants
g0 = 9.81  # gravity


# %% =========================================================================
#                               Variables
# ============================================================================

# State
state = cat.struct_symSX(["x_b", "y_b", "z_b", "vx_b", "vy_b", "vz_b", "x_c", "y_c", "phi"])

# Control
control = cat.struct_symSX(["v", "w", "psi"])

# Observation
observation = cat.struct_SX(
    [
        cat.entry("x_b", expr=state["x_b"]),
        cat.entry("y_b", expr=state["y_b"]),
        cat.entry("z_b", expr=state["z_b"]),
        cat.entry("x_c", expr=state["x_c"]),
        cat.entry("y_c", expr=state["y_c"]),
        cat.entry("phi", expr=state["phi"]),
    ]
)
l = casadi.Function("l", [x, u], [lfunc])

Pffunc = casadi.mtimes(x.T, x)
Pf = casadi.Function("Pf", [x], [Pffunc])

# Bounds on u.
uub = 1
ulb = -.75

# Make optimizers.
x0 = np.array([0, 1])

# Create variables struct.
var = ctools.struct_symSX([(
    ctools.entry("x", shape=(Nx, ), repeat=Nt + 1),
    ctools.entry("xc", shape=(Nx, Nc), repeat=Nt),
    ctools.entry("u", shape=(Nu, ), repeat=Nt),
)])
varlb = var(-np.inf)
varub = var(np.inf)
varguess = var(0)

# Adjust the relevant constraints.
for t in range(Nt):
    varlb["u", t, :] = ulb
    varub["u", t, :] = uub

# Now build up constraints and objective.
obj = casadi.SX(0)
con = []
for t in range(Nt):
    def create_optim(self):
        # Initialize trajectory lists (each list item, one time-step):
        self.mpc_obj_x = mpc_obj_x = struct_symSX([
            entry('x', repeat=self.N_steps+1, struct=self.mpc_xk),
            entry('u', repeat=self.N_steps, struct=self.mpc_uk),
            entry('eps', repeat=self.N_steps+1, struct=self.mpc_eps)
        ])

        # Note that:
        # x = [x_0, x_1, ... , x_N+1]   (N+1 elements)
        # u = [u_0, u_1, ... , u_N]     (N elements)
        # For the optimization variable x_0 we introduce the simple equality constraint that it has
        # to be equal to the parameter x0 (mpc_obj_p)
        self.mpc_obj_p = mpc_obj_p = struct_symSX([
            entry('tvp', repeat=self.N_steps, struct=self.mpc_tvpk),
            entry('x0',  struct=self.mpc_xk),
            entry('p',   struct=self.mpc_pk),
            entry('pN',  struct=self.mpc_pN)
        ])

        # Dummy struct with symbolic variables
        aux_struct = struct_symSX([
            entry('aux', repeat=self.N_steps, struct=self.mpc_aux_expr)
        ])

        # Create mutable symbolic expression from the struct defined above.
        self.mpc_obj_aux = mpc_obj_aux = struct_SX(aux_struct)

        # Initialize objective value:
        obj = 0
        # Initialize constraings:
        cons = []
        cons_ub = []
        cons_lb = []

        # Equality constraint for first state:
        cons.append(mpc_obj_x['x', 0]-mpc_obj_p['x0'])
        cons_lb.append(np.zeros(self.mpc_xk.shape))
        cons_ub.append(np.zeros(self.mpc_xk.shape))

        # Recursively evaluate system equation and add stage cost and stage constraints:
        for k in range(self.N_steps):
            mpc_xk_next = self.mpc_problem['model'](mpc_obj_x['x', k], mpc_obj_x['u', k], mpc_obj_p['tvp', k], mpc_obj_p['p'])
            # State constraint:
            cons.append(mpc_xk_next-mpc_obj_x['x', k+1])
            cons_lb.append(np.zeros(self.mpc_xk.shape))
            cons_ub.append(np.zeros(self.mpc_xk.shape))

            # Add the "stage cost" to the objective
            obj += self.mpc_problem['stage_cost'](mpc_obj_x['x', k], mpc_obj_x['u', k], mpc_obj_x['eps', k], mpc_obj_p['tvp', k], mpc_obj_p['p'])

            # Constraints for the current step
            cons.append(self.mpc_problem['cons'](mpc_obj_x['x', k], mpc_obj_x['u', k], mpc_obj_x['eps', k], mpc_obj_p['tvp', k], mpc_obj_p['p']))
            cons_lb.append(self.mpc_problem['cons_lb'])
            cons_ub.append(self.mpc_problem['cons_ub'])

            # Calculate auxiliary values:
            mpc_obj_aux['aux', k] = self.mpc_problem['aux'](mpc_obj_x['x', k], mpc_obj_x['u', k], mpc_obj_x['eps', k], mpc_obj_p['tvp', k], mpc_obj_p['p'])

        # Terminal cost:
        obj += self.mpc_problem['terminal_cost'](mpc_obj_x['x', -1], mpc_obj_x['eps', -1])

        # Terminal set:
        cons.append(self.mpc_problem['tcons'](mpc_obj_x['x', -1], mpc_obj_x['eps', -1], mpc_obj_p['pN']))
        cons_lb.append(self.mpc_problem['tcons_lb'])
        cons_ub.append(self.mpc_problem['tcons_ub'])

        # Upper and lower bounds on objective x:
        self.mpc_obj_x_lb = self.mpc_obj_x(0)
        self.mpc_obj_x_ub = self.mpc_obj_x(0)

        self.mpc_obj_x_lb['x', :] = self.mpc_xk_lb
        self.mpc_obj_x_ub['x', :] = self.mpc_xk_ub

        self.mpc_obj_x_lb['u', :] = self.mpc_uk_lb
        self.mpc_obj_x_ub['u', :] = self.mpc_uk_ub

        self.mpc_obj_x_lb['eps', :] = self.mpc_epsk_lb
        self.mpc_obj_x_ub['eps', :] = self.mpc_epsk_ub

        optim_dict = {'x': mpc_obj_x,       # Optimization variable
                      'f': obj,             # objective
                      'g': vertcat(*cons),  # constraints
                      'p': mpc_obj_p}       # parameters
        self.cons_lb = vertcat(*cons_lb)
        self.cons_ub = vertcat(*cons_ub)

        # Use the structured data obj_x and obj_p and create identically organized copies with numerical values (initialized to zero)
        self.mpc_obj_x_num = self.mpc_obj_x(0)
        self.mpc_obj_p_num = self.mpc_obj_p(0)
        self.mpc_obj_aux_num = self.mpc_obj_aux(0)

        # TODO: Make optimization option available to user.
        # Create casadi optimization object:
        opts = {'ipopt.linear_solver': 'ma27', 'error_on_fail': False, 'ipopt.tol': 1e-8, 'ipopt.max_iter': 300}
        self.optim = nlpsol('optim', 'ipopt', optim_dict, opts)
        if self.silent:
            opts['ipopt.print_level'] = 0
            opts['ipopt.sb'] = "yes"
            opts['print_time'] = 0

        # Create function to calculate buffer memory from parameter and optimization variable trajectories
        self.aux_fun = Function('aux_fun', [mpc_obj_x, mpc_obj_p], [mpc_obj_aux])
    u_ = np.zeros((N_, 2))
    for i in range(N_):
        u_[i] = data[i * 5:i * 5 + 2].T
        x_[i] = data[i * 5 + 2:i * 5 + 5].T
    x_[-1] = data[-3:].T
    return u_, x_


if __name__ == '__main__':
    T = 0.5  # sampling time [s]
    N = 8  # prediction horizon
    rob_diam = 0.3  # [m]
    v_max = 0.6
    omega_max = np.pi / 4.0

    states = ca_tools.struct_symSX([(ca_tools.entry('x'), ca_tools.entry('y'),
                                     ca_tools.entry('theta'))])
    x, y, theta = states[...]
    n_states = states.size

    controls = ca_tools.struct_symSX([(ca_tools.entry('v'),
                                       ca_tools.entry('omega'))])
    v, omega = controls[...]
    n_controls = controls.size

    ## rhs
    rhs = ca_tools.struct_SX(states)
    rhs['x'] = v * ca.cos(theta)
    rhs['y'] = v * ca.sin(theta)
    rhs['theta'] = omega

    ## function
示例#39
0
def create_plan_pc(b0, N_sim):
    # Degrees of freedom for the optimizer
    V = cat.struct_symSX([
            (
                cat.entry('X',repeat=N_sim+1,struct=state),
                cat.entry('U',repeat=N_sim,struct=control)
            )
        ])
    
    # Final means
    m_bN = V['X',N_sim,ca.veccat,['x_b','y_b']]
    m_cN = V['X',N_sim,ca.veccat,['x_c','y_c']]
    dm_bc = m_bN - m_cN
    
    # Regularize controls
    J = 1e-2 * ca.sum_square(ca.veccat(V['U'])) * dt # prevent bang-bang
    
    # Multiple shooting constraints and running costs
    bk = cat.struct_SX(belief)
    bk['S'] = b0['S']
    g = []
    lbg = []
    ubg = []
    for k in range(N_sim):
        # Belief propagation
        bk['m'] = V['X',k]
        [bk_next] = BF([ bk, V['U',k] ])
        bk_next = belief(bk_next) # simplify indexing
        
        # Multiple shooting
        g.append(bk_next['m'] - V['X',k+1])
        lbg.append(ca.DMatrix.zeros(nx))
        ubg.append(ca.DMatrix.zeros(nx))

        # Control constraints
        g.append(V['U',k,'v'] - a - b * ca.cos(V['U',k,'psi']))
        lbg.append(-ca.inf)
        ubg.append(ca.DMatrix([0]))
        
        # Advance time
        bk = bk_next
    g = ca.vertcat(g)
    lbg = ca.veccat(lbg)
    ubg = ca.veccat(ubg)
    
    # Simple cost
    J += 1e1 * (ca.mul(dm_bc.T, dm_bc) + ca.trace(bk_next['S']))
    
    # log-probability cost
    #Sb = bk_next['S', ['x_b','y_b'], ['x_b','y_b']]
    #J += 1e1 * (ca.mul([ dm_bc.T, ca.inv(Sb), dm_bc ]) + ca.log(ca.det(Sb)))
    
    # Formulate the NLP
    nlp = ca.SXFunction('nlp', ca.nlpIn(x=V), ca.nlpOut(f=J,g=g))
    
    # Create solver
    opts = {}
    opts['linear_solver'] = 'ma97'
    #opts['hessian_approximation'] = 'limited-memory'
    solver = ca.NlpSolver('solver', 'ipopt', nlp, opts)
    
    # Define box constraints
    lbx = V(-ca.inf)
    ubx = V(ca.inf)
    
    # 0 <= v
    lbx['U',:,'v'] = 0
    # -w_max <= w <= w_max
    lbx['U',:,'w'] = -w_max; ubx['U',:,'w'] = w_max
    # -pi <= psi <= pi
    lbx['U',:,'psi'] = -ca.pi; ubx['U',:,'psi'] = ca.pi
    
    # m(t=0) = m0
    lbx['X',0] = ubx['X',0] = b0['m']
    
    # Solve the NLP
    sol = solver(x0=0, lbg=lbg, ubg=ubg, lbx=lbx, ubx=ubx)
    return V(sol['x'])
示例#40
0
nu = 2

# Initial condition
x0 = ca.DMatrix([10, 6, ca.pi])

# Identity matrix
Inx = ca.DMatrix.eye(nx)


# ----------------------------------------------------------------------------
#                                 Dynamics
# ----------------------------------------------------------------------------

# Continuous dynamics
dt_sym = ca.SX.sym('dt')
state = cat.struct_symSX(['x', 'y', 'phi'])
control = cat.struct_symSX(['v', 'w'])
rhs = cat.struct_SX(state)
rhs['x'] = control['v'] * ca.cos(state['phi'])
rhs['y'] = control['v'] * ca.sin(state['phi'])
rhs['phi'] = control['w']
f = ca.SXFunction('Continuous dynamics', [state, control], [rhs])

# Discrete dynamics
state_next = state + dt_sym * f([state, control])[0]
op = {'input_scheme': ['state', 'control', 'dt'],
      'output_scheme': ['state_next']}
F = ca.SXFunction('Discrete dynamics',
                  [state, control, dt_sym], [state_next], op)
Fj_x = F.jacobian('state')
Fj_u = F.jacobian('control')
示例#41
0
def make_constraint_struct(eqs_dict, ineqs_dict):

    entry_list = make_entry_list(eqs_dict, ineqs_dict)
    constraint_struct = cas.struct_symSX(entry_list)

    return constraint_struct
示例#42
0
def test(gamma_scale=1.):

    architecture = archi.Architecture({1: 0})

    options = {}
    options['induction'] = {}
    options['induction']['vortex_gamma_scale'] = gamma_scale
    options['induction']['vortex_wake_nodes'] = 2
    options['induction']['vortex_far_convection_time'] = 1.
    options['induction']['vortex_u_ref'] = 1.
    options['induction']['vortex_position_scale'] = 1.

    kite = architecture.kite_nodes[0]

    xd_struct = cas.struct([
        cas.entry("wx_" + str(kite) + "_ext_0", shape=(3, 1)),
        cas.entry("wx_" + str(kite) + "_ext_1", shape=(3, 1)),
        cas.entry("wx_" + str(kite) + "_int_0", shape=(3, 1)),
        cas.entry("wx_" + str(kite) + "_int_1", shape=(3, 1))
    ])
    xl_struct = cas.struct([cas.entry("wg_" + str(kite) + "_0")])
    var_struct = cas.struct_symSX(
        [cas.entry('xd', struct=xd_struct),
         cas.entry('xl', struct=xl_struct)])

    variables = var_struct(0.)
    variables['xd', 'wx_' + str(kite) + '_ext_0'] = 0.5 * vect_op.yhat_np()
    variables['xd', 'wx_' + str(kite) + '_int_0'] = -0.5 * vect_op.yhat_np()
    variables['xd', 'wx_' + str(kite) +
              '_ext_1'] = variables['xd', 'wx_' + str(kite) +
                                    '_ext_0'] + vect_op.xhat_np()
    variables['xd', 'wx_' + str(kite) +
              '_int_1'] = variables['xd', 'wx_' + str(kite) +
                                    '_int_0'] + vect_op.xhat_np()
    variables['xl', 'wg_' + str(kite) + '_0'] = 1. / gamma_scale

    test_list = get_list(options, variables, architecture)

    filaments = test_list.shape[1]

    filament_count_test = filaments - 6
    if not (filament_count_test == 0):
        message = 'filament list does not work as expected. difference in number of filaments in test_list = ' + str(
            filament_count_test)
        awelogger.logger.error(message)
        raise Exception(message)

    LE_expected = cas.DM(np.array([0., -0.5, 0., 0., 0.5, 0., 1.]))
    PE_expected = cas.DM(np.array([0., 0.5, 0., 1., 0.5, 0., 1.]))
    TE_expected = cas.DM(np.array([1., -0.5, 0., 0., -0.5, 0., 1.]))

    expected_filaments = {
        'leading edge': LE_expected,
        'positive edge': PE_expected,
        'trailing edge': TE_expected
    }

    for type in expected_filaments.keys():
        expected_filament = expected_filaments[type]
        expected_in_list = expected_filament_in_list(test_list,
                                                     expected_filament)
        if not expected_in_list:
            message = 'filament list does not work as expected. ' + type + \
                      ' test filament not in test_list.'
            awelogger.logger.error(message)

            with np.printoptions(precision=3, suppress=True):
                print('test_list:')
                print(np.array(test_list))

            raise Exception(message)

    NE_not_expected = cas.DM(np.array([1., -0.5, 0., 1., 0.5, 0., -1.]))
    not_expected_filaments = {'negative edge': NE_not_expected}

    for type in not_expected_filaments.keys():
        not_expected_filament = not_expected_filaments[type]
        is_reasonable = not (expected_filament_in_list(test_list,
                                                       not_expected_filament))
        if not is_reasonable:
            message = 'filament list does not work as expected. ' + type + \
                      ' test filament in test_list.'
            awelogger.logger.error(message)

            with np.printoptions(precision=3, suppress=True):
                print('test_list:')
                print(np.array(test_list))

            raise Exception(message)

    return test_list
    def problem_formulation(self):
        """ MPC states for stage k"""

        self.mpc_xk = struct_symSX([
            entry('s_buffer', shape=(self.n_out, 1)),
            entry('ds_buffer_source', shape=(self.n_in,1))
        ])
        # States at next time-step. Same structure as mpc_xk. Will be assigned expressions later on.
        self.mpc_xk_next = struct_SX(self.mpc_xk)

        """ MPC control inputs for stage k"""
        self.mpc_uk = struct_symSX([
            entry('dv_in', shape=(self.n_in, 1)),
            entry('dv_out', shape=(self.n_out, 1)),
        ])

        """ MPC soft constraints"""
        self.mpc_eps = struct_symSX([
            entry('s_buffer', shape=(self.n_out, 1)),
        ])
        eps_s_buffer = self.mpc_eps['s_buffer']

        """ MPC time-varying parameters for stage k"""

        self.mpc_tvpk = struct_symSX([
            entry('u_prev', struct=self.mpc_uk),
            entry('v_out_max', shape=(self.n_out, 1)),
            entry('s_buffer_source', shape=(self.n_in, 1)),
            entry('v_out_source', shape=(self.n_in, 1)),
            entry('dv_out_source_fix', shape=(self.n_in,1)),
            entry('time_fac'),
        ])
        """ MPC parameters for stage k"""
        self.mpc_pk = struct_symSX([
            # Note: Pb is defined "transposed", as casadi will raise an error for n_out=1, since it cant handle row vectors.
            entry('Pb', shape=(np.sum(self.n_in), self.n_out)),
            entry('control_delta', shape=1),
        ])

        """ MPC parameters for stage N"""
        self.mpc_pN = struct_symSX([
            entry('s_buffer_source_N', shape=(self.n_in,1)),
        ])

        """ Memory """
        # Buffer memory
        s_buffer = self.mpc_xk['s_buffer']

        """ Incoming packet stream """
        # Allowed/accepted incoming packet stream:
        v_in = self.v_in_max_total-self.mpc_uk['dv_in']

        """ Outgoing packet stream """
        # Outgoing packet stream:
        v_out = self.v_out_max_total-self.mpc_uk['dv_out']
        # Maximum value for v_out (determined by target server):
        v_out_max = self.mpc_tvpk['v_out_max']

        """ Load information """
        # memory info incoming servers
        s_buffer_source = self.mpc_tvpk['s_buffer_source']

        """ Source Node """
        # Adjusted buffer memory of source:
        ds_buffer_source = self.mpc_xk['ds_buffer_source']
        # Predicted outgoing packet stream:
        v_out_source = self.mpc_tvpk['v_out_source']
        # v_out_source adjusted:
        dv_out_source = v_in - v_out_source
        # Corrected buffer memory of source:
        s_buffer_source_corr = s_buffer_source - ds_buffer_source
        # ds_buffer_source_next:
        self.mpc_xk_next['ds_buffer_source'] = ds_buffer_source + dv_out_source*self.dt

        """ Circuit matching """
        # Assignment Matrix: Which element of each input is assigned to which output buffer:
        # Note: Pb is defined "transposed", as casadi will raise an error for n_out=1, since it cant handle row vectors.
        Pb = self.mpc_pk['Pb'].T

        """ System dynamics"""
        # system dynamics, constraints and objective definition:
        s_tilde_next = s_buffer + self.dt*Pb@(v_in)

        s_buffer_next = s_tilde_next - self.dt*v_out

        self.mpc_xk_next['s_buffer'] = s_buffer_next

        """ Objective """
        stage_cost = 0
        # Objective function with fairness formulation:
        #s_buffer_source_split = (s_buffer_source+eps)/(sum1(s_buffer_source+eps))
        time_fac = self.mpc_tvpk['time_fac']
        stage_cost += 10*sum1(time_fac/(self.n_in)*self.mpc_uk['dv_in']**2)
        stage_cost += sum1(time_fac/(self.n_out)*self.mpc_uk['dv_out']**2)
        stage_cost += 1e5*sum1(eps_s_buffer)

        # Control delta regularization
        stage_cost += self.mpc_pk['control_delta']*sum1((self.mpc_uk-self.mpc_tvpk['u_prev'])**2)

        # Terminal cost:
        terminal_cost = 1e5*sum1(eps_s_buffer)

        """ Constraints"""
        self.mpc_xk_lb = self.mpc_xk(0)
        self.mpc_xk_lb['ds_buffer_source'] = -np.inf
        self.mpc_xk_ub = self.mpc_xk(np.inf)

        # All inputs with lower bound 0 and upper bound infinity
        self.mpc_uk_lb = self.mpc_uk(0)
        self.mpc_uk_ub = self.mpc_uk(np.inf)

        # All eps with lower bound 0 and upper bound infinity
        self.mpc_epsk_lb = self.mpc_eps(0)
        self.mpc_epsk_ub = self.mpc_eps(np.inf)

        # Further constraints on states and inputs:
        # Note lb and ub must be lists to be concatenated lateron
        dv_out_source_fix = self.mpc_tvpk['dv_out_source_fix']
        cons_list = [
            {'lb': [0]*self.n_in,        'eq': v_in,                             'ub': [np.inf]*self.n_in},                 # v_in must be greater than 0.
            {'lb': [0]*self.n_out,       'eq': v_out,                            'ub': [np.inf]*self.n_out},                # v_out cant be negative
            {'lb': [0]*self.n_out,       'eq': v_out_max-v_out,                  'ub': [np.inf]*self.n_out},                # outgoing packet stream cant be greater than what is allowed individually
            {'lb': [-np.inf],            'eq': sum1(v_in),                       'ub': [self.v_in_max_total]},              # sum of all incoming traffic can't exceed v_in_max_total
            {'lb': [-np.inf],            'eq': sum1(v_out),                      'ub': [self.v_out_max_total]},             # outgoing packet stream cant be greater than what is allowed in total.
            {'lb': [0]*self.n_out,       'eq': self.s_c_max_total+eps_s_buffer-s_buffer, 'ub': [np.inf]*self.n_out},
            {'lb': [0]*self.n_in,        'eq': s_buffer_source_corr,             'ub': [np.inf]*self.n_in},                 # Adjusted s_buffer_source must be >0
            {'lb': [0]*self.n_in,        'eq': dv_out_source_fix*dv_out_source,  'ub': [0]*self.n_in},
        ]
        assert np.all([type(cons_list_i['lb']) == list for cons_list_i in cons_list])
        assert np.all([type(cons_list_i['ub']) == list for cons_list_i in cons_list])


        cons = vertcat(*[con_i['eq'] for con_i in cons_list])
        cons_lb = np.concatenate([con_i['lb'] for con_i in cons_list])
        cons_ub = np.concatenate([con_i['ub'] for con_i in cons_list])

        # Terminal constraints:
        tcons_list = [
            {'lb': [0]*self.n_out,       'eq': self.s_c_max_total+eps_s_buffer-s_buffer, 'ub': [np.inf]*self.n_out},
            {'lb': [0]*self.n_out,       'eq': self.mpc_pN['s_buffer_source_N']-ds_buffer_source, 'ub': [np.inf]*self.n_in}
        ]
        tcons = vertcat(*[tcon_i['eq'] for tcon_i in tcons_list])
        tcons_lb = np.concatenate([tcon_i['lb'] for tcon_i in tcons_list])
        tcons_ub = np.concatenate([tcon_i['ub'] for tcon_i in tcons_list])

        """ Summarize auxiliary / intermediate variables in mpc_aux with their respective expression """
        bandwidth_load_in = sum1(v_in)/self.v_in_max_total
        bandwidth_load_out = sum1(v_out)/self.v_out_max_total

        # For debugging: Add intermediate variables to mpc_aux_expr and query them after solving the optimization problem.
        self.mpc_aux_expr = struct_SX([
            entry('v_in', expr=v_in),
            entry('v_out', expr=v_out),
            entry('bandwidth_load_in', expr=bandwidth_load_in),
            entry('bandwidth_load_out', expr=bandwidth_load_out),
            entry('s_buffer_source_corr', expr=s_buffer_source_corr)
        ])

        """ Problem dictionary """
        mpc_problem = {}
        mpc_problem['cons'] = Function('cons', [self.mpc_xk, self.mpc_uk, self.mpc_eps, self.mpc_tvpk, self.mpc_pk], [cons])
        mpc_problem['cons_lb'] = cons_lb
        mpc_problem['cons_ub'] = cons_ub
        mpc_problem['tcons'] = Function('tcons', [self.mpc_xk, self.mpc_eps, self.mpc_pN], [tcons])
        mpc_problem['tcons_lb'] = tcons_lb
        mpc_problem['tcons_ub'] = tcons_ub
        mpc_problem['stage_cost'] = Function('stage_cost', [self.mpc_xk, self.mpc_uk, self.mpc_eps, self.mpc_tvpk, self.mpc_pk], [stage_cost])
        mpc_problem['terminal_cost'] = Function('terminal_cost', [self.mpc_xk, self.mpc_eps], [terminal_cost])
        mpc_problem['model'] = Function('model', [self.mpc_xk, self.mpc_uk, self.mpc_tvpk, self.mpc_pk], [self.mpc_xk_next])
        mpc_problem['aux'] = Function('aux', [self.mpc_xk, self.mpc_uk, self.mpc_eps, self.mpc_tvpk, self.mpc_pk], [self.mpc_aux_expr])

        self.mpc_problem = mpc_problem