Ejemplo n.º 1
0
def initial_guess_actuator_xd(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)

    dict = {}
    dict['a'] = cas.DM(init_options['xd']['a'])
    dict['asin'] = cas.DM(0.)
    dict['acos'] = cas.DM(0.)
    dict['ct'] = 4. * dict['a'] * (1. - dict['a'])
    dict['bar_varrho'] = cas.DM(1.)

    var_type = 'xd'
    for name in struct_op.subkeys(model.variables, var_type):
        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
Ejemplo n.º 2
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
Ejemplo n.º 3
0
def collect_inputs(alpha, beta, airspeed, omega, delta, parameters,
                   named_frame):

    # delta:
    # aileron left-right [right teu+, rad], ... positive delta a -> negative roll
    # elevator [ted+, rad],                 ... positive delta e -> negative pitch
    # rudder [tel+, rad])                   ... positive delta r -> positive yaw
    deltaa = delta[0]
    deltae = delta[1]
    deltar = delta[2]

    p, q, r = get_p_q_r(airspeed, omega, parameters, named_frame)

    inputs = {}
    inputs['0'] = cas.DM(1.)
    inputs['alpha'] = alpha
    inputs['beta'] = beta
    inputs['p'] = p
    inputs['q'] = q
    inputs['r'] = r
    inputs['deltaa'] = deltaa
    inputs['deltae'] = deltae
    inputs['deltar'] = deltar

    for combi_1 in ['alpha', 'beta']:
        for combi_2 in ['deltaa', 'deltae', 'deltar']:
            inputs[combi_1 + '_' + combi_2] = inputs[combi_1] * inputs[combi_2]

    return inputs
Ejemplo n.º 4
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.º 5
0
def summation_check_on_potential_and_kinetic_power(trial, thresh, results):

    types = ['pot', 'kin']

    kin_comp = np.array(trial.visualization.plot_dict['outputs']
                        ['power_balance_comparison']['kinetic'][0])
    pot_comp = np.array(trial.visualization.plot_dict['outputs']
                        ['power_balance_comparison']['potential'][0])
    comp_timeseries = {'pot': pot_comp, 'kin': kin_comp}

    # extract info
    tgrid = trial.visualization.plot_dict['time_grids']['ip']
    power_balance = trial.visualization.plot_dict['outputs']['power_balance']

    for type in types:
        sum_timeseries = np.zeros(tgrid.shape)
        for keyname in list(power_balance.keys()):
            if type in keyname:
                timeseries = power_balance[keyname][0]
                sum_timeseries += timeseries

        difference = cas.DM(sum_timeseries - comp_timeseries[type])

        error = float(cas.mtimes(difference.T, difference))

        if error > thresh:
            awelogger.logger.warning(
                'some of the power based on ' + type +
                '. energy must have gotten lost, since a summation check fails. Considering trial '
                + trial.name + ' with ' + str(error) + ' > ' + str(thresh))
            results['power_summation_check_' + type] = False
        else:
            results['power_summation_check_' + type] = True

    return results
Ejemplo n.º 6
0
def add_groundstation_mass(options, node_masses, parameters):
    m_groundstation = parameters['theta0', 'ground_station', 'm_gen']
    node_masses['groundstation'] += m_groundstation
    if not options['ground_station']['in_lag_dyn']:
        node_masses['groundstation'] = cas.DM(0.)

    print("node_masses['groundstation']")
    print(node_masses['groundstation'])
    return node_masses
Ejemplo n.º 7
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
Ejemplo n.º 8
0
    def get_temperature(self, zz):
        params = self.__params.prefix['theta0', 'atmosphere']
        options = self.__options
        if options['model'] == 'isa':
            t = params['t_ref'] - params['gamma_air'] * zz
        elif options['model'] == 'windshear':
            t = params['t_ref'] - params['gamma_air'] * zz
        elif options['model'] == 'log_wind':
            t = cas.DM(params['t_ref'])
        elif options['model'] == 'uniform':
            t = cas.DM(params['t_ref'])
        elif options['model'] == 'datafile':
            t = params['t_ref'] - params['gamma_air'] * zz
        else:
            raise ValueError(
                'failure: unsupported atmospheric option chosen: %s',
                options['model'])

        return t
