Exemplo n.º 1
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
Exemplo n.º 2
0
def jacobian_dcm(expr, xd_si, variables_scaled, kite, parent):
    """ Differentiate expression w.r.t. kite direct cosine matrix"""

    dcm_si = xd_si['r{}{}'.format(kite, parent)]
    dcm_scaled = variables_scaled['xd', 'r{}{}'.format(kite, parent)]

    jac_dcm = rotation(
            cas.reshape(dcm_si, (3,3)),
            cas.reshape(cas.jacobian(expr, dcm_scaled), (3,3))
    ).T
    return jac_dcm
Exemplo n.º 3
0
def initial_guess_actuator_xl(init_options, nlp, formulation, model, V_init):
    level_siblings = model.architecture.get_all_level_siblings()

    time_final = init_options['precompute']['time_final']
    omega_norm = init_options['precompute']['angular_speed']

    tgrid_coll = nlp.time_grids['coll'](time_final)

    u_hat, v_hat, w_hat = get_local_wind_reference_frame(init_options)
    uzero_matr = cas.horzcat(u_hat, v_hat, w_hat)
    uzero_matr_cols = cas.reshape(uzero_matr, (9, 1))

    n_rot_hat, y_rot_hat, z_rot_hat = tools_init.get_rotor_reference_frame(init_options)
    rot_matr = cas.horzcat(n_rot_hat, y_rot_hat, z_rot_hat)
    rot_matr_cols = cas.reshape(rot_matr, (9, 1))

    dict = {}
    dict['rot_matr'] = rot_matr_cols
    dict['area'] = cas.DM(1.)
    dict['cmy'] = cas.DM(0.)
    dict['cmz'] = cas.DM(0.)
    dict['uzero_matr'] = uzero_matr_cols
    dict['g_vec_length'] = cas.DM(1.)
    dict['n_vec_length'] = cas.DM(1.)
    dict['z_vec_length'] = cas.DM(1.)
    dict['u_vec_length'] = cas.DM(1.)
    dict['varrho'] = cas.DM(1.)
    dict['qzero'] = cas.DM(1.)
    dict['gamma'] = get_gamma_angle(init_options)
    dict['cosgamma'] = np.cos(dict['gamma'])
    dict['singamma'] = np.sin(dict['gamma'])
    dict['chi'] = get_chi_angle(init_options, 'xl')
    dict['coschi'] = np.cos(dict['chi'])
    dict['sinchi'] = np.sin(dict['chi'])
    dict['tanhalfchi'] = np.tan(dict['chi'] / 2.)
    dict['sechalfchi'] = 1. / np.cos(dict['chi'] / 2.)
    dict['LL'] = cas.DM([0.375, 0., 0., 0., -1., 0., 0., -1., 0.])
    dict['corr'] = 1. - init_options['xd']['a']

    var_type = 'xl'
    for name in struct_op.subkeys(model.variables, 'xl'):
        name_stripped, _ = struct_op.split_name_and_node_identifier(name)

        if 'psi' in name_stripped:
            V_init = set_azimuth_variables(V_init, init_options, name, model, nlp, tgrid_coll, level_siblings, omega_norm)

        elif name_stripped in dict.keys():
            V_init = tools_init.insert_dict(dict, var_type, name, name_stripped, V_init)

    return V_init
Exemplo n.º 4
0
def draw_kite_vertical(ax, q, r, length, height, b_ref, c_ref, kite_color, side, num_per_meter, naca="0012"):

    r_dcm = np.array(cas.reshape(r, (3, 3)))
    r_dcm = np.array(cas.reshape(r, (3, 3)))
    ehat_1 = np.reshape(r_dcm[:, 0], (3, 1))
    ehat_3 = np.reshape(r_dcm[:, 2], (3, 1))

    new_ehat1 = ehat_1
    new_ehat2 = ehat_3
    new_ehat3 = np.array(vect_op.normed_cross(new_ehat1, new_ehat2))
    r_new = np.array(cas.horzcat(new_ehat1, new_ehat2, new_ehat3))

    horizontal_space = (3. * length / 4. - c_ref / 3.) * ehat_1
    pos = q + horizontal_space + ehat_3 * height / 2.

    draw_lifting_surface(ax, pos, r_new, height, c_ref, c_ref / 2., c_ref / 4., kite_color, side, num_per_meter, naca)
Exemplo n.º 5
0
def get_aero_test_values(t, options):

    h_0 = options['aero_test']['h_0']
    phi_0 = options['aero_test']['phi_0']
    omega = options['aero_test']['omega']

    h = h_0 * np.sin(omega * t)
    dh = h_0 * np.cos(omega * t) * omega
    dh = -1. * h_0 * np.sin(omega * t) * omega**2.

    phi = phi_0 * np.cos(omega * t)
    dphi = -1. * phi_0 * np.sin(omega * t) * omega
    ddphi = -1. * phi_0 * np.cos(omega * t) * omega**2.

    l_t = h + 3.
    dl_t = dh

    q10 = l_t * vect_op.zhat_np()
    dq10 = dl_t * vect_op.zhat_np()

    ehat1 = np.cos(phi) * vect_op.xhat_np() - np.sin(phi) * vect_op.zhat_np()
    ehat2 = vect_op.yhat_np()
    ehat3 = np.cos(phi) * vect_op.zhat_np() + np.sin(phi) * vect_op.xhat_np()

    r_dcm = cas.horzcat(ehat1, ehat2, ehat3)
    r_dcm = cas.reshape(r_dcm, (9, 1))

    omega = dphi * ehat2

    return l_t, dl_t, q10, dq10, r_dcm, omega
