Esempio n. 1
0
def get_MM_matrix():
    MM11 = 1.69765
    MM22 = 0.113177
    MM33 = 0.113177

    MM_col1 = MM11 * vect_op.xhat()
    MM_col2 = MM22 * vect_op.yhat()
    MM_col3 = MM33 * vect_op.zhat()

    MM = cas.horzcat(MM_col1, MM_col2, MM_col3)

    return MM
Esempio n. 2
0
def test(test_list):

    options = {}
    options['induction'] = {}
    options['induction']['vortex_epsilon'] = 0.

    x_obs = 0.5 * vect_op.xhat_np()

    u_ind = get_induced_velocity_at_observer(options, test_list, x_obs)

    xhat_component = cas.mtimes(u_ind.T, vect_op.xhat())
    if not (xhat_component == 0):
        message = 'induced velocity at observer does not work as expected. ' \
                  'test u_ind component in plane of QSVR (along xhat) is ' + str(xhat_component)
        awelogger.logger.error(message)
        raise Exception(message)

    yhat_component = cas.mtimes(u_ind.T, vect_op.yhat())
    if not (yhat_component == 0):
        message = 'induced velocity at observer does not work as expected. ' \
                  'test u_ind component in plane of QSVR (along yhat) is ' + str(yhat_component)
        awelogger.logger.error(message)
        raise Exception(message)

    zhat_component = cas.mtimes(u_ind.T, vect_op.zhat())
    sign_along_zhat = vect_op.sign(zhat_component)
    sign_comparison = (sign_along_zhat - (-1))**2.
    if not (sign_comparison < 1.e-8):
        message = 'induced velocity at observer does not work as expected. ' \
                  'sign of test u_ind component out-of-plane of QSVR (projected on zhat) is ' + str(sign_along_zhat)
        awelogger.logger.error(message)
        raise Exception(message)

    calculated_norm = vect_op.norm(u_ind)
    expected_norm = 0.752133
    norm_comparison = (calculated_norm - expected_norm)**2.
    if not (norm_comparison < 1.e-8):
        message = 'induced velocity at observer does not work as expected. ' \
                  'squared difference of norm of test u_ind vector is ' + str(norm_comparison)
        awelogger.logger.error(message)
        raise Exception(message)

    return None
Esempio n. 3
0
def get_convection_residual(options, wind, variables, architecture):

    kite_nodes = architecture.kite_nodes
    wingtips = ['ext', 'int']
    wake_nodes = options['aero']['vortex']['wake_nodes']

    resi = []
    for kite in kite_nodes:
        for tip in wingtips:
            for wake_node in range(wake_nodes):

                wx_local = tools.get_wake_node_position_si(
                    options, variables, kite, tip, wake_node)
                dwx_local = tools.get_wake_node_velocity_si(
                    options, variables, kite, tip, wake_node)

                altitude = cas.mtimes(wx_local.T, vect_op.zhat())
                u_infty = wind.get_velocity(altitude)

                resi_local = dwx_local - u_infty
                resi = cas.vertcat(resi, resi_local)

    return resi
Esempio n. 4
0
def test():

    point_obs = vect_op.yhat()
    point_1 = 1000. * vect_op.zhat()
    point_2 = -1. * point_1
    Gamma = 1.
    epsilon = 1.e-2
    seg_data = cas.vertcat(point_obs, point_1, point_2, Gamma, epsilon)

    vec_found = filament(seg_data)
    val_normalize = 1. / (2. * np.pi)
    vec_norm = vec_found / val_normalize

    difference = vec_norm - vect_op.xhat()
    resi = cas.mtimes(difference.T, difference)

    thresh = 1.e-6
    if resi > thresh:
        message = 'biot-savart filament induction test gives error of size: ' + str(
            resi)
        awelogger.logger.error(message)
        raise Exception(message)

    return None