Ejemplo n.º 9
0
    def get_density(self, zz):
        params = self.__params.prefix['theta0', 'atmosphere']
        options = self.__options
        if options['model'] == 'isa':
            t = self.get_temperature(zz)
            rho = params['rho_ref'] * (t / params['t_ref'])**(
                params['g'] / params['gamma_air'] / params['r'] - 1.0)
        elif options['model'] == 'log_wind':
            rho = cas.DM(params['rho_ref'])
        elif options['model'] == 'uniform':
            rho = cas.DM(1.)
        elif options['model'] == 'datafile':
            rho = self.get_pressure(zz) / \
                params['r'] / self.get_temperature(zz)
        else:
            raise ValueError(
                'failure: unsupported atmospheric option chosen: %s',
                options['model'])

        return rho
Ejemplo n.º 10
0
    def get_pressure(self, zz):
        params = self.__params.prefix['theta0', 'atmosphere']
        options = self.__options
        if options['model'] == 'isa':
            p = self.get_density(zz) * \
                params['r'] * self.get_temperature(zz)
        elif options['model'] == 'log_wind':
            p = cas.DM(params['p_ref'])
        elif options['model'] == 'uniform':
            p = cas.DM(params['p_ref'])
        elif options['model'] == 'datafile':
            p = cas.DM(
                params['p_ref']
            )  # constant value for now, could be computed with the files..
            # raise ValueError('failure: unsupported atmospheric option chosen: %s', options['model'])
        else:
            raise ValueError(
                'failure: unsupported atmospheric option chosen: %s',
                options['model'])

        return p
Ejemplo n.º 11
0
    def get_viscosity(self, zz):
        params = self.__params.prefix['theta0', 'atmosphere']
        options = self.__options
        if options['model'] == 'isa':
            mu = params['mu_ref'] * (
                params['t_ref'] + params['c_sutherland']
            ) / (self.get_temperature(zz) + params['c_sutherland']) * (
                self.get_temperature(zz) / params['t_ref'])**(3.0 / 2.0)
        elif options['model'] == 'log_wind':
            mu = cas.DM(params['mu_ref'])
        elif options['model'] == 'uniform':
            mu = cas.DM(params['mu_ref'])
        elif options['model'] == 'datafile':
            mu = params['mu_ref'] * (
                params['t_ref'] + params['c_sutherland']
            ) / (self.get_temperature(zz) + params['c_sutherland']) * (
                self.get_temperature(zz) / params['t_ref'])**(3.0 / 2.0)
        else:
            raise ValueError(
                'failure: unsupported atmospheric option chosen: %s',
                options['model'])

        return mu
Ejemplo n.º 12
0
def add_groundstation_kinetic(options, parameters, node_masses_si, variables_si, outputs):

    # = 1/2 i omega_gen^2, with no-slip condition
    # add mass of first half of main tether, and the mass of wound tether.

    total_groundstation_mass = node_masses_si['groundstation']
    tether_ground_station_mass = cas.DM(0.)

    if options['tether']['use_wound_tether']:
        total_groundstation_mass += node_masses_si['m00']
        tether_ground_station_mass = node_masses_si['m00']

    dq10 = variables_si['xd']['dq10']
    q10 = variables_si['xd']['q10']
    l_t = variables_si['xd']['l_t']

    speed_groundstation = cas.mtimes(dq10.T, q10) / l_t