Exemplo n.º 6
0
def get_wingtip_position(kite, model, variables, parameters, ext_int):
    parent_map = model.architecture.parent_map

    xd = model.variables_dict['xd'](variables['xd'])

    if ext_int == 'ext':
        span_sign = 1.
    elif ext_int == 'int':
        span_sign = -1.
    else:
        awelogger.logger.error('wing side not recognized for 6dof kite.')

    parent = parent_map[kite]

    name = 'q' + str(kite) + str(parent)
    q_unscaled = xd[name]
    scale = model.scaling['xd'][name]
    q = q_unscaled * scale

    kite_dcm = cas.reshape(xd['kite_dcm' + str(kite) + str(parent)], (3, 3))
    ehat_span = kite_dcm[:, 1]

    b_ref = parameters['theta0', 'geometry', 'b_ref']

    wingtip_position = q + ehat_span * span_sign * b_ref / 2.

    return wingtip_position
Exemplo n.º 7
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
Exemplo n.º 8
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)
Exemplo n.º 9
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
Exemplo n.º 10
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
Exemplo n.º 11
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
Exemplo n.º 12
0
def columnize(var):
    # only allows 2x2 matrices for variable

    [counted_rows, counted_columns] = var.shape
    number_elements = counted_rows * counted_columns

    column_var = cas.reshape(var, (number_elements, 1))

    return column_var
Exemplo n.º 13
0
def draw_kite_horizontal(ax, q, r, length, height, b_ref, c_ref, kite_color, side, num_per_meter, naca="0012"):

    r_dcm = np.array(cas.reshape(r, (3, 3)))
    ehat_1 = np.reshape(r_dcm[:, 0], (3,1))
    ehat_3 = np.reshape(r_dcm[:, 2], (3,1))

    horizontal_space = (3. * length / 4. - c_ref / 3.) * ehat_1
    pos = q + horizontal_space + ehat_3 * height

    draw_lifting_surface(ax, pos, r_dcm, b_ref / 3., c_ref / 3., c_ref / 2., c_ref / 3., kite_color, side, num_per_meter, naca)
Exemplo n.º 14
0
def isRotationMatrix(R):

    diff = cas.DM.eye(3) - cas.mtimes(R.T, R)
    diff_vert = cas.reshape(diff, (9, 1))
    resi = norm(diff_vert)**0.5

    threshold = 1.e-1
    
    if resi > threshold:
        print('resi:' + str(resi) + ' threshold: ' + str(threshold))
    return resi < threshold
Exemplo n.º 15
0
def guess_values_at_time(t, init_options, model):
    ret = {}
    for name in struct_op.subkeys(model.variables, 'xd'):
        ret[name] = 0.0
    ret['e'] = 0.0

    ret['l_t'] = init_options['xd']['l_t']
    ret['dl_t'] = 0.0

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

    kite_dof = model.kite_dof

    for node in range(1, number_of_nodes):

        parent = parent_map[node]
        if parent == 0:
            parent_position = np.zeros((3, 1))
        else:
            grandparent = parent_map[parent]
            parent_position = ret['q' + str(parent) + str(grandparent)]

        if not node in kite_nodes:
            ret['q' + str(node) + str(parent)] = get_tether_node_position(init_options, parent_position, node, ret['l_t'])
            ret['dq' + str(node) + str(parent)] = np.zeros((3, 1))

        else:
            height = init_options['precompute']['height']
            radius = init_options['precompute']['radius']

            ehat_normal, ehat_radial, ehat_tangential = tools.get_rotating_reference_frame(t, init_options, model, node, ret)

            tether_vector = ehat_radial * radius + ehat_normal * height

            position = parent_position + tether_vector
            velocity = tools.get_velocity_vector(t, init_options, model, node, ret)
            ret['q' + str(node) + str(parent)] = position
            ret['dq' + str(node) + str(parent)] = velocity

            dcm = tools.get_kite_dcm(t, init_options, model, node, ret)
            if init_options['cross_tether']:
                if init_options['cross_tether_attachment'] in ['com','stick']:
                    dcm = get_cross_tether_dcm(init_options, dcm)
            dcm_column = cas.reshape(dcm, (9, 1))

            omega_vector = tools.get_omega_vector(t, init_options, model, node, ret)

            if int(kite_dof) == 6:
                ret['omega' + str(node) + str(parent)] = omega_vector
                ret['r' + str(node) + str(parent)] = dcm_column

    return ret
