Ejemplo n.º 1
0
def get_gamma_residual(model_options, wind, parent, variables, parameters,
                       architecture):

    uzero_hat_var = get_uzero_hat_var(variables, parent)
    vzero_hat_var = get_vzero_hat_var(variables, parent)

    n_hat_var = general_geom.get_n_hat_var(variables, parent)
    u_comp = cas.mtimes(n_hat_var.T, uzero_hat_var)
    v_comp = cas.mtimes(n_hat_var.T, vzero_hat_var)

    gamma_var = get_gamma_var(variables, parent)
    cosgamma_var = get_cosgamma_var(variables, parent)
    singamma_var = get_singamma_var(variables, parent)

    g_vec_length_var = get_g_vec_length_var(variables, parent)

    f_cosproj = g_vec_length_var * cosgamma_var - u_comp
    f_sinproj = g_vec_length_var * singamma_var - v_comp

    f_cos = np.cos(gamma_var) - cosgamma_var
    f_sin = np.sin(gamma_var) - singamma_var

    resi = cas.vertcat(f_cos, f_sin, f_cosproj, f_sinproj)

    return resi
Ejemplo n.º 2
0
def draw_kite_fuselage(ax, q, r, length, kite_color, side, num_per_meter, naca="0006"):

    r_dcm = np.array(cas.reshape(r, (3, 3)))

    total_width = np.float(naca[2:]) / 100. * length

    num_spanwise = np.ceil(total_width * num_per_meter / 2.)

    ypos = np.arange(-1. * num_spanwise, num_spanwise + 1.) / num_spanwise / 2.

    for y in ypos:

        yloc = cas.mtimes(r_dcm, vect_op.yhat_np()) * y * total_width

        basic_shell = get_naca_shell(length, naca) * (1 - (2. * y)**2.)

        horizontal_shell = []
        for idx in range(basic_shell[:, 0].shape[0]):

            new_point = q + yloc + np.array(cas.mtimes(r_dcm, basic_shell[idx, :].T))

            horizontal_shell = cas.vertcat(horizontal_shell, new_point.T)
        horizontal_shell = np.array(horizontal_shell)

        make_side_plot(ax, horizontal_shell, side, kite_color)
Ejemplo n.º 3
0
def rotation_matrix(theta, phi, psi):
    # rotation angles are defined positive, for clockwise rotation when
    # looking from origin along positive axis

    ori_pre_rot = np.eye(3)

    rot_x = cas.MX.zeros(3, 3)
    rot_x[0, 0] = 1.0
    rot_x[1, 1] = np.cos(phi)
    rot_x[1, 2] = np.sin(phi)
    rot_x[2, 1] = -1.0 * np.sin(phi)
    rot_x[2, 2] = np.cos(phi)

    rot_y = cas.MX.zeros(3, 3)
    rot_y[0, 0] = np.cos(theta)
    rot_y[0, 2] = -1.0 * np.sin(theta)
    rot_y[1, 1] = 1.0
    rot_y[2, 0] = np.sin(theta)
    rot_y[2, 2] = np.cos(theta)

    rot_z = cas.MX.zeros(3, 3)
    rot_z[0, 0] = np.cos(psi)
    rot_z[0, 1] = np.sin(psi)
    rot_z[1, 0] = -1.0 * np.sin(psi)
    rot_z[1, 1] = np.cos(psi)
    rot_z[2, 2] = 1.0

    ori_post_rot = cas.mtimes(cas.mtimes(rot_x, rot_y),
                              cas.mtimes(rot_z, ori_pre_rot))

    return ori_post_rot
Ejemplo n.º 4
0
def find_nominal_landing_cost(V, P, variables, nlp_options):
    pos_weight = nlp_options['landing']['cost']['position_weight']
    vel_weight = nlp_options['landing']['cost']['velocity_weight']

    q_end = {}
    dq_end = {}
    for name in struct_op.subkeys(variables, 'xd'):
        if name[0] == 'q':
            q_end[name] = V['xd', -1, name]
        elif name[:2] == 'dq':
            dq_end[name] = V['xd', -1, name]

    velocity_end = 0.0
    position_end = 0.0
    for position in list(q_end.keys()):
        position_end += cas.mtimes(q_end[position].T, q_end[position])
    position_end *= 1. / len(list(q_end.keys()))

    for velocity in list(dq_end.keys()):
        velocity_end += cas.mtimes(dq_end[velocity].T, dq_end[velocity])
    velocity_end *= 1. / len(list(dq_end.keys()))

    nominal_landing_cost = P['cost', 'nominal_landing'] * (
        vel_weight * velocity_end + pos_weight * position_end)

    return nominal_landing_cost