#if (not g_s_in_lagr_dyn) and (use_generator_model)
    if not options['ground_station']['in_lag_dyn'] and options['generator']['type']:
        e_kinetic = cas.DM(0.)

    elif options['ground_station']['in_lag_dyn'] and options['ground_station']['name']:
        radius_winch = parameters['theta0','ground_station','r_gen']
        j_gen = parameters['theta0','ground_station','j_gen']
        j_winch = parameters['theta0','ground_station','j_winch']
        e_kinetic = 0.5 * (j_gen + j_winch) * speed_groundstation ** 2 * 1/radius_winch**2
        e_kinetic += 0.5 * tether_ground_station_mass * speed_groundstation ** 2

    else:
        e_kinetic = 0.25 * total_groundstation_mass * speed_groundstation ** 2.

    print("e_kinetic")
    print(e_kinetic)
    outputs['e_kinetic']['groundstation'] = e_kinetic

    return outputs
Ejemplo n.º 13
0
def make_side_plot(ax,
                   vertically_stacked_array,
                   side,
                   plot_color,
                   plot_marker=' ',
                   label=None,
                   alpha=1,
                   linestyle='-'):
    vsa = np.array(cas.DM(vertically_stacked_array))

    if vsa.shape[0] == 3 and (not vsa.shape[1] == 3):
        vsa = vsa.T

    if side == 'isometric':
        ax.plot(vsa[:, 0],
                vsa[:, 1],
                zs=vsa[:, 2],
                color=plot_color,
                marker=plot_marker,
                label=label,
                alpha=alpha,
                linestyle=linestyle)
    else:
        side_num = ''
        for sdx in side:
            if sdx == 'x':
                side_num += '0'
            elif sdx == 'y':
                side_num += '1'
            elif sdx == 'z':
                side_num += '2'

        idx = int(side_num[0])
        jdx = int(side_num[1])

        ax.plot(vsa[:, idx],
                vsa[:, jdx],
                color=plot_color,
                marker=plot_marker,
                label=label,
                alpha=alpha,
                linestyle=linestyle)

    return None