Esempio n. 5
0
def get_aerodynamic_outputs(options, atmos, wind, variables, outputs,
                            parameters, architecture):

    xd = variables['xd']

    b_ref = parameters['theta0', 'geometry', 'b_ref']
    c_ref = parameters['theta0', 'geometry', 'c_ref']
    s_ref = parameters['theta0', 'geometry', 's_ref']
    reference_lengths = cas.diag(cas.vertcat(b_ref, c_ref, b_ref))

    kite_nodes = architecture.kite_nodes
    for kite in kite_nodes:
        parent = architecture.parent_map[kite]

        q = xd['q' + str(kite) + str(parent)]
        dq = xd['dq' + str(kite) + str(parent)]

        vec_u_eff = tools.get_u_eff_in_earth_frame(options, variables, wind,
                                                   kite, architecture)
        u_eff = vect_op.smooth_norm(vec_u_eff)
        rho = atmos.get_density(q[2])
        q_eff = 0.5 * rho * cas.mtimes(vec_u_eff.T, vec_u_eff)

        if int(options['kite_dof']) == 3:
            kite_dcm = three_dof_kite.get_kite_dcm(options, variables, wind,
                                                   kite, architecture)
        elif int(options['kite_dof']) == 6:
            kite_dcm = six_dof_kite.get_kite_dcm(kite, variables, architecture)
        else:
            message = 'unsupported kite_dof chosen in options: ' + str(
                options['kite_dof'])
            awelogger.logger.error(message)

        if int(options['kite_dof']) == 3:
            framed_forces = tools.get_framed_forces(vec_u_eff, kite_dcm,
                                                    variables, kite,
                                                    architecture)
            m_aero_body = cas.DM.zeros((3, 1))
        elif int(options['kite_dof']) == 6:
            framed_forces = tools.get_framed_forces(vec_u_eff, kite_dcm,
                                                    variables, kite,
                                                    architecture)
            framed_moments = tools.get_framed_moments(vec_u_eff, kite_dcm,
                                                      variables, kite,
                                                      architecture)
            m_aero_body = framed_moments['body']
        else:
            message = 'unsupported kite_dof chosen in options: ' + str(
                options['kite_dof'])
            awelogger.logger.error(message)

        f_aero_body = framed_forces['body']
        f_aero_wind = framed_forces['wind']
        f_aero_control = framed_forces['control']
        f_aero_earth = framed_forces['earth']

        coeff_body = f_aero_body / q_eff / s_ref
        CA = coeff_body[0]
        CY = coeff_body[1]
        CN = coeff_body[2]

        f_drag_wind = f_aero_wind[0] * vect_op.xhat()
        f_side_wind = f_aero_wind[1] * vect_op.yhat()
        f_lift_wind = f_aero_wind[2] * vect_op.zhat()

        f_drag_earth = frames.from_wind_to_earth(vec_u_eff, kite_dcm,
                                                 f_drag_wind)
        f_side_earth = frames.from_wind_to_earth(vec_u_eff, kite_dcm,
                                                 f_side_wind)
        f_lift_earth = frames.from_wind_to_earth(vec_u_eff, kite_dcm,
                                                 f_lift_wind)

        coeff_wind = f_aero_wind / q_eff / s_ref
        CD = coeff_wind[0]
        CS = coeff_wind[1]
        CL = coeff_wind[2]

        CM = cas.mtimes(cas.inv(reference_lengths),
                        m_aero_body) / q_eff / s_ref
        Cl = CM[0]
        Cm = CM[1]
        Cn = CM[2]

        aero_coefficients = {}
        aero_coefficients['CD'] = CD
        aero_coefficients['CS'] = CS
        aero_coefficients['CL'] = CL
        aero_coefficients['CA'] = CA
        aero_coefficients['CY'] = CY
        aero_coefficients['CN'] = CN
        aero_coefficients['Cl'] = Cl
        aero_coefficients['Cm'] = Cm
        aero_coefficients['Cn'] = Cn
        aero_coefficients['LoverD'] = CL / CD

        base_aerodynamic_quantities = {}
        base_aerodynamic_quantities['kite'] = kite
        base_aerodynamic_quantities['air_velocity'] = vec_u_eff
        base_aerodynamic_quantities['airspeed'] = u_eff
        base_aerodynamic_quantities['aero_coefficients'] = aero_coefficients
        base_aerodynamic_quantities['f_aero_earth'] = f_aero_earth
        base_aerodynamic_quantities['f_aero_body'] = f_aero_body
        base_aerodynamic_quantities['f_aero_control'] = f_aero_control
        base_aerodynamic_quantities['f_aero_wind'] = f_aero_wind
        base_aerodynamic_quantities['f_lift_earth'] = f_lift_earth
        base_aerodynamic_quantities['f_drag_earth'] = f_drag_earth
        base_aerodynamic_quantities['f_side_earth'] = f_side_earth
        base_aerodynamic_quantities['m_aero_body'] = m_aero_body
        base_aerodynamic_quantities['kite_dcm'] = kite_dcm
        base_aerodynamic_quantities['q'] = q
        base_aerodynamic_quantities['dq'] = dq

        outputs = indicators.collect_kite_aerodynamics_outputs(
            options, architecture, atmos, wind, variables, parameters,
            base_aerodynamic_quantities, outputs)
        outputs = indicators.collect_environmental_outputs(
            atmos, wind, base_aerodynamic_quantities, outputs)
        outputs = indicators.collect_aero_validity_outputs(
            options, base_aerodynamic_quantities, outputs)
        outputs = indicators.collect_local_performance_outputs(
            architecture, atmos, wind, variables, parameters,
            base_aerodynamic_quantities, outputs)
        outputs = indicators.collect_power_balance_outputs(
            options, architecture, variables, base_aerodynamic_quantities,
            outputs)

    return outputs