Ejemplo n.º 5
0
def get_radius_of_curvature(variables, kite, parent):

    dq = variables['xd']['dq' + str(kite) + str(parent)]
    ddq = variables['xddot']['ddq' + str(kite) + str(parent)]

    gamma_dot = dq
    gamma_ddot = ddq

    # from frenet vectors + curvature definition
    # r = || gamma' || / (e1' cdot e2)
    # e1 = gamma' / || gamma' ||
    # e1' = ( gamma" || gamma' ||^2  - gamma' (gamma' cdot gamma") ) / || gamma' ||^3
    # e2 = ebar2 / || ebar2 ||
    # ebar2 = gamma" - (gamma' cdot gamma") gamma' / || gamma' ||^2
    # ....
    # r = || gamma' ||^4 // || gamma" || gamma' ||^2 - gamma' (gamma' cdot gamma") ||

    num = cas.mtimes(gamma_dot.T, gamma_dot)**2. + 1.0e-8

    den_vec = gamma_ddot * cas.mtimes(gamma_dot.T,
                                      gamma_dot) - gamma_dot * cas.mtimes(
                                          gamma_dot.T, gamma_ddot)
    den = vect_op.smooth_norm(den_vec)

    radius = num / den
    return radius
Ejemplo n.º 6
0
def get_radius_inequality(model_options, variables, kite, parent, parameters):
    # no projection included...

    b_ref = parameters['theta0', 'geometry', 'b_ref']
    half_span = b_ref / 2.
    num_ref = model_options['model_bounds']['anticollision_radius']['num_ref']

    # half_span - radius < 0
    # half_span * den - num < 0

    dq = variables['xd']['dq' + str(kite) + str(parent)]
    ddq = variables['xddot']['ddq' + str(kite) + str(parent)]

    gamma_dot = cas.vertcat(0., dq[1], dq[2])
    gamma_ddot = cas.vertcat(0., ddq[1], ddq[2])

    num = cas.mtimes(gamma_dot.T, gamma_dot)**2.

    den_vec = gamma_ddot * cas.mtimes(gamma_dot.T,
                                      gamma_dot) - gamma_dot * cas.mtimes(
                                          gamma_dot.T, gamma_ddot)
    den = vect_op.norm(den_vec)

    inequality = (half_span * den - num) / num_ref

    return inequality
Ejemplo n.º 7
0
def collect_power_balance_outputs(options, architecture, variables,
                                  base_aerodynamic_quantities, outputs):

    kite = base_aerodynamic_quantities['kite']

    if 'power_balance' not in list(outputs.keys()):
        # initialize
        outputs['power_balance'] = {}

    # kite velocity
    parent = architecture.parent_map[kite]
    dq = variables['xd']['dq' + str(kite) + str(parent)]

    f_lift_earth = outputs['aerodynamics']['f_lift_earth' + str(kite)]
    f_drag_earth = outputs['aerodynamics']['f_drag_earth' + str(kite)]
    f_side_earth = outputs['aerodynamics']['f_side_earth' + str(kite)]

    # get lift, drag and aero-moment power
    outputs['power_balance']['P_lift' + str(kite)] = cas.mtimes(
        f_lift_earth.T, dq)
    outputs['power_balance']['P_drag' + str(kite)] = cas.mtimes(
        f_drag_earth.T, dq)
    outputs['power_balance']['P_side' + str(kite)] = cas.mtimes(
        f_side_earth.T, dq)

    if int(options['kite_dof']) == 6:
        omega = variables['xd']['omega' + str(kite) + str(parent)]
        m_aero_body = outputs['aerodynamics']['m_aero_body' + str(kite)]
        outputs['power_balance']['P_moment' + str(kite)] = cas.mtimes(
            m_aero_body.T, omega)

    return outputs
Ejemplo n.º 8
0
def find_ddq_regularisation(nlp_numerics_options, V, P, xdot, outputs):
    nk = nlp_numerics_options['n_k']
    direct_collocation, multiple_shooting, d, scheme, int_weights = extract_discretization_info(
        nlp_numerics_options)

    ddq_regularisation = 0.

    for kdx in range(nk):

        if multiple_shooting:

            for name in set(struct_op.subkeys(outputs, 'xddot_from_var')):
                ddq_regularisation += cas.mtimes(xdot['xd', kdx, name[1:]].T,
                                                 xdot['xd', kdx, name[1:]])

        elif direct_collocation:

            for jdx in range(d):
                for name in set(struct_op.subkeys(outputs, 'xddot_from_var')):
                    if 'ddq' in name:
                        ddq_regularisation += int_weights[jdx] * cas.mtimes(
                            xdot['coll_xd', kdx, jdx, name[1:]].T,
                            xdot['coll_xd', kdx, jdx, name[1:]])

    return ddq_regularisation