Ejemplo n.º 14
0
def var_scaled_to_si(var_type, var_name, var_scaled, 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_scaled
            else:
                return var_scaled * scale
        else:
            matrix_factor = cas.diag(scale)
            return cas.mtimes(matrix_factor, var_scaled)

    else:
        return var_scaled
Ejemplo n.º 15
0
def guess_values_at_time(t, init_options, model, formulation, tf_guess,
                         ntp_dict):
    n_min_0 = ntp_dict['n_min_0']
    d_min_0 = ntp_dict['d_min_0']
    n_min_f = ntp_dict['n_min_f']
    d_min_f = ntp_dict['d_min_f']

    l_s = model.variable_bounds['theta']['l_s']['lb'] * init_options['theta'][
        'l_s']
    l_i = model.variable_bounds['theta']['l_i']['lb'] * init_options['theta'][
        'l_i']

    ret = {}
    for name in struct_op.subkeys(model.variables, 'xd'):
        ret[name] = 0.0

    parent_map = model.architecture.parent_map
    parent_map[0] = -1
    number_of_nodes = model.architecture.number_of_nodes
    V_0 = formulation.xi_dict['V_pickle_initial']
    V_f = formulation.xi_dict['V_pickle_terminal']
    q_n = {}
    q_0 = {}
    q_f = {}
    phi_0 = {}
    phi_f = {}
    phi_n = {}
    theta_0 = {}
    theta_f = {}
    theta_n = {}
    dphi_n = {}
    dtheta_n = {}
    x_t_0 = {}
    x_t_f = {}
    dq_n = {}

    dl_0 = formulation.xi_dict['V_pickle_initial'][
        'coll_var', n_min_0, d_min_0, 'xd', 'dl_t'] * init_options['xd']['l_t']
    l_0 = formulation.xi_dict['V_pickle_initial'][
        'coll_var', n_min_0, d_min_0, 'xd', 'l_t'] * init_options['xd']['l_t']
    l_f = formulation.xi_dict['V_pickle_terminal'][
        'coll_var', n_min_f, d_min_f, 'xd', 'l_t'] * init_options['xd']['l_t']
    dl_f = formulation.xi_dict['V_pickle_terminal'][
        'coll_var', n_min_f, d_min_f, 'xd', 'dl_t'] * init_options['xd']['l_t']

    c1 = (l_f - l_0 - 0.5 * tf_guess * dl_0 -
          0.5 * tf_guess * dl_f) / (1. / 6. * tf_guess**3 - 0.25 * tf_guess**3)
    c2 = (dl_f - dl_0 - 0.5 * tf_guess**2 * c1) / tf_guess
    c3 = dl_0
    c4 = l_0
    l_t = 1. / 6. * t**3 * c1 + 0.5 * t**2 * c2 + t * c3 + c4
    dl_t = 0.5 * t**2 * c1 + t * c2 + c3
    ddl_t = t**2 * c2 + t * c1

    q_0['q0-1'] = cas.DM([0.0, 0.0, 0.0])
    q_f['q0-1'] = cas.DM([0.0, 0.0, 0.0])

    for node in range(1, number_of_nodes):
        parent = parent_map[node]
        node_str = 'q' + str(node) + str(parent)
        q_0[node_str] = V_0['coll_var', n_min_0, d_min_0, 'xd', node_str]
        q_f[node_str] = V_f['coll_var', n_min_f, d_min_f, 'xd', node_str]

    for node in range(1, number_of_nodes):
        parent = parent_map[node]
        grandparent = parent_map[parent]
        tether_str = 'q' + str(node) + str(parent)
        x_t_0[tether_str] = vect_op.normalize(
            q_0['q' + str(node) + str(parent)] -
            q_0['q' + str(parent) + str(grandparent)])
        x_t_f[tether_str] = vect_op.normalize(
            q_f['q' + str(node) + str(parent)] -
            q_f['q' + str(parent) + str(grandparent)])

    vec_plus = vect_op.normalize(q_0['q31'] - q_0['q21'])
    vec_par = vect_op.normalize(x_t_0['q21'] * l_s + 0.5 *
                                (q_0['q31'] - q_0['q21']))
    vec_orth = vect_op.normed_cross(vec_par, vec_plus)

    for node in range(2, number_of_nodes):
        x_0 = cas.mtimes(vec_par.T, l_s * x_t_0['q' + str(node) + str(parent)])
        y_0 = cas.mtimes(vec_plus.T,
                         l_s * x_t_0['q' + str(node) + str(parent)])
        z_0 = cas.mtimes(vec_orth.T,
                         l_s * x_t_0['q' + str(node) + str(parent)])
        theta_0['q' + str(node) + str(parent)] = np.arcsin(z_0 / l_s)
        phi_0['q' + str(node) + str(parent)] = np.arctan2(y_0, x_0)
        x_f = cas.mtimes(vec_par.T, l_s * x_t_f['q' + str(node) + str(parent)])
        y_f = cas.mtimes(vec_plus.T,
                         l_s * x_t_f['q' + str(node) + str(parent)])
        z_f = cas.mtimes(vec_orth.T,
                         l_s * x_t_f['q' + str(node) + str(parent)])
        theta_f['q' + str(node) + str(parent)] = np.arcsin(z_f / l_s)
        phi_f['q' + str(node) + str(parent)] = np.arctan2(y_f, x_f)

    for node in range(2, number_of_nodes):
        parent = parent_map[node]
        phi_n['q' + str(node) + str(parent)] = phi_0['q' + str(node) + str(
            parent)] + t / tf_guess * (phi_f['q' + str(node) + str(parent)] -
                                       phi_0['q' + str(node) + str(parent)])
        dphi_n['q' + str(node) + str(parent)] = 1. / tf_guess * (
            phi_f['q' + str(node) + str(parent)] -
            phi_0['q' + str(node) + str(parent)])
        theta_n['q' + str(node) + str(parent)] = theta_0['q' + str(node) + str(
            parent)] + t / tf_guess * (theta_f['q' + str(node) + str(parent)] -
                                       theta_0['q' + str(node) + str(parent)])
        dtheta_n['q' + str(node) + str(parent)] = 1. / tf_guess * (
            theta_f['q' + str(node) + str(parent)] -
            theta_0['q' + str(node) + str(parent)])

    a = cas.mtimes((q_f['q10'] - q_0['q10']).T, (q_f['q10'] - q_0['q10']))
    b = 2 * cas.mtimes(q_0['q10'].T, (q_f['q10'] - q_0['q10']))
    c = cas.mtimes(q_0['q10'].T, q_0['q10']) - l_t**2
    dc = -2 * l_t * dl_t
    D = b**2 - 4 * a * c
    dD = -4 * a * dc
    x1 = (-b + np.sqrt(D)) / (2 * a)
    x2 = (-b - np.sqrt(D)) / (2 * a)
    s = x2
    ds = -1. / (2 * a) * 1. / (2 * np.sqrt(D)) * dD
    e_t = 1. / l_t * (q_0['q10'] + s * (q_f['q10'] - q_0['q10']))
    de_t = 1. / l_t * (ds * (q_f['q10'] - q_0['q10'])) - 1. / l_t**2 * dl_t * (
        q_0['q10'] + s * (q_f['q10'] - q_0['q10']))
    q_n['q10'] = l_t * e_t
    dq_n['q10'] = dl_t * e_t + l_t * de_t

    for node in range(2, number_of_nodes):
        parent = parent_map[node]
        nstr = 'q' + str(node) + str(parent)
        q_n[nstr] = q_n['q10'] + (
            np.sin(phi_n[nstr]) * np.cos(theta_n[nstr]) * vec_plus +
            np.cos(phi_n[nstr]) * np.cos(theta_n[nstr]) * vec_par +
            np.sin(theta_n[nstr]) * vec_orth) * l_s
        dq_n[nstr] = dq_n['q10'] + (
            -np.cos(phi_n[nstr]) * np.sin(theta_n[nstr]) * dtheta_n[nstr] *
            dphi_n[nstr] * vec_plus + np.sin(phi_n[nstr]) *
            np.sin(theta_n[nstr]) * dtheta_n[nstr] * dphi_n[nstr] * vec_par +
            np.cos(theta_n[nstr]) * dtheta_n[nstr] * vec_orth) * l_s

    for node in range(1, number_of_nodes):
        parent = parent_map[node]
        ret['q' + str(node) + str(parent)] = q_n['q' + str(node) + str(parent)]
        ret['dq' + str(node) + str(parent)] = dq_n['q' + str(node) +
                                                   str(parent)]

    ret['l_t'] = l_t
    ret['dl_t'] = dl_t

    return ret
Ejemplo n.º 16
0
def from_control_to_body(vector):
    rot = cas.diag(cas.DM([-1., 1., -1.]))
    transformed = cas.mtimes(rot, vector)
    return transformed
Ejemplo n.º 17
0
def guess_values_at_time(t, init_options, model, formulation, tf_guess, ntp_dict):
    n_min = ntp_dict['n_min']
    d_min = ntp_dict['d_min']

    l_s = model.variable_bounds['theta']['l_s']['lb'] * init_options['theta']['l_s']
    l_i = model.variable_bounds['theta']['l_i']['lb'] * init_options['theta']['l_i']

    ret = {}
    for name in struct_op.subkeys(model.variables, 'xd'):
        ret[name] = 0.0

    kite_nodes = model.architecture.kite_nodes
    parent_map = model.architecture.parent_map
    parent_map[0] = -1
    number_of_nodes = model.architecture.number_of_nodes
    V_0 = formulation.xi_dict['V_pickle_initial']
    q_n = {}
    q_0 = {}
    x_t = {}
    dq_n = {}

    q_0['q0-1'] = cas.DM([0.0, 0.0, 0.0])
    for node in range(1, number_of_nodes):
        parent = parent_map[node]
        node_str = 'q' + str(node) + str(parent)
        q_0[node_str] = V_0['coll_var', n_min, d_min, 'xd', node_str]

    for node in range(1, number_of_nodes):
        parent = parent_map[node]
        grandparent = parent_map[parent]
        tether_str = 't' + str(node) + str(parent)
        x_t[tether_str] = vect_op.normalize(
            q_0['q' + str(node) + str(parent)] - q_0['q' + str(parent) + str(grandparent)])

    dl_0 = formulation.xi_dict['V_pickle_initial']['coll_var', n_min, d_min, 'xd', 'dl_t'] * init_options['xd']['l_t']
    l_0 = formulation.xi_dict['V_pickle_initial']['coll_var', n_min, d_min, 'xd', 'l_t'] * init_options['xd']['l_t']
    l_f = model.variable_bounds['xd']['q10']['lb'][2] / x_t['t10'][2]
    dl_f = 0

    c1 = (l_f - l_0 - 0.5 * tf_guess * dl_0 - 0.5 * tf_guess * dl_f) / (1. / 6. * tf_guess ** 3 - 0.25 * tf_guess ** 3)
    c2 = (dl_f - dl_0 - 0.5 * tf_guess ** 2 * c1) / tf_guess
    c3 = dl_0
    c4 = l_0
    l_t = 1. / 6. * t ** 3 * c1 + 0.5 * t ** 2 * c2 + t * c3 + c4
    dl_t = 0.5 * t ** 2 * c1 + t * c2 + c3
    ddl_t = t ** 2 * c2 + t * c1

    q_n['q0-1'] = cas.DM([0.0, 0.0, 0.0])
    for node in range(1, number_of_nodes):
        parent = parent_map[node]
        grandparent = parent_map[parent]
        if node == 1:
            seg_length = l_t
        elif node in kite_nodes:
            seg_length = l_s
        else:
            seg_length = l_i
        q_n['q' + str(node) + str(parent)] = x_t['t' + str(node) + str(parent)] * seg_length + q_n[
            'q' + str(parent) + str(grandparent)]
        if node == 1:
            dq_n['dq' + str(node) + str(parent)] = dl_t * x_t['t' + str(node) + str(parent)]
        else:
            dq_n['dq' + str(node) + str(parent)] = dq_n['dq10']

    for node in range(1, number_of_nodes):
        parent = parent_map[node]
        ret['q' + str(node) + str(parent)] = q_n['q' + str(node) + str(parent)]
        ret['dq' + str(node) + str(parent)] = dq_n['dq' + str(node) + str(parent)]

    ret['l_t'] = l_t
    ret['dl_t'] = dl_t
    # ret['ddl_t'] = ddl_t

    return ret
Ejemplo n.º 18
0
def add_groundstation_potential(outputs):
    # the winch is at ground level
    e_potential = cas.DM(0.)
    outputs['e_potential']['groundstation'] = e_potential
    return outputs
Ejemplo n.º 19
0
def get_outputs(options, atmos, wind, variables, outputs, parameters,
                architecture):
    parent_map = architecture.parent_map
    kite_nodes = architecture.kite_nodes

    xd = variables['xd']

    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)]
        coeff = xd['coeff' + str(n) + str(parent)]

        # 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
        ua_norm = vect_op.smooth_norm(ua, epsilon=1e-8)
        # ua_norm = mtimes(ua.T, ua) ** 0.5

        # in kite body:
        if parent > 0:
            grandparent = parent_map[parent]
            qparent = xd['q' + str(parent) + str(grandparent)]
        else:
            qparent = np.array([0., 0., 0.])

        ehat_r = (q - qparent) / vect_op.norm(q - qparent)
        ehat_t = vect_op.normed_cross(ua, ehat_r)
        ehat_s = vect_op.normed_cross(ehat_t, ua)

        # roll angle
        psi = coeff[1]

        ehat_l = cas.cos(psi) * ehat_s + cas.sin(psi) * ehat_t
        ehat_span = cas.cos(psi) * ehat_t - cas.sin(psi) * ehat_s
        ehat_chord = ua / ua_norm

        # implicit direct cosine matrix (for plotting only)
        r = cas.horzcat(ehat_chord, ehat_span, ehat_l)

        # lift and drag coefficients
        CL = coeff[0]
        CD = parameters['theta0', 'aero', 'CD0'] + 0.02 * CL**2

        # lift and drag force
        f_lift = CL * 1. / 2. * rho_infty * cas.mtimes(
            ua.T, ua) * parameters['theta0', 'geometry', 's_ref'] * ehat_l
        f_drag = CD * 1. / 2. * rho_infty * ua_norm * parameters['theta0',
                                                                 'geometry',
                                                                 's_ref'] * ua
        f_side = cas.DM(np.zeros((3, 1)))

        f_aero = f_lift + f_drag
        m_aero = cas.DM(np.zeros((3, 1)))

        CA = CD
        CN = CL
        CY = cas.DM(0.)

        aero_coefficients = {}
        aero_coefficients['CD'] = CD
        aero_coefficients['CL'] = CL
        aero_coefficients['CA'] = CA
        aero_coefficients['CN'] = CN
        aero_coefficients['CY'] = CY

        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