Exemplo n.º 16
0
    def __create_reference_interpolator(self):
        """ Create time-varying reference generator for tracking MPC based on interpolation of
            optimal periodic steady state.
        """

        # MPC time grid
        self.__t_grid_coll = self.__trial.nlp.time_grids['coll'](self.__N*self.__ts)
        self.__t_grid_coll = ct.reshape(self.__t_grid_coll.T, self.__t_grid_coll.numel(),1).full()
        self.__t_grid_x_coll = self.__trial.nlp.time_grids['x_coll'](self.__N*self.__ts)
        self.__t_grid_x_coll = ct.reshape(self.__t_grid_x_coll.T, self.__t_grid_x_coll.numel(),1).full()

        # interpolate steady state solution
        self.__ref_dict = self.__pocp_trial.visualization.plot_dict
        nlp_options = self.__pocp_trial.options['nlp']
        V_opt = self.__pocp_trial.optimization.V_opt
        if self.__mpc_options['ref_interpolator'] == 'poly':
            self.__interpolator = self.__pocp_trial.nlp.Collocation.build_interpolator(nlp_options, V_opt)
        elif self.__mpc_options['ref_interpolator'] == 'spline':
            self.__interpolator = self.__build_spline_interpolator(nlp_options, V_opt)

        return None
Exemplo n.º 17
0
def decolumnize(options, architecture, columnized_list):
    wake_nodes = options['induction']['vortex_wake_nodes']
    number_kites = architecture.number_of_kites
    rings = wake_nodes - 1

    entries = columnized_list.shape[0]
    filaments = 3 * (rings + 1) * number_kites
    arguments = int(float(entries) / float(filaments))

    filament_list = cas.reshape(columnized_list, (arguments, filaments))

    return filament_list
Exemplo n.º 18
0
def resquare(column):

    entries = column.shape[0] * column.shape[1]
    guess_side_dim = np.sqrt(float(entries))
    can_be_resquared = (np.floor(guess_side_dim) **2. == float(entries))

    if can_be_resquared:
        side = int(guess_side_dim)
        return cas.reshape(column, (side, side))
    else:
        message = 'column matrix cannot be re-squared. inappropriate number of entries: ' + str(entries)
        awelogger.logger.error(message)
        return column