Ejemplo n.º 9
0
        def coll_interpolator(time_grid, name, dim, var_type):
            """Interpolating function

            @param time_grid list with time points
            @param name xd variable name
            @param dim xd variable dimension index
            """

            vals = []
            for t in time_grid:
                kdx, tau = struct_op.calculate_kdx(nlp_params, V, t)
                if var_type == 'xd':
                    poly_vars = cas.vertcat(
                        V['xd', kdx, name, dim], *V['coll_var', kdx, :, 'xd',
                                                    name, dim])
                    vals = cas.vertcat(
                        vals, cas.mtimes(poly_vars.T, self.__coeff_fun(tau)))
                elif var_type in ['u', 'xa', 'xl']:
                    poly_vars = cas.vertcat(*V['coll_var', kdx, :, var_type,
                                               name, dim])
                    vals = cas.vertcat(
                        vals, cas.mtimes(poly_vars.T, self.__coeff_fun_u(tau)))
                elif var_type in ['int_out']:
                    poly_vars = cas.vertcat(
                        integral_outputs['int_out', kdx, name, dim],
                        *integral_outputs['coll_int_out', kdx, :, name, dim])
                    vals = cas.vertcat(
                        vals, cas.mtimes(poly_vars.T, self.__coeff_fun(tau)))

            return vals
Ejemplo n.º 10
0
def add_node_kinetic(node, options, node_masses_si, variables_si, parameters, outputs, architecture):

    parent = architecture.parent_map[node]
    label = str(node) + str(parent)

    node_has_a_kite = node in architecture.kite_nodes
    kites_have_6dof = int(options['kite_dof']) == 6
    node_has_rotational_energy = node_has_a_kite and kites_have_6dof

    mass = node_masses_si['m' + label]
    dq = variables_si['xd']['dq' + label]
    e_kin_trans = 0.5 * mass * cas.mtimes(dq.T, dq)

    if node_has_rotational_energy:
        omega = variables_si['xd']['omega' + label]
        j_kite = parameters['theta0', 'geometry', 'j']
        e_kin_rot = 0.5 * cas.mtimes(cas.mtimes(omega.T, j_kite), omega)

    else:
        e_kin_rot = cas.DM.zeros((1, 1))

    e_kinetic = e_kin_trans + e_kin_rot

    outputs['e_kinetic']['q' + label] = e_kinetic

    return outputs
Ejemplo n.º 11
0
def draw_lifting_surface(ax,
                         q,
                         r,
                         b_ref,
                         c_tipn,
                         c_root,
                         c_tipp,
                         kite_color,
                         side,
                         body_cross_sections_per_meter,
                         naca="0012"):

    r_dcm = np.array(cas.reshape(r, (3, 3)))

    num_spanwise = np.ceil(b_ref * body_cross_sections_per_meter / 2.)

    ypos = np.arange(-1. * num_spanwise, num_spanwise + 1.) / num_spanwise / 2.

    leading_edges = []
    trailing_edges = []

    for y in ypos:

        yloc = cas.mtimes(r_dcm, vect_op.yhat_np()) * y * b_ref

        s = np.abs(y) / 0.5  # 1 at tips and 0 at root
        if y < 0:
            c_local = c_root * (1. - s) + c_tipn * s
        else:
            c_local = c_root * (1. - s) + c_tipp * s

        basic_shell = get_naca_shell(c_local, naca)

        basic_leading_ege = basic_shell[np.argmin(basic_shell[:, 0]), :]
        basic_trailing_ege = basic_shell[np.argmax(basic_shell[:, 0]), :]

        new_leading_edge = q + yloc + np.array(
            cas.mtimes(r_dcm, basic_leading_ege.T))
        new_trailing_edge = q + yloc + np.array(
            cas.mtimes(r_dcm, basic_trailing_ege.T))

        leading_edges = cas.vertcat(leading_edges, new_leading_edge.T)
        trailing_edges = cas.vertcat(trailing_edges, new_trailing_edge.T)

        horizontal_shell = []
        for idx in range(basic_shell[:, 0].shape[0]):

            new_point = q + yloc + np.array(
                cas.mtimes(r_dcm, basic_shell[idx, :].T))

            horizontal_shell = cas.vertcat(horizontal_shell, new_point.T)
        horizontal_shell = np.array(horizontal_shell)

        make_side_plot(ax, horizontal_shell, side, kite_color)

    make_side_plot(ax, leading_edges, side, kite_color)
    make_side_plot(ax, trailing_edges, side, kite_color)

    return None
