Пример #1
0
def from_earth_to_body(kite_dcm, vector):

    # kite frame conversion (earth to body) involves a matrix inversion. div-by-zero errors are possible.
    # therefore: avoid using this conversion in critical-path

    dcm_inv = cas.inv(kite_dcm)
    transformed = cas.mtimes(dcm_inv, vector)
    return transformed
Пример #2
0
def from_earth_to_wind(vec_u, kite_dcm, vector):

    # kite frame conversion (earth to wind) involves a matrix inversion. div-by-zero errors are possible.
    # therefore: avoid using this conversion in critical-path

    wind_dcm = get_wind_dcm(vec_u, kite_dcm)
    wind_dcm_inv = cas.inv(wind_dcm)
    transformed = cas.mtimes(wind_dcm_inv, vector)
    return transformed
Пример #3
0
def from_earth_to_body(vector, q_upper, q_lower):

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

    r_from_body_to_ef = cas.horzcat(ehat_x, ehat_y, ehat_z)
    r_from_ef_to_body = cas.inv(r_from_body_to_ef)

    transformed = cas.mtimes(r_from_ef_to_body, vector)

    return transformed
Пример #4
0
def time_derivative(expr, variables, architecture):

    # notice that the the chain rule
    # df/dt = partial f/partial t
    #       + (partial f/partial x1)(partial x1/partial t)
    #       + (partial f/partial x2)(partial x2/partial t)...
    # doesn't care about the scaling of the component functions, as long as
    # the units of (partial xi) will cancel

    # it is here assumed that (partial f/partial t) = 0.

    vars_scaled = variables['scaled']
    deriv = 0.

    # (partial f/partial xi) for variables with trivial derivatives
    deriv_vars = struct_op.subkeys(vars_scaled, 'xddot')
    for deriv_name in deriv_vars:

        deriv_type = struct_op.get_variable_type(variables['SI'], deriv_name)

        var_name = deriv_name[1:]
        var_type = struct_op.get_variable_type(variables['SI'], var_name)

        q_sym = vars_scaled[var_type, var_name]
        dq_sym = vars_scaled[deriv_type, deriv_name]
        deriv += cas.mtimes(cas.jacobian(expr, q_sym), dq_sym)

    # (partial f/partial xi) for kite rotation matrices
    kite_nodes = architecture.kite_nodes
    for kite in kite_nodes:
        parent = architecture.parent_map[kite]

        r_name = 'r{}{}'.format(kite, parent)
        kite_has_6dof = r_name in struct_op.subkeys(vars_scaled, 'xd')
        if kite_has_6dof:
            r_kite = vars_scaled['xd', r_name]
            dcm_kite = cas.reshape(r_kite, (3, 3))

            omega = vars_scaled['xd', 'omega{}{}'.format(kite, parent)]

            dexpr_dr = cas.jacobian(expr, r_kite)
            dr_dt = cas.reshape(
                cas.mtimes(vect_op.skew(omega), cas.inv(dcm_kite.T)), (9, 1))
            deriv += cas.mtimes(dexpr_dr, dr_dt)

    return deriv
Пример #5
0
def var_si_to_scaled(var_type, var_name, var_si, scaling):

    scaling_defined_for_variable = (var_type in scaling.keys()) and (
        var_name in scaling[var_type].keys())
    if scaling_defined_for_variable:

        scale = scaling[var_type][var_name]

        if scale.shape == (1, 1):

            use_unit_scaling = (scale == cas.DM(1.)) or (scale == 1.)
            if use_unit_scaling:
                return var_si
            else:
                return var_si / scale

        else:
            matrix_factor = cas.inv(cas.diag(scale))
            return cas.mtimes(matrix_factor, var_si)

    else:
        return var_si
Пример #6
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