Ejemplo n.º 20
0
def guess_wake_gamma_val(init_options):
    # already scaled!
    gamma = cas.DM(1.)

    return gamma
Ejemplo n.º 21
0
def test(gamma_scale=1.):

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

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

    kite = architecture.kite_nodes[0]

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

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

    test_list = get_list(options, variables, architecture)

    filaments = test_list.shape[1]

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

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

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

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

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

            raise Exception(message)

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

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

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

            raise Exception(message)

    return test_list
Ejemplo n.º 22
0
def get_winch_cstr(options, atmos, wind, variables_si, parameters, outputs,
                   architecture):

    cstr_list = mdl_constraint.MdlConstraintList()

    t_em = cas.DM(0.)

    if options['generator']['type'] != None and options['generator'][
            'type'] != 'experimental':
        if not options['tether']['use_wound_tether']:
            raise ValueError(
                'Invalid user_options: use_wound_tether = False, when you use a generator model with ODEs it have to be True'
            )
        if options['ground_station']['in_lag_dyn']:
            raise ValueError(
                'Invalid user_options: in_lag_dyn = True, when you use a generator model with ODEs it have to be False or when you dont want to use the default winch'
            )

        t_em = t_em_ode(options, variables_si, outputs, parameters,
                        architecture)

    if not options['ground_station']['in_lag_dyn']:

        radius_winch = parameters['theta0', 'ground_station',
                                  'r_gen']  #not optinal
        j_gen = parameters['theta0', 'ground_station', 'j_gen']
        j_winch = parameters['theta0', 'ground_station', 'j_winch']
        f_winch = parameters['theta0', 'ground_station', 'f_winch']
        l_t_full = variables_si['theta']['l_t_full']
        phi = (l_t_full - variables_si['xd']['l_t']) / radius_winch
        omega = -variables_si['xd']['dl_t'] / radius_winch
        domega = -variables_si['xddot']['ddl_t'] / radius_winch
        t_tether = -variables_si['xa']['lambda10'] * variables_si['xd'][
            'l_t'] * radius_winch
        t_frict = -f_winch * omega
        t_inertia = j_winch * domega
        t_inertia += variables_si['theta'][
            'diam_t']**2 / 4 * np.pi * parameters['theta0', 'tether',
                                                  'rho'] * radius_winch**3 * (
                                                      omega * omega +
                                                      domega * phi)  #

        rhs = t_tether + t_em + t_frict
        lhs = t_inertia

        omega = variables_si['xd']['dl_t'] / radius_winch
        domega = variables_si['xddot']['ddl_t'] / radius_winch
        phi = (l_t_full - variables_si['xd']['l_t']) / radius_winch

        rhs = (j_gen + j_winch) * variables_si['xddot']['ddl_t'] / radius_winch
        rhs += variables_si['theta']['diam_t']**2 / 4 * np.pi * parameters[
            'theta0', 'tether',
            'rho'] * radius_winch**3 * (-omega * omega + domega * phi)
        lhs = variables_si['xa']['lambda10'] * variables_si['xd'][
            'l_t'] * radius_winch - t_em

        if options['generator']['gear_train']['used']:
            j_gen = parameters['theta0', 'ground_station', 'j_gen']
            j_winch = parameters['theta0', 'ground_station',
                                 'j_winch']  #normaly rigid body
            f_gen = parameters['theta0', 'ground_station', 'f_gen']

            k = variables_si['theta']['k_gear']

            t_win = j_winch * variables_si['xddot'][
                'ddl_t'] / radius_winch + options['scaling']['theta'][
                    'diam_t']**2 / 4 * np.pi * parameters[
                        'theta0', 'tether', 'rho'] * radius_winch**3 * (
                            -omega * omega + domega * phi)  #
            j_gen *= k**2
            t_tether = -variables_si['xa']['lambda10'] * variables_si['xd'][
                'l_t'] * radius_winch

            t_gen = j_gen * variables_si['xddot']['ddl_t'] / radius_winch
            lhs = -t_gen - t_win
            rhs = t_tether + k * t_em  #+ omega*(f_winch + f_gen*k**2)

        if options['generator']['gear_train']['used']:

            k = variables_si['theta']['k_gear']
            #            dk  = variables_si['xddot']['dk_gear']

            #           dk_ineq         = dk

            #          dk_ineq_cstr    = cstr_op.Constraint(expr=dk_ineq, name='dk_ineq', cstr_type='eq')
            #         cstr_list.append(dk_ineq_cstr)
            #
            len_zstl = 0.1
            delta_r = 0.05
            rho_zstl = 2700
            j_zstl = np.pi * len_zstl * rho_zstl * (
                -3 * k * radius_winch**2 * delta_r**2 +
                2 * k**2 * delta_r**3 * radius_winch +
                2 * delta_r * radius_winch**3 - 1 / 2 * k**3 * delta_r**4)

            j_gen_zstl = k**3 * j_gen + j_zstl

            t_tether = variables_si['xa']['lambda10'] * variables_si['xd'][
                'l_t'] * radius_winch

            t_angular_momentum = (j_gen_zstl + k * j_winch) * domega
            t_angular_momentum_tether = k * variables_si['theta'][
                'diam_t']**2 / 4 * np.pi * parameters['theta0', 'tether',
                                                      'rho']
            t_angular_momentum_tether *= radius_winch**3 * (-omega * omega +
                                                            domega * phi)

            rhs = t_angular_momentum + t_angular_momentum_tether
            rhs += omega * (f_winch * k**3)
            lhs = t_tether * k - k**2 * t_em

        if options['generator']['type'] == 'pmsm':
            generator = generator_ode(options, variables_si, outputs,
                                      parameters, architecture)
            cstr_list.append(generator)


#            sign = variables_si['u']['sign']
#            sign_eq = sign**2 - 4*sign + 3
#            sign_ineq = -variables_si['u']['v_sq']/(sign)
#            sign_eq = cstr_op.Constraint(expr=sign_eq, name='sign_eq', cstr_type='eq')
#            cstr_list.append(sign_eq)
#            sign_ineq = cstr_op.Constraint(expr=sign_ineq, name='sign_ineq', cstr_type='ineq')
#            cstr_list.append(sign_ineq)
#sign = p_el_sign(options, variables_si, outputs, parameters, architecture)
#cstr_list.append(sign)

        torque = lhs - rhs

        print("torque")
        print(torque)
        winch_cstr = cstr_op.Constraint(expr=torque,
                                        name='winch',
                                        cstr_type='eq')
        cstr_list.append(winch_cstr)

    return cstr_list