Ejemplo n.º 12
0
def get_tether_length_constraint(options, vars_si, parameters, architecture):

    xd_si = vars_si['xd']
    theta_si = vars_si['theta']

    g_dict = {}

    number_of_nodes = architecture.number_of_nodes
    parent_map = architecture.parent_map
    kite_nodes = architecture.kite_nodes

    com_attachment = (options['tether']['attachment'] == 'com')
    stick_attachment = (options['tether']['attachment'] == 'stick')
    kite_has_6dof = (int(options['kite_dof']) == 6)

    if not (com_attachment or stick_attachment):
        message = 'Unknown tether attachment option: {}'.format(options['tether']['attachment'])
        awelogger.logger.error(message)
        raise Exception(message)

    for node in range(1, number_of_nodes):

        parent = parent_map[node]
        q_si = xd_si['q' + str(node) + str(parent)]

        node_is_a_kite = (node in kite_nodes)
        has_extended_arm = node_is_a_kite and stick_attachment

        if has_extended_arm and not kite_has_6dof:
            message = 'Stick tether attachment option not implemented for 3DOF kites'
            awelogger.logger.error(message)
            raise Exception(message)

        if has_extended_arm:
            dcm = cas.reshape(xd_si['r{}{}'.format(node, parent)], (3, 3))
            current_node = q_si + cas.mtimes(dcm, parameters['theta0', 'geometry', 'r_tether'])
        else:
            current_node = q_si

        if node == 1:
            previous_node = cas.DM.zeros((3, 1))
            segment_length = xd_si['l_t']
        elif node in kite_nodes:
            grandparent = parent_map[parent]
            previous_node = xd_si['q' + str(parent) + str(grandparent)]
            segment_length = theta_si['l_s']
        else:
            grandparent = parent_map[parent]
            previous_node = xd_si['q' + str(parent) + str(grandparent)]
            segment_length = theta_si['l_i']

        # holonomic constraint
        seg_vector = (current_node - previous_node)
        length_constraint = 0.5 * (cas.mtimes(seg_vector.T, seg_vector) - segment_length ** 2.0)

        g_dict['c' + str(node) + str(parent)] = length_constraint

    return g_dict
Ejemplo n.º 13
0
def get_reduced_hessian(health_solver_options, cstr_jacobian_eval,
                        lagr_hessian_eval):
    awelogger.logger.info('compute reduced hessian...')

    null_tolerance = health_solver_options['tol']['reduced_hessian_null']
    null = scila.null_space(cstr_jacobian_eval, null_tolerance)

    reduced_hessian = cas.mtimes(cas.mtimes(null.T, lagr_hessian_eval), null)

    return reduced_hessian
Ejemplo n.º 14
0
def from_earthfixed_to_body(earthfixed_vector, q_upper, q_lower):

    [ehat_x, ehat_y, ehat_z] = get_body_axes(q_upper, q_lower)

    body_x = cas.mtimes(earthfixed_vector.T, ehat_x)
    body_y = cas.mtimes(earthfixed_vector.T, ehat_y)
    body_z = cas.mtimes(earthfixed_vector.T, ehat_z)

    body_vector = cas.vertcat(body_x, body_y, body_z)

    return body_vector
Ejemplo n.º 15
0
def generate_rotational_dynamics(variables, f_nodes, parameters, outputs,
                                 architecture):
    kite_nodes = architecture.kite_nodes
    parent_map = architecture.parent_map

    j_inertia = parameters['theta0', 'geometry', 'j']

    xd = variables['SI']['xd']
    xddot = variables['SI']['xddot']

    cstr_list = mdl_constraint.MdlConstraintList()

    for kite in kite_nodes:
        parent = parent_map[kite]
        moment = f_nodes['m' + str(kite) + str(parent)]

        rlocal = cas.reshape(xd['r' + str(kite) + str(parent)], (3, 3))
        drlocal = cas.reshape(xddot['dr' + str(kite) + str(parent)], (3, 3))

        omega = xd['omega' + str(kite) + str(parent)]
        omega_skew = vect_op.skew(omega)
        domega = xddot['domega' + str(kite) + str(parent)]

        tether_moment = outputs['tether_moments']['n{}{}'.format(kite, parent)]

        # moment = J dot(omega) + omega x (J omega) + [tether moment which is zero if holonomic constraints do not depend on omega]
        J_dot_omega = cas.mtimes(j_inertia, domega)
        omega_cross_J_omega = vect_op.cross(omega,
                                            cas.mtimes(j_inertia, omega))
        omega_derivative = moment - (J_dot_omega + omega_cross_J_omega +
                                     tether_moment)
        rotational_2nd_law = omega_derivative / vect_op.norm(
            cas.diag(j_inertia))

        rotation_dynamics_cstr = cstr_op.Constraint(expr=rotational_2nd_law,
                                                    name='rotation_dynamics' +
                                                    str(kite),
                                                    cstr_type='eq')
        cstr_list.append(rotation_dynamics_cstr)

        # Rdot = R omega_skew -> R ( kappa/2 (I - R.T R) + omega_skew )
        baumgarte = parameters['theta0', 'kappa_r']
        orthonormality = baumgarte / 2. * (cas.DM_eye(3) -
                                           cas.mtimes(rlocal.T, rlocal))
        ref_frame_deriv_matrix = drlocal - (cas.mtimes(
            rlocal, orthonormality + omega_skew))
        ref_frame_derivative = cas.reshape(ref_frame_deriv_matrix, (9, 1))

        ortho_cstr = cstr_op.Constraint(expr=ref_frame_derivative,
                                        name='ref_frame_deriv' + str(kite),
                                        cstr_type='eq')
        cstr_list.append(ortho_cstr)

    return cstr_list, outputs