Esempio n. 6
0
def get_ehat_tether(options):
    inclination = options['incid_deg'] * np.pi / 180.
    ehat_tether = np.cos(inclination) * vect_op.xhat() + np.sin(
        inclination) * vect_op.zhat()

    return ehat_tether
def __process_interpolation_Variables(interpolation_variables, configurations,
                                      model):
    """Create casadi functions mapping interpolation variables to states

    :type interpolation_variables: dict
    :param interpolation_variables: variables defining the interpolation

    :type configurations: dict
    :param configurations: parameters defining a given configuration

    :type model: awebox.model_dir.model
    :param model: system model

    :rtype: dict, casadi.struct_symSX
    """

    # initialize dict
    rotation_matrix = {}
    rotation_matrix['q00'] = np.eye(3)
    rotation_matrix['dq00'] = np.zeros([3, 3])

    kite_nodes = model.architecture.kite_nodes
    parent_nodes = model.architecture.parent_map
    parent_nodes[0] = 0
    number_of_nodes = model.architecture.number_of_nodes
    kite_dof = model.kite_dof
    trajectory_type = model.options['trajectory']['type']

    conf_0 = configurations['conf_0']
    conf_f = configurations['conf_f']
    l_s = configurations['l_s']
    l_i = configurations['l_i']

    ## generate casadi expressions

    # generate symbolic variables
    sinterp = __get_sstruct(interpolation_variables)
    sstates = {}
    sstates['var'] = {}
    sstates['var']['q00'] = 0.
    sstates['dvar'] = {}
    sstates['dvar']['q00'] = 0.
    sstates['ddvar'] = {}
    sstates['ddvar']['q00'] = 0.

    # generate dict to store functions in
    sstates_functions = {}

    # generate casadi functions: inteprolation variables -> states
    l_t = sinterp['var', 'l_t']
    for node in range(1, number_of_nodes):
        parent_node = parent_nodes[node]
        node_str = str(node) + str(parent_node)
        grandparent_node = parent_nodes[parent_node]
        parent_str = str(parent_node) + str(grandparent_node)
        grandgrandparent_node = parent_nodes[grandparent_node]
        grandparent_str = str(grandparent_node) + str(grandgrandparent_node)

        if (node == 1) and (
                node not in kite_nodes
        ):  # first node parameterized with main tether length
            a = cas.mtimes((conf_f['q' + node_str] - conf_0['q' + node_str]).T,
                           (conf_f['q' + node_str] - conf_0['q' + node_str]))
            if a == 0:
                e_t = vect_op.normalize(conf_0['q' + node_str])
            else:
                b = 2 * cas.mtimes(
                    conf_0['q' + node_str].T,
                    (conf_f['q' + node_str] - conf_0['q' + node_str]))
                c = cas.mtimes(conf_0['q' + node_str].T,
                               conf_0['q' + node_str]) - l_t**2
                D = b**2 - 4 * a * c
                x1 = (-b + np.sqrt(D)) / (2 * a)
                x2 = (-b - np.sqrt(D)) / (2 * a)
                #if x2 >= 0:
                #    s = x2
                #else:
                #    s = x1
                s = x1
                e_t = 1. / l_t * (
                    conf_0['q' + node_str] + s *
                    (conf_f['q' + node_str] - conf_0['q' + node_str]))
            sstates['var']['q' + node_str] = l_t * e_t
            rotation_matrix = compute_rotation_matrices(
                sinterp.prefix['var'], node_str, parent_str, rotation_matrix)

        else:
            if (node in kite_nodes):

                if node == 1:
                    tether_length = l_t
                else:
                    tether_length = l_s

                Phi = sinterp['var', 'Phi' + node_str]
                Omega = sinterp['var', 'Omega' + node_str]
                parent = sstates['var']['q' + parent_str]
                grandparent = sstates['var']['q' + grandparent_str]

                radius = tether_length * np.sin(Phi)
                l_x = tether_length * np.cos(Phi)

                # define axis of rotation
                if node != 1:
                    axis_of_rot = parent - grandparent
                    axis_of_rot = vect_op.normalize(axis_of_rot)
                else:
                    inclination = sinterp['var', 'inclination' + node_str]
                    axis_of_rot = np.zeros([3, 1])
                    axis_of_rot[0] = np.cos(inclination)
                    axis_of_rot[2] = np.sin(inclination)
                e_hat_x = axis_of_rot
                e_hat_y = vect_op.normed_cross(e_hat_x, vect_op.zhat())
                e_hat_z = vect_op.normed_cross(e_hat_y, e_hat_x)
                e_hat_r = e_hat_z * np.sin(Omega) + e_hat_y * np.cos(Omega)

                sstates['var']['q' + node_str] = sstates['var'][
                    'q' + parent_str] + e_hat_r * radius + e_hat_x * l_x

            else:
                tether_length = l_i
                rotation_matrix = compute_rotation_matrices(
                    sinterp.prefix['var'], node_str, parent_str,
                    rotation_matrix)
                tether_vector = vect_op.xhat()
                tether_vector = cas.mtimes(rotation_matrix['q' + node_str],
                                           tether_vector)
                sstates['var']['q' + node_str] = sstates['var'][
                    'q' + parent_str] + tether_vector * tether_length

        sstates['dvar']['q' + node_str] = cas.mtimes(
            cas.jacobian(sstates['var']['q' + node_str], sinterp['var']),
            sinterp['dvar'])

        # create rotational kinematics
        if int(kite_dof) == 6:

            # iterate over all kite ndoes
            if node in kite_nodes:

                # get node strings
                parent = parent_nodes[node]
                node_str = str(node) + str(parent)
                grandparent = parent_nodes[parent]
                parent_str = str(parent) + str(grandparent)
                grandgrandparent = parent_nodes[grandparent]
                grandparent_str = str(grandparent) + str(grandgrandparent)

                # compute dcm matrix for node
                e_hat_1, e_hat_2, e_hat_3 = __get_kite_axis(
                    sstates, node_str, parent_str, grandparent_str,
                    trajectory_type)
                dcm = ct.horzcat(e_hat_1, e_hat_2, e_hat_3)
                dcm_column = ct.reshape(dcm, (9, 1))

                # compute rotation around axis
                omega_norm = vect_op.norm(
                    sstates['dvar']['q' + node_str]) / radius
                if trajectory_type == 'lift_mode':
                    omega_vector = vect_op.normalize(axis_of_rot) * omega_norm
                elif trajectory_type == 'nominal_landing':
                    omega_vector = cas.DM([0, 0, 0])

                # put in state dict
                sstates['omega' + node_str] = omega_vector
                sstates['r' + node_str] = dcm_column

        # generate functions
        sstates_functions['q' + node_str] = cas.Function(
            'q' + node_str, [sinterp], [sstates['var']['q' + node_str]])
        sstates_functions['dq' + node_str] = cas.Function(
            'dq' + node_str, [sinterp], [sstates['dvar']['q' + node_str]])
        if int(kite_dof) == 6 and node in kite_nodes:
            sstates_functions['r' + node_str] = cas.Function(
                'r' + node_str, [sinterp], [sstates['r' + node_str]])
            sstates_functions['omega' + node_str] = cas.Function(
                'omega' + node_str, [sinterp], [sstates['omega' + node_str]])

    return sstates_functions, sinterp