Exemplo n.º 19
0
def draw_kite_fuselage(ax,
                       q,
                       r,
                       length,
                       kite_color,
                       side,
                       body_cross_sections_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 * body_cross_sections_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
        zloc = cas.mtimes(r_dcm, vect_op.zhat_np()) * y * total_width

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

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

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

            new_point_upwise = q + zloc + np.array(
                cas.mtimes(r_dcm, basic_shell[idx, :].T))
            up_direction_shell = cas.vertcat(up_direction_shell,
                                             new_point_upwise.T)

        span_direction_shell = np.array(span_direction_shell)
        make_side_plot(ax, span_direction_shell, side, kite_color)

        up_direction_shell = np.array(up_direction_shell)
        make_side_plot(ax, up_direction_shell, side, kite_color)

    return None
Exemplo n.º 20
0
def collect_aero_validity_outputs(options, xd, ua, n, parent, outputs, parameters):

    if 'aero_validity' not in list(outputs.keys()):
        outputs['aero_validity'] = {}
    tightness = options['model_bounds']['aero_validity']['scaling']
    num_ref = options['model_bounds']['aero_validity']['num_ref']

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

    alpha = cas.DM(0.)
    beta = cas.DM(0.)
    if int(options['kite_dof']) == 6:

        r = cas.reshape(xd['r' + str(n) + str(parent)], (3, 3))
        ehat1 = r[:, 0]  # chordwise, froml_e tot_e
        ehat2 = r[:, 1]  # spanwise, fromp_e ton_e
        ehat3 = r[:, 2]  # up

        alpha = get_alpha(ua, r)
        beta = get_beta(ua, r)

        alpha_min = options['aero']['alpha_min_deg']*np.pi/180.0
        alpha_max = options['aero']['alpha_max_deg']*np.pi/180.0
        beta_min = options['aero']['beta_min_deg']*np.pi/180.0
        beta_max = options['aero']['beta_max_deg']*np.pi/180.0

        alpha_ub = (cas.mtimes(ua.T, ehat3) - cas.mtimes(ua.T, ehat1) * alpha_max) * tightness / num_ref
        alpha_lb = (- cas.mtimes(ua.T, ehat3) + cas.mtimes(ua.T, ehat1) * alpha_min) * tightness / num_ref
        beta_ub = (cas.mtimes(ua.T, ehat2) - cas.mtimes(ua.T, ehat1) * beta_max) * tightness / num_ref
        beta_lb = (- cas.mtimes(ua.T, ehat2) + cas.mtimes(ua.T, ehat1) * beta_min) * tightness / num_ref

        outputs['aero_validity']['alpha_ub' + str(n)] = alpha_ub
        outputs['aero_validity']['alpha_lb' + str(n)] = alpha_lb
        outputs['aero_validity']['beta_ub' + str(n)] = beta_ub
        outputs['aero_validity']['beta_lb' + str(n)] = beta_lb

    outputs['aerodynamics']['alpha' + str(n)] = alpha
    outputs['aerodynamics']['beta' + str(n)] = beta
    outputs['aerodynamics']['alpha_deg' + str(n)] = alpha * 180. / np.pi
    outputs['aerodynamics']['beta_deg' + str(n)] = beta * 180. / np.pi

    return outputs
Exemplo n.º 21
0
def collect_kite_aerodynamics_outputs(options, architecture, atmos, wind,
                                      variables, parameters,
                                      base_aerodynamic_quantities, outputs):

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

    # unpack
    kite = base_aerodynamic_quantities['kite']
    air_velocity = base_aerodynamic_quantities['air_velocity']
    aero_coefficients = base_aerodynamic_quantities['aero_coefficients']
    f_aero_earth = base_aerodynamic_quantities['f_aero_earth']
    f_aero_body = base_aerodynamic_quantities['f_aero_body']

    f_aero_control = base_aerodynamic_quantities['f_aero_control']
    f_aero_wind = base_aerodynamic_quantities['f_aero_wind']
    f_lift_earth = base_aerodynamic_quantities['f_lift_earth']
    f_drag_earth = base_aerodynamic_quantities['f_drag_earth']
    f_side_earth = base_aerodynamic_quantities['f_side_earth']
    m_aero_body = base_aerodynamic_quantities['m_aero_body']
    kite_dcm = base_aerodynamic_quantities['kite_dcm']
    q = base_aerodynamic_quantities['q']

    f_lift_earth_overwrite = options['aero']['overwrite']['f_lift_earth']
    if f_lift_earth_overwrite is not None:
        f_lift_earth = f_lift_earth_overwrite

    for name in set(base_aerodynamic_quantities['aero_coefficients'].keys()):
        outputs['aerodynamics'][
            name +
            str(kite)] = base_aerodynamic_quantities['aero_coefficients'][name]

    outputs['aerodynamics']['air_velocity' + str(kite)] = air_velocity
    airspeed = vect_op.norm(air_velocity)
    outputs['aerodynamics']['airspeed' + str(kite)] = airspeed
    outputs['aerodynamics']['u_infty' + str(kite)] = wind.get_velocity(q[2])

    rho = atmos.get_density(q[2])
    outputs['aerodynamics']['air_density' + str(kite)] = rho
    outputs['aerodynamics']['dyn_pressure' +
                            str(kite)] = 0.5 * rho * cas.mtimes(
                                air_velocity.T, air_velocity)

    ehat_chord = kite_dcm[:, 0]
    ehat_span = kite_dcm[:, 1]
    ehat_up = kite_dcm[:, 2]

    outputs['aerodynamics']['ehat_chord' + str(kite)] = ehat_chord
    outputs['aerodynamics']['ehat_span' + str(kite)] = ehat_span
    outputs['aerodynamics']['ehat_up' + str(kite)] = ehat_up

    outputs['aerodynamics']['f_aero_body' + str(kite)] = f_aero_body
    outputs['aerodynamics']['f_aero_control' + str(kite)] = f_aero_control
    outputs['aerodynamics']['f_aero_earth' + str(kite)] = f_aero_earth
    outputs['aerodynamics']['f_aero_wind' + str(kite)] = f_aero_wind

    ortho = cas.reshape(cas.mtimes(kite_dcm.T, kite_dcm) - np.eye(3), (9, 1))
    ortho_resi = cas.mtimes(ortho.T, ortho)
    outputs['aerodynamics']['ortho_resi' + str(kite)] = ortho_resi

    conversion_resis = []
    conversion_targets = {
        'control': f_aero_control,
        'earth': f_aero_earth,
        'wind': f_aero_wind
    }
    for f_aero_target in conversion_targets.values():
        resi = 1. - vect_op.norm(f_aero_target) / vect_op.norm(f_aero_body)
        conversion_resis = cas.vertcat(conversion_resis, resi)

    resi = vect_op.norm(f_aero_earth - f_lift_earth - f_drag_earth -
                        f_side_earth) / vect_op.norm(f_aero_body)
    conversion_resis = cas.vertcat(conversion_resis, resi)

    outputs['aerodynamics']['check_conversion' + str(kite)] = conversion_resis

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

    b_ref = parameters['theta0', 'geometry', 'b_ref']
    c_ref = parameters['theta0', 'geometry', 'c_ref']

    circulation_cross = vect_op.smooth_norm(
        f_lift_earth) / b_ref / rho / vect_op.smooth_norm(
            vect_op.cross(air_velocity, ehat_span))
    circulation_cl = 0.5 * airspeed**2. * aero_coefficients[
        'CL'] * c_ref / vect_op.smooth_norm(
            vect_op.cross(air_velocity, ehat_span))

    outputs['aerodynamics']['circulation_cross' +
                            str(kite)] = circulation_cross
    outputs['aerodynamics']['circulation_cl' + str(kite)] = circulation_cl
    outputs['aerodynamics']['circulation' + str(kite)] = circulation_cross

    outputs['aerodynamics']['wingtip_ext' +
                            str(kite)] = q + ehat_span * b_ref / 2.
    outputs['aerodynamics']['wingtip_int' +
                            str(kite)] = q - ehat_span * b_ref / 2.

    outputs['aerodynamics']['fstar_aero' + str(kite)] = cas.mtimes(
        air_velocity.T, ehat_chord) / c_ref

    outputs['aerodynamics']['r' + str(kite)] = kite_dcm.reshape((9, 1))

    if int(options['kite_dof']) == 6:
        outputs['aerodynamics']['m_aero_body' + str(kite)] = m_aero_body

    outputs['aerodynamics']['mach' + str(kite)] = get_mach(
        options, atmos, air_velocity, q)
    outputs['aerodynamics']['reynolds' + str(kite)] = get_reynolds(
        options, atmos, air_velocity, q, parameters)

    return outputs
Exemplo n.º 22
0
def generate_holonomic_constraints(architecture, outputs, variables, parameters, options):
    number_of_nodes = architecture.number_of_nodes
    parent_map = architecture.parent_map
    kite_nodes = architecture.kite_nodes

    # extract necessary SI variables
    xd_si = variables['SI']['xd']
    xa_si = variables['SI']['xa']

    # scaled variables struct
    var_scaled = variables['scaled']

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

    # build constraints with si variables
    g_dict = get_tether_length_constraint(options, variables['SI'], parameters, architecture)
    outputs['tether_length'].update(g_dict)

    g = []
    gdot = []
    gddot = []
    holonomic_constraints = 0.0

    for node in range(1, number_of_nodes):
        parent = parent_map[node]

        # chain rule, based on scaled variables
        g_local = g_dict['c' + str(node) + str(parent)]
        g.append(g_local)

        # first-order derivative
        dg_local = tools.time_derivative(g_local, variables, architecture)
        gdot.append(dg_local)

        # second-order derivative
        ddg_local = tools.time_derivative(dg_local, variables, architecture)
        gddot.append(ddg_local)

        # outputs['tether_length']['c' + str(node) + str(parent)] = g[-1]
        outputs['tether_length']['dc' + str(node) + str(parent)] = dg_local
        outputs['tether_length']['ddc' + str(node) + str(parent)] = ddg_local
        holonomic_constraints += xa_si['lambda{}{}'.format(node, parent)] * g_local

    # add cross-tethers
    if options['cross_tether'] and len(kite_nodes) > 1:

        g_dict = get_cross_tether_length_constraint(options, variables['SI'], parameters, architecture)
        outputs['tether_length'].update(g_dict)

        for l in architecture.layer_nodes:
            kite_children = architecture.kites_map[l]

            # dual kite system (per layer) only has one tether
            if len(kite_children) == 2:
                no_tethers = 1
            else:
                no_tethers = len(kite_children)

            # add cross-tether constraints
            for k in range(no_tethers):

                # set-up relevant node numbers
                n01 = '{}{}'.format(kite_children[k], kite_children[(k + 1) % len(kite_children)])

                length_constraint = g_dict['c{}'.format(n01)]

                # append constraint
                g_local = length_constraint
                g.append(length_constraint)

                dg_local = tools.time_derivative(g_local, variables, architecture)
                gdot.append(dg_local)

                ddg_local = tools.time_derivative(dg_local, variables, architecture)
                gddot.append(ddg_local)

                # save invariants to outputs
                outputs['tether_length']['dc{}'.format(n01)] = dg_local
                outputs['tether_length']['ddc{}'.format(n01)] = ddg_local

                # add to holonomic constraints
                holonomic_constraints += xa_si['lambda{}'.format(n01)] * g_local

        if node in kite_nodes:
            if 'r' + str(node) + str(parent) in list(xd_si.keys()):
                r = cas.reshape(var_scaled['xd', 'r' + str(node) + str(parent)], (3, 3))
                orthonormality = cas.mtimes(r.T, r) - cas.DM_eye(3)
                orthonormality = cas.reshape(orthonormality, (9, 1))

                outputs['tether_length']['orthonormality' + str(node) + str(parent)] = orthonormality

                dr_dt = variables['SI']['xddot']['dr' + str(node) + str(parent)]
                dr_dt = cas.reshape(dr_dt, (3, 3))
                omega = variables['SI']['xd']['omega' + str(node) + str(parent)]
                omega_skew = vect_op.skew(omega)
                dr = cas.mtimes(r, omega_skew)
                rot_kinematics = dr_dt - dr
                rot_kinematics = cas.reshape(rot_kinematics, (9, 1))

                outputs['tether_length']['rot_kinematics10'] = rot_kinematics

    g_cat = cas.vertcat(*g)
    gdot_cat = cas.vertcat(*gdot)
    gddot_cat = cas.vertcat(*gddot)

    return holonomic_constraints, outputs, g_cat, gdot_cat, gddot_cat
Exemplo n.º 23
0
def get_cross_tether_length_constraint(options, vars_si, parameters, architecture):

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

    g_dict = {}

    kite_nodes = architecture.kite_nodes
    parent_map = architecture.parent_map

    if options['cross_tether'] and len(kite_nodes) > 1:
        for l in architecture.layer_nodes:
            kite_children = architecture.kites_map[l]

            # dual kite system (per layer) only has one tether
            if len(kite_children) == 2:
                no_tethers = 1
            else:
                no_tethers = len(kite_children)

            # add cross-tether constraints
            for k in range(no_tethers):

                # set-up relevant node numbers
                n0 = '{}{}'.format(kite_children[k], parent_map[kite_children[k]])
                n1 = '{}{}'.format(kite_children[(k + 1) % len(kite_children)],
                                   parent_map[kite_children[(k + 1) % len(kite_children)]])
                n01 = '{}{}'.format(kite_children[k], kite_children[(k + 1) % len(kite_children)])

                # center-of-mass attachment
                if options['tether']['cross_tether']['attachment'] == 'com':
                    first_node = xd_si['q{}'.format(n0)]
                    second_node = xd_si['q{}'.format(n1)]

                # stick or wing-tip attachment
                else:

                    # only implemented for 6DOF
                    if int(options['kite_dof']) == 6:

                        # rotation matrices of relevant kites
                        dcm_first = cas.reshape(xd_si['r{}'.format(n0)], (3, 3))
                        dcm_second = cas.reshape(xd_si['r{}'.format(n1)], (3, 3))

                        # stick: same attachment point as secondary tether
                        if options['tether']['cross_tether']['attachment'] == 'stick':
                            r_tether = parameters['theta0', 'geometry', 'r_tether']

                        # wing_tip: attachment half a wing span in negative span direction
                        elif options['tether']['cross_tether']['attachment'] == 'wing_tip':
                            r_tether = cas.vertcat(0.0, -parameters['theta0', 'geometry', 'b_ref'] / 2.0, 0.0)

                        # unknown option notifier
                        else:
                            raise ValueError('Unknown cross-tether attachment option: {}'.format(
                                options['tether']['cross_tether']['attachment']))

                        # create attachment nodes
                        first_node = xd_si['q{}'.format(n0)] + cas.mtimes(dcm_first, r_tether)
                        second_node = xd_si['q{}'.format(n1)] + cas.mtimes(dcm_second, r_tether)

                    # not implemented for 3DOF
                    elif int(options['kite_dof']) == 3:
                        raise ValueError('Stick cross-tether attachment options not implemented for 3DOF kites')

                # cross-tether length
                segment_length = theta_si['l_c{}'.format(l)]

                # create constraint
                length_constraint = 0.5 * (
                        cas.mtimes(
                            (first_node - second_node).T,
                            (first_node - second_node)) - segment_length ** 2.0)

                g_dict['c{}'.format(n01)] = length_constraint

    return g_dict
Exemplo n.º 24
0
def columnize(filament_list):
    dims = filament_list.shape
    columnized_list = cas.reshape(filament_list, (dims[0] * dims[1], 1))
    return columnized_list
Exemplo n.º 25
0
def get_uzero_matr_var(variables, parent):
    rot_cols = variables['xl']['uzero_matr' + str(parent)]
    rot_matr = cas.reshape(rot_cols, (3, 3))

    return rot_matr
Exemplo n.º 26
0
def initial_node_variables_for_standard_path(t,
                                             options,
                                             model,
                                             formulation,
                                             ret={}):

    trajectory_type = options['type']

    number_of_nodes = model.architecture.number_of_nodes
    parent_map = model.architecture.parent_map
    kite_nodes = model.architecture.kite_nodes
    level_siblings = get_all_level_siblings(options, model)

    ua_norm = options['ua_norm']
    kite_dof = model.kite_dof

    [height_list, radius, ehat_tether, ehat_side,
     ehat_up] = get_orbit_cone_parameters(options, model, ret['l_t'])

    for node in range(1, number_of_nodes):

        parent = parent_map[node]
        if parent == 0:
            parent_position = np.zeros((3, 1))
        else:
            grandparent = parent_map[parent]
            parent_position = ret['q' + str(parent) + str(grandparent)]

        if not node in kite_nodes:
            ret['q' + str(node) + str(parent)] = get_tether_node_position(
                options, parent_position, node, ret['l_t'])
            ret['dq' + str(node) + str(parent)] = np.zeros((3, 1))

        else:
            if parent == 0:
                height = height_list[0]
            else:
                height = height_list[1]

            omega_norm = ua_norm / radius
            omega_vector = ehat_tether * omega_norm

            psi = get_azimuthal_angle(t, level_siblings, node, parent,
                                      omega_norm)

            ehat_radial = ehat_side * np.cos(psi) + ehat_up * np.sin(psi)
            tether_vector = ehat_radial * radius + ehat_tether * height

            position = parent_position + tether_vector

            ehat_tangential = -1. * ehat_side * np.sin(psi) + ehat_up * np.cos(
                psi)
            velocity = ua_norm * ehat_tangential

            ehat1 = -1. * ehat_tangential
            ehat3 = ehat_tether
            ehat2 = vect_op.normed_cross(ehat3, ehat1)

            dcm = cas.horzcat(ehat1, ehat2, ehat3)
            dcm_column = cas.reshape(dcm, (9, 1))

            ret['q' + str(node) + str(parent)] = position
            ret['dq' + str(node) + str(parent)] = velocity

            if int(kite_dof) == 6:
                ret['omega' + str(node) + str(parent)] = omega_vector
                ret['r' + str(node) + str(parent)] = dcm_column

    return ret
Exemplo n.º 27
0
def compute_vortex_verification_points(plot_dict, cosmetics, idx_at_eval, kdx):

    kite_plane_induction_params = get_kite_plane_induction_params(
        plot_dict, idx_at_eval)

    architecture = plot_dict['architecture']
    filament_list = reconstruct_filament_list(plot_dict, idx_at_eval)
    number_of_kites = architecture.number_of_kites

    radius = kite_plane_induction_params['average_radius']
    center = kite_plane_induction_params['center']
    u_infty = kite_plane_induction_params['u_infty']

    u_zero = u_infty

    verification_points = plot_dict['options']['model']['aero']['vortex'][
        'verification_points']
    half_points = int(verification_points / 2.) + 1

    psi0_base = plot_dict['options']['solver']['initialization']['psi0_rad']

    mu_grid_min = kite_plane_induction_params['mu_start_by_path']
    mu_grid_max = kite_plane_induction_params['mu_end_by_path']
    psi_grid_min = psi0_base - np.pi / float(number_of_kites) + float(
        kdx) * 2. * np.pi / float(number_of_kites)
    psi_grid_max = psi0_base + np.pi / float(number_of_kites) + float(
        kdx) * 2. * np.pi / float(number_of_kites)

    # define mu with respect to kite mid-span radius
    mu_grid_points = np.linspace(mu_grid_min,
                                 mu_grid_max,
                                 verification_points,
                                 endpoint=True)
    length_mu = mu_grid_points.shape[0]

    beta = np.linspace(0., np.pi / 2, half_points)
    cos_front = 0.5 * (1. - np.cos(beta))
    cos_back = -1. * cos_front[::-1]
    psi_grid_unscaled = cas.vertcat(cos_back, cos_front) + 0.5
    psi_grid_points_cas = psi_grid_unscaled * (psi_grid_max -
                                               psi_grid_min) + psi_grid_min

    psi_grid_points_np = np.array(psi_grid_points_cas)
    psi_grid_points_recenter = np.deg2rad(np.rad2deg(psi_grid_points_np))
    psi_grid_points = np.unique(psi_grid_points_recenter)

    length_psi = psi_grid_points.shape[0]

    # reserve mesh space
    y_matr = np.ones((length_psi, length_mu))
    z_matr = np.ones((length_psi, length_mu))
    a_matr = np.ones((length_psi, length_mu))

    for mdx in range(length_mu):
        mu_val = mu_grid_points[mdx]

        for pdx in range(length_psi):
            psi_val = psi_grid_points[pdx]

            r_val = mu_val * radius

            ehat_radial = vect_op.zhat_np() * cas.cos(
                psi_val) - vect_op.yhat_np() * cas.sin(psi_val)
            added = r_val * ehat_radial
            x_obs = center + added

            unscaled = mu_val * ehat_radial

            a_ind = float(
                vortex_flow.get_induction_factor_at_observer(
                    plot_dict['options']['model'],
                    filament_list,
                    x_obs,
                    u_zero,
                    n_hat=vect_op.xhat()))

            unscaled_y_val = float(cas.mtimes(unscaled.T, vect_op.yhat_np()))
            unscaled_z_val = float(cas.mtimes(unscaled.T, vect_op.zhat_np()))

            y_matr[pdx, mdx] = unscaled_y_val
            z_matr[pdx, mdx] = unscaled_z_val
            a_matr[pdx, mdx] = a_ind

    y_list = np.array(cas.reshape(y_matr, (length_psi * length_mu, 1)))
    z_list = np.array(cas.reshape(z_matr, (length_psi * length_mu, 1)))

    return y_matr, z_matr, a_matr, y_list, z_list
Exemplo n.º 28
0
def get_LL_matrix_var(variables, parent, label):
    LL_var = get_LL_var(variables, parent, label)
    LL_matr = cas.reshape(LL_var, (3, 3))

    return LL_matr
Exemplo n.º 29
0
def get_outputs(options, atmos, wind, variables, outputs, parameters,
                architecture):
    parent_map = architecture.parent_map
    kite_nodes = architecture.kite_nodes

    xd = variables['xd']
    u = variables['u']

    elevation_angle = indicators.get_elevation_angle(xd)

    for n in kite_nodes:

        parent = parent_map[n]

        # get relevant variables for kite n
        q = xd['q' + str(n) + str(parent)]
        dq = xd['dq' + str(n) + str(parent)]

        r = cas.reshape(xd['r' + str(n) + str(parent)], (3, 3))
        ehat_span = r[:, 1]
        ehat_chord = r[:, 0]

        # wind parameters
        rho_infty = atmos.get_density(q[2])
        uw_infty = wind.get_velocity(q[2])

        # apparent air velocity
        if options['induction_model'] == 'actuator':
            ua = actuator_disk_flow.get_kite_effective_velocity(
                options, variables, wind, n, parent, architecture)
        else:
            ua = uw_infty - dq

        # relative air speed
        norm_ua_squared = cas.mtimes(ua.T, ua)
        ua_norm = norm_ua_squared**0.5

        # angle of attack and sideslip angle
        alpha = indicators.get_alpha(ua, r)
        beta = indicators.get_beta(ua, r)

        if int(options['surface_control']) == 0:
            delta = u['delta' + str(n) + str(parent)]
            omega = xd['omega' + str(n) + str(parent)]
            [CF, CM] = stability_derivatives.stability_derivatives(
                options, alpha, beta, ua, omega, delta, parameters)
        elif int(options['surface_control']) == 1:
            delta = xd['delta' + str(n) + str(parent)]
            omega = xd['omega' + str(n) + str(parent)]
            [CF, CM] = stability_derivatives.stability_derivatives(
                options, alpha, beta, ua, omega, delta, parameters)
        else:
            raise ValueError('unsupported surface_control chosen: %i',
                             options['surface_control'])

        # body-_frameforcecomponents
        # notice that these are unusual because an apparent wind reference coordinate system is in use.
        # see below (get_coeffs_from_control_surfaces) for information
        CA = CF[0]
        CY = CF[1]
        CN = CF[2]

        Cl = CM[0]
        Cm = CM[1]
        Cn = CM[2]

        dynamic_pressure = 1. / 2. * rho_infty * norm_ua_squared
        planform_area = parameters['theta0', 'geometry', 's_ref']
        ftilde_aero = cas.mtimes(r, CF)
        f_aero = dynamic_pressure * planform_area * ftilde_aero

        ehat_drag = vect_op.normalize(ua)
        f_drag = cas.mtimes(cas.mtimes(f_aero.T, ehat_drag), ehat_drag)

        ehat_lift = vect_op.normed_cross(ua, ehat_span)
        f_lift = cas.mtimes(cas.mtimes(f_aero.T, ehat_lift), ehat_lift)

        f_side = f_aero - f_drag - f_lift

        drag_cross_lift = indicators.convert_from_body_to_wind_axes(
            alpha, beta, CF)
        CD = drag_cross_lift[0]
        CS = drag_cross_lift[1]
        CL = drag_cross_lift[2]

        b_ref = parameters['theta0', 'geometry', 'b_ref']
        c_ref = parameters['theta0', 'geometry', 'c_ref']

        reference_lengths = cas.diag(cas.vertcat(b_ref, c_ref, b_ref))
        m_aero = dynamic_pressure * planform_area * cas.mtimes(
            reference_lengths, CM)

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

        outputs = indicators.collect_kite_aerodynamics_outputs(
            options, atmos, ua, ua_norm, aero_coefficients, f_aero, f_lift,
            f_drag, f_side, m_aero, ehat_chord, ehat_span, r, q, n, outputs,
            parameters)
        outputs = indicators.collect_environmental_outputs(
            atmos, wind, q, n, outputs)
        outputs = indicators.collect_aero_validity_outputs(
            options, xd, ua, n, parent, outputs, parameters)
        outputs = indicators.collect_local_performance_outputs(
            options, atmos, wind, variables, CL, CD, elevation_angle, ua, n,
            parent, outputs, parameters)
        outputs = indicators.collect_power_balance_outputs(
            variables, n, outputs, architecture)

    return outputs
Exemplo n.º 30
0
def write_data_row(pcdw, plot_dict, write_csv_dict, tgrid_ip, k,
                   rotation_representation):
    """
    Write one row of data into the .csv file
    :param pcdw: dictWriter object
    :param plot_dict: dictionary containing trial data
    :param write_csv_dict: csv helper dict used to write the trial data into the .csv
    :param k: time step in trajectory
    :return: None
    """

    # loop over variables
    for variable_type in ['xd', 'xa', 'xl', 'u', 'outputs']:
        for variable in list(plot_dict[variable_type].keys()):

            # check whether sub_variables exist
            if type(plot_dict[variable_type][variable]) == dict:
                for sub_variable in list(
                        plot_dict[variable_type][variable].keys()):
                    var = plot_dict[variable_type][variable][sub_variable]
                    variable_length = len(var)
                    for index in range(variable_length):
                        write_csv_dict[variable_type + '_' + variable + '_' +
                                       sub_variable + '_' + str(index)] = str(
                                           var[index][k])

            # continue if no sub_variables exist
            else:

                # convert rotations from dcm to euler
                if variable[0] == 'r' and rotation_representation == 'euler':
                    dcm = []
                    for i in range(9):
                        dcm = cas.vertcat(
                            dcm, plot_dict[variable_type][variable][i][k])

                    var = vect_op.rotationMatrixToEulerAngles(
                        cas.reshape(dcm, 3, 3))

                    for index in range(3):
                        write_csv_dict[variable_type + '_' + variable + '_' +
                                       str(index)] = str(var[index])
                elif rotation_representation not in ['euler', 'dcm']:
                    awelogger.logger.error(
                        'Error: Only euler angles and direct cosine matrix supported.'
                    )
                else:
                    var = plot_dict[variable_type][variable]
                    variable_length = len(var)
                    for index in range(variable_length):
                        write_csv_dict[variable_type + '_' + variable + '_' +
                                       str(index)] = str(var[index][k])

    write_csv_dict['time'] = tgrid_ip[k]

    parent_map = plot_dict['architecture'].parent_map
    if k < plot_dict['architecture'].number_of_nodes - 1:
        node = list(parent_map.keys())[k]
        write_csv_dict['nodes'] = str(node)
        write_csv_dict['parent'] = str(parent_map[node])
        if k < len(plot_dict['architecture'].kite_nodes):
            write_csv_dict['kites'] = plot_dict['architecture'].kite_nodes[k]
        else:
            write_csv_dict['kites'] = None
    else:
        write_csv_dict['nodes'] = None
        write_csv_dict['parent'] = None
        write_csv_dict['kites'] = None

    write_csv_dict['cross_tether'] = int(
        plot_dict['options']['user_options']['system_model']['cross_tether'])

    # write out sorted row
    ordered_dict = collections.OrderedDict(
        sorted(list(write_csv_dict.items()), key=lambda t: t[0]))
    pcdw.writerow(ordered_dict)

    return None