Ejemplo n.º 16
0
def get_kite_radius_proj_squared(model_options, kite, variables, architecture):
    radius_vec = get_kite_radius_vector(model_options, kite, variables, architecture)

    parent = architecture.parent_map[kite]
    nhat_vec = get_nhat_var(variables, parent)

    hypotenuse_squared = cas.mtimes(radius_vec.T, radius_vec)
    normal_squared = cas.mtimes(radius_vec.T, nhat_vec)**2.

    radius_proj_squared = hypotenuse_squared - normal_squared

    return radius_proj_squared
Ejemplo n.º 17
0
def get_beta(ua, r):
    ehat1 = r[:, 0]  # chordwise, from le to te
    ehat2 = r[:, 1]  # spanwise, from pe to ne
    ehat3 = r[:, 2]  # up

    y_component = cas.mtimes(ua.T, ehat2)
    x_component = vect_op.smooth_abs(cas.mtimes(ua.T, ehat1))
    # x component had better be positive

    beta = y_component / x_component

    return beta
Ejemplo n.º 18
0
def get_beta(ua, r):
    ehat1 = r[:, 0]  # chordwise, from le to te
    ehat2 = r[:, 1]  # spanwise, from pe to ne
    ehat3 = r[:, 2]  # up

    y_component = cas.mtimes(ua.T, ehat2)
    x_component = vect_op.smooth_abs(cas.mtimes(ua.T, ehat1))
    # x component had better be positive

    # the small angle approximation of:
    # beta = cas.arctan(y_component / x_component)
    beta = y_component / x_component

    return beta
Ejemplo n.º 19
0
def sosc_check(health_solver_options, nlp, solution, arg):

    logging.debug('sosc check...')

    V = nlp.V
    P = nlp.P

    V_vals = V(solution['x'])
    lambda_g_vals = solution['lam_g']
    lambda_x_vals = solution['lam_x']
    p_fix_num = nlp.P(arg['p'])

    logging.debug('get constraints...')

    [stacked_cstr_fun, stacked_lam_fun,
     stacked_labels] = collect_equality_and_active_inequality_constraints(
         health_solver_options, nlp, solution, arg)
    relevant_constraints = stacked_cstr_fun(V, P, arg['lbx'], arg['ubx'])

    logging.debug('get jacobian...')

    linearization = cas.jacobian(relevant_constraints, V)
    linearization_fun = cas.Function('linearization_fun', [V, P],
                                     [linearization])
    linearization_eval = np.array(linearization_fun(V_vals, p_fix_num))

    logging.debug('find the null space...')

    pdb.set_trace()

    null = vect_op.null(
        linearization_eval,
        health_solver_options['sosc']['reduced_hessian_null_tol'])

    logging.debug('make lagrangian')

    [lagr_fun, lagr_jacobian_fun,
     lagr_hessian_fun] = generate_lagrangian(health_solver_options, nlp, arg,
                                             solution)
    lagr_hessian = lagr_hessian_fun(V_vals, p_fix_num, lambda_g_vals,
                                    lambda_x_vals)

    logging.debug('get reduced hessian')

    reduced_hessian = cas.mtimes(cas.mtimes(null.T, lagr_hessian), null)

    logging.debug('rank check on reduced hessian')

    full_rank_check(health_solver_options, reduced_hessian, 'reduced hessian',
                    'SOSC')
Ejemplo n.º 20
0
def test_horizontal():

    name = 'horizontal'

    xhat = vect_op.xhat_np()
    yhat = vect_op.yhat_np()
    zhat = vect_op.zhat_np()

    ehat_x = vect_op.xhat_np()
    ehat_y = vect_op.yhat_np()
    ehat_z = vect_op.zhat_np()

    q_upper = 5. * xhat
    q_lower = 2. * xhat

    dir = 'x'
    transformed = from_earth_to_body(xhat, q_upper, q_lower)
    reference = ehat_z
    diff = transformed - reference
    resi = cas.mtimes(diff.T, diff)
    epsilon = 1.e-12
    if resi > epsilon:
        awelogger.logger.error('tether frame transformation test (' + name +
                               ' ' + dir + ') gives error of size: ' +
                               str(resi))

    dir = 'y'
    transformed = from_earth_to_body(yhat, q_upper, q_lower)
    reference = ehat_y
    diff = transformed - reference
    resi = cas.mtimes(diff.T, diff)
    epsilon = 1.e-12
    if resi > epsilon:
        awelogger.logger.error('tether frame transformation test (' + name +
                               ' ' + dir + ') gives error of size: ' +
                               str(resi))

    dir = 'z'
    transformed = from_earth_to_body(zhat, q_upper, q_lower)
    reference = -1. * ehat_x
    diff = transformed - reference
    resi = cas.mtimes(diff.T, diff)
    epsilon = 1.e-12
    if resi > epsilon:
        awelogger.logger.error('tether frame transformation test (' + name +
                               ' ' + dir + ') gives error of size: ' +
                               str(resi))

    return None
Ejemplo n.º 21
0
    def __set_acados_reference(self):

        for i in range(self.__N):

            # periodic index
            idx = (self.__index_acados + i) % self.__Nref

            # reference
            xref = np.squeeze(self.__ref[idx][:self.__nx], axis=1)
            uref = np.squeeze(self.__ref[idx][self.__nx:self.__nx + self.__nu +
                                              self.__ns],
                              axis=1)

            if self.__type == 'tracking':

                # construct output reference with gradient term
                yref = np.squeeze(
                    ca.vertcat(xref,uref).full() - \
                    ct.mtimes(
                        np.linalg.inv(self.__Href[idx][0]), # inverse of weighting matrix
                        self.__qref[idx][0].T).full(), # gradient term
                    axis = 1
                    )
                self.__acados_ocp_solver.set(i, 'yref', yref)

                # update tuning matrix
                self.__acados_ocp_solver.cost_set(i, 'W', self.__Href[idx][0])

            # update constraint bounds
            if self.__h is not None:
                C = self.__S['C'][idx][:, :self.__nx]
                D = self.__S['C'][idx][:, self.__nx:]
                lg = -self.__S['e'][idx] + ct.mtimes(
                    C, xref).full() + ct.mtimes(D, uref).full()
                ug = 1e8 - self.__S['e'][idx] + ct.mtimes(
                    C, xref).full() + ct.mtimes(D, uref).full()
                self.__acados_ocp_solver.constraints_set(
                    i, 'lg', np.squeeze(lg, axis=1))
                self.__acados_ocp_solver.constraints_set(
                    i, 'ug', np.squeeze(ug, axis=1))

        # update terminal constraint
        idx = (self.__index_acados + self.__N) % self.__Nref
        x_term = np.squeeze(self.__p_operator(self.__ref[idx][:self.__nx]),
                            axis=1)
        self.__acados_ocp_solver.set(self.__N, 'lbx', x_term)
        self.__acados_ocp_solver.set(self.__N, 'ubx', x_term)

        return None
Ejemplo n.º 22
0
def tracking_cost(nw):
    """ Create tracking cost function for variables nw
    """

    # reference parameters
    w =  ca.MX.sym('w', (nw, 1))
    wref = ca.MX.sym('wref', (nw, 1))
    H = ca.MX.sym('H', (nw, nw))
    q = ca.MX.sym('H', (nw, 1))

    # cost definition
    dw   = w - wref
    obj = 0.5*ct.mtimes(dw.T, ct.mtimes(H, dw)) + ct.mtimes(q.T,dw)

    return ca.Function('tracking_cost',[w, wref, H, q],[obj])
Ejemplo n.º 23
0
def momentum_correction(options, generalized_coordinates, system_variables,
                        node_masses, outputs, architecture):
    """Compute momentum correction for translational lagrangian dynamics of an open system.
    Here the system is "open" because the main tether mass is changing in time. During reel-out,
    momentum is injected in the system, and during reel-in, momentum is extracted.
    It is assumed that the tether mass is concentrated at the main tether node.

    See "Lagrangian Dynamics for Open Systems", R. L. Greene and J. J. Matese 1981, Eur. J. Phys. 2, 103.

    @return: lagrangian_momentum_correction - correction term that can directly be added to rhs of transl_dyn
    """

    # initialize
    xgcdot = generalized_coordinates['scaled']['xgcdot'].cat
    lagrangian_momentum_correction = cas.DM.zeros(xgcdot.shape)

    use_wound_tether = options['tether']['use_wound_tether']
    if not use_wound_tether:

        for node in range(1, architecture.number_of_nodes):
            label = str(node) + str(architecture.parent_map[node])
            mass = node_masses['m' + label]
            mass_flow = tools.time_derivative(mass, system_variables,
                                              architecture)

            # velocity of the mass particles leaving the system
            velocity = system_variables['SI']['xd']['dq' + label]
            # see formula in reference
            lagrangian_momentum_correction += mass_flow * cas.mtimes(
                velocity.T, cas.jacobian(velocity, xgcdot)).T

    return lagrangian_momentum_correction
Ejemplo n.º 24
0
    def __construct_sensitivities(self):
        """ Construct NLP sensitivities
        """

        # convenience
        w = self.__w
        p = self.__p

        # cost function
        self.__f_fun = ca.Function('f_fun', [w, p], [self.__f])
        self.__jacf_fun = ca.Function('jacf_fun', [w, p],
                                      [ca.jacobian(self.__f, self.__w)])

        # constraints
        self.__g_fun = ca.Function('g_fun', [w, p], [self.__g])
        self.__jacg_fun = ca.Function('jacg_fun', [w, p],
                                      [ca.jacobian(self.__g, self.__w)])
        self.__gzeros = np.zeros((self.__g.shape[0], 1))

        # exact hessian
        lam_g = ca.MX.sym('lam_g', self.__g.shape)
        lag = self.__f + ct.mtimes(lam_g.T, self.__g)
        self.__jlag_fun = ca.Function('jLag', [w, p, lam_g],
                                      [ca.jacobian(lag, w)])

        if self.__options['hessian_approximation'] == 'exact':
            self.__H_fun = ca.Function('H_fun', [w, p, lam_g],
                                       [ca.hessian(lag, w)[0]])
        else:
            self.__H_fun = self.__options['hessian_approximation']
Ejemplo n.º 25
0
def find_compromised_battery_cost(nlp_numerics_options, V, P,
                                  emergency_scenario, model):
    n_k = nlp_numerics_options['n_k']
    if (len(model.architecture.kite_nodes) == 1
            or nlp_numerics_options['system_model']['kite_dof'] == 6
            or emergency_scenario[0] != 'broken_battery'):
        compromised_battery_cost = cas.DM(0.0)
    elif emergency_scenario[0] == 'broken_battery':
        actuator_len = V['u', 0, 'dcoeff21'].shape[0]
        broken_actuator = slice(0, actuator_len)
        broken_kite = emergency_scenario[1]
        broken_kite_parent = model.architecture.parent_map[broken_kite]

        compromised_battery_cost = 0.0
        for j in range(n_k):
            broken_str = 'dcoeff' + str(broken_kite) + str(broken_kite_parent)
            compromised_battery_cost += cas.mtimes(
                V['u', j, broken_str, broken_actuator].T, V['u', j, broken_str,
                                                            broken_actuator])

        compromised_battery_cost *= 1. / n_k
        compromised_battery_cost = P[
            'cost', 'compromised_battery'] * compromised_battery_cost

    return compromised_battery_cost
Ejemplo n.º 26
0
def find_theta_regularisation_cost(V, P):

    difference = V['theta'] - P['p', 'ref', 'theta']
    theta_regularisation_cost = P['cost', 'theta'] * cas.mtimes(
        difference.T, difference)

    return theta_regularisation_cost
Ejemplo n.º 27
0
def get_reynolds(options, atmos, ua, q, parameters):
    norm_ua = cas.mtimes(ua.T, ua) ** 0.5
    rho_infty = atmos.get_density( q[2])
    mu_infty = atmos.get_viscosity( q[2])
    c_ref = parameters['theta0','geometry','c_ref']
    reynolds = rho_infty * norm_ua * c_ref / mu_infty
    return reynolds
Ejemplo n.º 28
0
def collect_local_performance_outputs(options, atmos, wind, variables, CL, CD, elevation_angle, ua, n, parent, outputs,parameters):

    xd = variables['xd']
    q = xd['q' + str(n) + str(parent)]

    if 'local_performance' not in list(outputs.keys()):
        outputs['local_performance'] = {}

    [CR, f_crosswind, p_loyd, loyd_speed, loyd_phf] = get_loyd_comparison(options, atmos, wind, xd, n, parent, CL, CD, parameters, elevation_angle)

    norm_ua = cas.mtimes(ua.T, ua)**0.5

    outputs['local_performance']['CR' + str(n)] = CR
    outputs['local_performance']['f_crosswind' + str(n)] = f_crosswind
    outputs['local_performance']['p_loyd' + str(n)] = p_loyd
    outputs['local_performance']['loyd_speed' + str(n)] = loyd_speed
    outputs['local_performance']['loyd_phf' + str(n)] = loyd_phf
    outputs['local_performance']['radius' + str(n)] = get_radius_of_curvature(variables, n, parent)

    outputs['local_performance']['speed_ratio' + str(n)] = norm_ua / vect_op.norm(wind.get_velocity(q[2]))
    outputs['local_performance']['speed_ratio_loyd' + str(n)] = loyd_speed / vect_op.norm(wind.get_velocity(q[2]))

    outputs['local_performance']['radius_of_curvature' + str(n)] = get_radius_of_curvature(variables, n, parent)


    return outputs
Ejemplo n.º 29
0
def approximate_tip_radius(model_options, variables, kite, architecture, tip,
                           parameters):

    b_ref = parameters['theta0', 'geometry', 'b_ref']
    half_span_proj = b_ref / 2.
    parent = architecture.parent_map[kite]

    radial_vector = get_kite_radial_vector(model_options, kite, variables,
                                           architecture, parameters)

    if int(model_options['kite_dof']) == 6:

        r_column = variables['xd']['r' + str(kite) + str(parent)]
        r = cas.reshape(r_column, (3, 3))
        ehat2 = r[:, 1]  # spanwise, from pe to ne

        ehat2_proj_radial = vect_op.smooth_abs(
            cas.mtimes(radial_vector.T, ehat2))

        half_span_proj = b_ref * ehat2_proj_radial / 2.

    radius = get_kite_radius(model_options, kite, variables, architecture,
                             parameters)

    tip_radius = radius
    if ('int' in tip) or (tip == 0):
        tip_radius = tip_radius - half_span_proj
    elif ('ext' in tip) or (tip == 1):
        tip_radius = tip_radius + half_span_proj
    else:
        raise Exception('invalid tip designated')

    return tip_radius
Ejemplo n.º 30
0
def collect_contributions(parameters, inputs):

    stab_derivs = extract_derivs_from_parameters(parameters)

    coeffs = {}
    for deriv_name in stab_derivs.keys():

        if not deriv_name == 'frame':
            coeffs[deriv_name] = 0.

            for input_name in stab_derivs[deriv_name].keys():

                deriv_stack = stab_derivs[deriv_name][input_name]
                deriv_length = deriv_stack.shape[0]

                if not input_name in inputs.keys():
                    message = 'desired stability derivative input ' + input_name + ' is not recognized. ' \
                        + 'The following inputs are defined: ' + repr(inputs.keys())
                    awelogger.logger.error(message)

                input_val = inputs[input_name]
                input_stack = []
                for ldx in range(deriv_length):
                    input_stack = cas.vertcat(input_stack,
                                              input_val**(ldx + 1))

                contrib_from_input = cas.mtimes(deriv_stack.T, input_stack)
                coeffs[deriv_name] += contrib_from_input

    return coeffs
Ejemplo n.º 31
0
def mtimes(*args, **kwargs):
    """
    More flexible version casadi.tools.mtimes.

    Matrix multiplies all of the given arguments and returns the result. If any
    inputs are Casadi's SX or MX data types, uses Casadi's mtimes. Otherwise,
    uses a sequence of np.dot operations.

    Keyword arguments forcedot or forcemtimes can be set to True to pick one
    behavior or another.
    """
    # Get keyword arguments.
    forcemtimes = kwargs.pop("forcemtimes", None)
    forcedot = kwargs.pop("forcedot", False)
    if len(kwargs) > 0:
        raise TypeError("Invalid keywords: %s" % kwargs.keys())

    # Pick whether to use mul or dot.
    if forcemtimes:
        if forcedot:
            raise ValueError("forcemtimes and forcedot can't both be True!")
        useMul = True
    elif forcedot:
        useMul = False
    else:
        useMul = False
        symtypes = set(["SX", "MX"])
        for a in args:
            atype = getattr(a, "type_name", lambda : None)()
            if atype in symtypes:
                useMul = True
                break

    # Now actually do multiplication.
    ans = ctools.mtimes(args) if useMul else reduce(np.dot, args)
    return ans