示例#1
0
def collect_local_performance_outputs(options, atmos, wind, variables, CL, CD, elevation_angle, ua, n, parent, outputs,parameters):

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

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

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

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

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

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

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


    return outputs
示例#2
0
文件: frames.py 项目: mg-meth/awebox
def test_transform_from_body():

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

    qx_test = np.random.random() * 1000.
    qy_test = np.random.random() * 1000.
    qz_test = np.random.random() * 1000.

    q_upper = qx_test * xhat + qy_test * yhat + qz_test * zhat
    q_lower = q_upper / 2.

    x_test = np.random.random() * 100.
    y_test = np.random.random() * 100.
    z_test = np.random.random() * 100.
    test_vec = x_test * xhat + y_test * yhat + z_test * zhat
    test_mag = vect_op.norm(test_vec)

    trans_vec = from_body_to_earth(test_vec, q_upper, q_lower)
    trans_mag = vect_op.norm(trans_vec)
    norm_error = vect_op.norm(trans_mag - test_mag)

    reformed_vec = from_earth_to_body(trans_vec, q_upper, q_lower)
    vector_diff = reformed_vec - test_vec
    vector_error = cas.mtimes(vector_diff.T, vector_diff)

    tot_error = norm_error + vector_error
    epsilon = 1.e-12
    if tot_error > epsilon:
        awelogger.logger.error(
            'tether frame transformation test gives error of size: ' +
            str(tot_error))

    return None
示例#3
0
def get_segment_force(diam, q_upper, q_lower, dq_upper, dq_lower, atmos, wind, cd_tether_fun):

    q_average = (q_upper + q_lower) / 2.
    zz = q_average[2]

    uw_average = wind.get_velocity(zz)
    density = atmos.get_density(zz)

    dq_average = (dq_upper + dq_lower) / 2.
    ua = uw_average - dq_average

    ua_norm = vect_op.smooth_norm(ua, 1e-6)
    ehat_ua = vect_op.smooth_normalize(ua, 1e-6)

    tether = q_upper - q_lower

    length = vect_op.norm(tether)
    length_parallel_to_wind = cas.mtimes(tether.T, ehat_ua)
    length_perp_to_wind = (length**2. - length_parallel_to_wind**2.)**0.5

    reynolds = get_reynolds_number(atmos, ua, diam, q_upper, q_lower)
    cd = cd_tether_fun(reynolds)

    drag = cd * 0.5 * density * ua_norm * diam * length_perp_to_wind * ua

    return drag
示例#4
0
def get_loyd_comparison(atmos,
                        wind,
                        xd,
                        n,
                        parent,
                        CL,
                        CD,
                        parameters,
                        elevation_angle=0.):
    # for elevation angle cosine losses see Van der Lind, p. 477, AWE book

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

    epsilon = 1.e-8
    CR = CL * (1. + (CD / (CL + epsilon))**2.)**0.5

    windspeed = vect_op.norm(wind.get_velocity(q[2]))
    power_density = get_power_density(atmos, wind, q[2])

    phf_loyd = perf_op.get_loyd_phf(CL, CD, elevation_angle)

    s_ref = parameters['theta0', 'geometry', 's_ref']
    p_loyd = perf_op.get_loyd_power(power_density, CL, CD, s_ref,
                                    elevation_angle)

    speed_loyd = 2. * CR / 3. / CD * windspeed * np.cos(elevation_angle)

    return [CR, phf_loyd, p_loyd, speed_loyd]
示例#5
0
def get_force_from_u_sym_in_earth_frame(vec_u, options, variables, kite, atmos, wind, architecture, parameters):

    parent = architecture.parent_map[kite]

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

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

    kite_dcm = get_kite_dcm(options, variables, wind, kite, architecture)
    Lhat = kite_dcm[:,2]

    # lift and drag coefficients
    CL = coeff[0]

    CD0 = 0.
    poss_drag_labels_in_order_of_increasing_preference = ['CX', 'CA', 'CD']
    for poss_drag_label in poss_drag_labels_in_order_of_increasing_preference:
        local_parameter_label = '[theta0,aero,' + poss_drag_label + ',0,0]'
        if local_parameter_label in parameters.labels():
            CD0 = vect_op.abs(parameters['theta0', 'aero', poss_drag_label, '0'][0])

    CD = CD0 + CL ** 2 / (np.pi * parameters['theta0', 'geometry', 'ar'])

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

    # lift and drag force
    f_lift = CL * 1. / 2. * rho_infty * cas.mtimes(vec_u.T, vec_u) * s_ref * Lhat
    f_drag = CD * 1. / 2. * rho_infty * vect_op.norm(vec_u) * s_ref * vec_u

    f_aero = f_lift + f_drag

    return f_aero
示例#6
0
文件: segment.py 项目: mg-meth/awebox
def get_kite_only_segment_forces(atmos, outputs, variables, upper_node,
                                 architecture, cd_tether_fun):

    force_lower = cas.DM.zeros((3, 1))
    force_upper = cas.DM.zeros((3, 1))

    if upper_node in architecture.kite_nodes:

        kite = upper_node

        ehat_1 = outputs['aerodynamics']['ehat_chord' + str(kite)]
        ehat_3 = outputs['aerodynamics']['ehat_span' + str(kite)]
        alpha = outputs['aerodynamics']['alpha' + str(kite)]
        d_hat = cas.cos(alpha) * ehat_1 + cas.sin(alpha) * ehat_3

        kite_dyn_pressure = outputs['aerodynamics']['dyn_pressure' + str(kite)]
        q_upper, q_lower, dq_upper, dq_lower = element.get_upper_and_lower_pos_and_vel(
            variables, upper_node, architecture)
        length = vect_op.norm(q_upper - q_lower)
        diam = element.get_element_diameter(variables, upper_node,
                                            architecture)

        air_velocity = outputs['aerodynamics']['air_velocity' + str(kite)]
        re_number = reynolds.get_reynolds_number(atmos, air_velocity, diam,
                                                 q_upper, q_lower)
        cd_tether = cd_tether_fun(re_number)

        d_mag = (1. / 4.) * cd_tether * kite_dyn_pressure * diam * length

        force_upper = d_mag * d_hat

    return force_lower, force_upper
示例#7
0
def get_radius_inequality(model_options, variables, kite, parent, parameters):
    # no projection included...

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

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

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

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

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

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

    inequality = (half_span * den - num) / num_ref

    return inequality
示例#8
0
文件: tools.py 项目: mg-meth/awebox
def get_dependent_rotation_direction_sign(t, init_options, model, node, ret):
    velocity = get_velocity_vector(t, init_options, model, node, ret)
    ehat_normal, ehat_radial, ehat_tangential = get_rotating_reference_frame(
        t, init_options, model, node, ret)
    forwards_speed = cas.mtimes(velocity.T, ehat_tangential)
    forwards_sign = forwards_speed / vect_op.norm(forwards_speed)

    return forwards_sign
示例#9
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
示例#10
0
def collect_environmental_outputs(atmos, wind, q, n, outputs):

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

    outputs['environment']['windspeed' + str(n)] = vect_op.norm(wind.get_velocity(q[2]))
    outputs['environment']['pressure' + str(n)] = atmos.get_pressure(q[2])
    outputs['environment']['temperature' + str(n)] = atmos.get_temperature(q[2])
    outputs['environment']['density' + str(n)] = atmos.get_density(q[2])

    return outputs
示例#11
0
def get_local_wind_reference_frame(init_options):
    u_hat = vect_op.xhat_np()
    n_rot_hat, y_rot_hat, z_rot_hat = tools_init.get_rotor_reference_frame(init_options)

    if vect_op.norm(u_hat - n_rot_hat) < 1.e-5:
        v_hat = y_rot_hat
        w_hat = z_rot_hat

    else:
        w_hat = vect_op.normed_cross(u_hat, n_rot_hat)
        v_hat = vect_op.normed_cross(w_hat, u_hat)
    return u_hat, v_hat, w_hat
示例#12
0
def collect_local_performance_outputs(architecture, atmos, wind, variables,
                                      parameters, base_aerodynamic_quantities,
                                      outputs):

    kite = base_aerodynamic_quantities['kite']
    q = base_aerodynamic_quantities['q']
    airspeed = base_aerodynamic_quantities['airspeed']
    CL = base_aerodynamic_quantities['aero_coefficients']['CL']
    CD = base_aerodynamic_quantities['aero_coefficients']['CD']

    xd = variables['xd']
    elevation_angle = get_elevation_angle(xd)

    parent = architecture.parent_map[kite]

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

    [CR, phf_loyd, p_loyd,
     speed_loyd] = get_loyd_comparison(atmos, wind, xd, kite, parent, CL, CD,
                                       parameters, elevation_angle)

    outputs['local_performance']['CR' + str(kite)] = CR
    outputs['local_performance']['p_loyd' + str(kite)] = p_loyd
    outputs['local_performance']['speed_loyd' + str(kite)] = speed_loyd
    outputs['local_performance']['phf_loyd' + str(kite)] = phf_loyd

    outputs['local_performance']['speed_ratio' +
                                 str(kite)] = airspeed / vect_op.norm(
                                     wind.get_velocity(q[2]))
    outputs['local_performance']['speed_ratio_loyd' +
                                 str(kite)] = speed_loyd / vect_op.norm(
                                     wind.get_velocity(q[2]))

    outputs['local_performance'][
        'radius_of_curvature' +
        str(kite)] = path_based_geom.get_radius_of_curvature(
            variables, kite, parent)

    return outputs
示例#13
0
def expected_filament_in_list(test_list, expected_filament):

    filaments = test_list.shape[1]

    thresh = 1.e-8

    for filament in range(filaments):
        local = test_list[:, filament]
        comparison = vect_op.norm(local - expected_filament)
        if comparison < thresh:
            return True

    return False
示例#14
0
文件: tools.py 项目: mg-meth/awebox
def get_rotor_reference_frame(init_options):
    n_rot_hat = get_ehat_tether(init_options)

    n_hat_is_x_hat = vect_op.abs(
        vect_op.norm(n_rot_hat - vect_op.xhat_np())) < 1.e-4
    if n_hat_is_x_hat:
        y_rot_hat = vect_op.yhat_np()
        z_rot_hat = vect_op.zhat_np()
    else:
        u_hat = vect_op.xhat_np()
        z_rot_hat = vect_op.normed_cross(u_hat, n_rot_hat)
        y_rot_hat = vect_op.normed_cross(z_rot_hat, n_rot_hat)

    return n_rot_hat, y_rot_hat, z_rot_hat
示例#15
0
def get_cosgamma_residual(model_options, wind, parent, variables, architecture):

    cosgamma_var = get_cosgamma_var(variables, parent)
    u_app = get_rotor_apparent_velocity(model_options, wind, parent, variables, architecture)
    nhat_var = geom.get_nhat_var(variables, parent)

    num = cas.mtimes(u_app.T, nhat_var)**2.
    den = cas.mtimes(u_app.T, u_app)
    # den^(1/2) = norm(u_app) * norm(nhat)

    u_ref = vect_op.norm(get_uapp_ref(wind))

    resi_unscaled = cosgamma_var**2. * den - num
    resi = resi_unscaled / u_ref**2.

    return resi
示例#16
0
文件: tools.py 项目: mg-meth/awebox
def get_kite_dcm(t, init_options, model, node, ret):

    velocity = get_velocity_vector(t, init_options, model, node, ret)
    ehat_normal, ehat_radial, ehat_tangential = get_rotating_reference_frame(
        t, init_options, model, node, ret)

    forwards_speed = cas.mtimes(velocity.T, ehat_tangential)
    forwards_sign = forwards_speed / vect_op.norm(forwards_speed)
    ehat_forwards = forwards_sign * ehat_tangential

    ehat1 = -1. * ehat_forwards
    ehat3 = ehat_normal
    ehat2 = vect_op.normed_cross(ehat3, ehat1)

    kite_dcm = cas.horzcat(ehat1, ehat2, ehat3)

    return kite_dcm
示例#17
0
def collect_environmental_outputs(atmos, wind, base_aerodynamic_quantities,
                                  outputs):

    kite = base_aerodynamic_quantities['kite']
    q = base_aerodynamic_quantities['q']

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

    outputs['environment']['windspeed' + str(kite)] = vect_op.norm(
        wind.get_velocity(q[2]))
    outputs['environment']['pressure' + str(kite)] = atmos.get_pressure(q[2])
    outputs['environment']['temperature' + str(kite)] = atmos.get_temperature(
        q[2])
    outputs['environment']['density' + str(kite)] = atmos.get_density(q[2])

    return outputs
示例#18
0
def compute_position_indicators(power_and_performance, plot_dict):

    # elevation angle
    q10 = plot_dict['xd']['q10']
    elevation = []
    for i in range(q10[0].shape[0]):
        elevation += [
            np.arccos(
                np.linalg.norm(np.array([q10[0][i], q10[1][i], 0.0])) /
                np.linalg.norm(np.array([q10[0][i], q10[1][i], q10[2][i]])))
        ]
    elevation = np.mean(elevation) * 180 / np.pi
    power_and_performance['elevation'] = elevation

    # average velocity of kites (maybe?)
    parent_map = plot_dict['architecture'].parent_map
    number_of_nodes = plot_dict['architecture'].number_of_nodes
    dq_final = 0.
    for node in range(1, number_of_nodes):
        parent = parent_map[node]
        dq = plot_dict['xd']['dq' + str(node) + str(parent)]
        parent = parent_map[node]
        dq_array = cas.vertcat(dq[0][-1], dq[1][-1], dq[2][-1])
        dq_norm_float = float(vect_op.norm(dq_array))
        dq_final += dq_norm_float
        dq_final = np.array(dq_final)
    dq_final /= float(number_of_nodes - 1.)
    power_and_performance['dq_final'] = dq_final

    # average connex-point velocity
    dq10 = plot_dict['xd']['dq10']
    dq10hat = []
    for i in range(dq10[0].shape[0]):
        dq = np.array([dq10[0][i], dq10[1][i], dq10[2][i]])
        q = np.array([q10[0][i], q10[1][i], q10[2][i]])
        dq10hat += [
            np.linalg.norm(dq - np.matmul(dq.T, q / np.linalg.norm(q)) * q /
                           np.linalg.norm(q))
        ]

    dq10_av = np.mean(np.array(dq10hat))
    power_and_performance['dq10_av'] = dq10_av

    return power_and_performance
示例#19
0
def get_trivial_forces(model_options, variables, atmos, wind, n, parameters, architecture):

    [diam, q_upper, q_lower, dq_upper, dq_lower, ua_upper, ua_lower] = get_upper_lower_q_and_dq(model_options,
                                                                                                  variables, wind, n,architecture)

    length = vect_op.norm(q_upper - q_lower)
    q_average = 0.5 * (q_upper + q_lower)
    dq_average = 0.5 * (dq_upper + dq_lower)
    rho = atmos.get_density(q_average[2])

    u_a = wind.get_velocity(q_average[2]) - dq_average

    cd = parameters['theta0','tether','cd']
    drag_force = cd * 0.5 * rho * vect_op.smooth_norm(u_a, 1e-6) * u_a * diam * length

    force_upper = drag_force / 2.
    force_lower = drag_force / 2.

    return [force_lower, force_upper]
示例#20
0
def test(test_list):

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

    x_obs = 0.5 * vect_op.xhat_np()

    u_ind = get_induced_velocity_at_observer(options, test_list, x_obs)

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

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

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

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

    return None
示例#21
0
文件: tools.py 项目: mg-meth/awebox
def find_airspeed(init_options, groundspeed, psi):

    dq_kite = get_velocity_vector_from_psi(init_options, groundspeed, psi)

    l_t = init_options['xd']['l_t']
    ehat_tether = get_ehat_tether(init_options)
    zz = l_t * ehat_tether[2]

    wind_model = init_options['model']['wind_model']
    u_ref = init_options['model']['wind_u_ref']
    z_ref = init_options['model']['wind_z_ref']
    z0_air = init_options['model']['wind_z0_air']
    exp_ref = init_options['model']['wind_exp_ref']

    uu = wind.get_speed(wind_model, u_ref, z_ref, z0_air, exp_ref,
                        zz) * vect_op.xhat_np()

    u_app = dq_kite - uu
    airspeed = float(vect_op.norm(u_app))

    return airspeed
示例#22
0
def get_loyd_comparison(options, atmos, wind, xd, n, parent, CL, CD, parameters, elevation_angle=0.):
    # for elevation angle cosine losses see Van der Lind, p. 477, AWE book

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

    epsilon = 1.e-8
    CR = CL * (1. + (CD / (CL + epsilon))**2.)**0.5

    windspeed = vect_op.norm(wind.get_velocity(q[2]))
    power_density = get_power_density(atmos, wind, q[2])

    f_crosswind = 4. / 27. * CR * (CR / CD) ** 2. * np.cos(elevation_angle) ** 3.

    s_ref = parameters['theta0','geometry','s_ref']
    p_loyd = power_density * s_ref * f_crosswind

    loyd_speed = 2. * CR / 3. / CD * windspeed * np.cos(elevation_angle)

    loyd_phf = f_crosswind

    return [CR, f_crosswind, p_loyd, loyd_speed, loyd_phf]
示例#23
0
文件: segment.py 项目: mg-meth/awebox
def get_segment_equiv_fun():

    seg_info_sym = cas.SX.sym('seg_info_sym', (12, 1))

    q_upper = seg_info_sym[:3]
    q_lower = seg_info_sym[3:6]
    drag_earthfixed = seg_info_sym[6:9]
    moment_earthfixed = seg_info_sym[9:12]

    tether = q_upper - q_lower

    # frames.test_transforms()

    drag_body = frames.from_earth_to_body(drag_earthfixed, q_upper, q_lower)
    moment_body = frames.from_earth_to_body(moment_earthfixed, q_upper,
                                            q_lower)

    moment_body[2] = 0.  # no spin on tether segment

    total_vect = cas.vertcat(drag_body, moment_body)

    Ainv = frames.get_inverse_equivalence_matrix(vect_op.norm(tether))

    equiv_vect = cas.mtimes(Ainv, total_vect)

    equiv_force_upper_body = equiv_vect[0:3]
    equiv_force_lower_body = equiv_vect[3:6]

    equiv_force_upper_earthfixed = frames.from_body_to_earth(
        equiv_force_upper_body, q_upper, q_lower)
    equiv_force_lower_earthfixed = frames.from_body_to_earth(
        equiv_force_lower_body, q_upper, q_lower)

    equivs = cas.vertcat(equiv_force_upper_earthfixed,
                         equiv_force_lower_earthfixed)

    segment_equiv_fun = cas.Function('segment_equiv_fun', [seg_info_sym],
                                     [equivs])

    return segment_equiv_fun
示例#24
0
def get_force_and_moment(options, parameters, vec_u_earth, kite_dcm, omega,
                         delta, rho):

    # we use the vec_u_earth and the kite_dcm to give the relative orientation.
    # this means, that they must be in the same frame. otherwise, the frame of
    # the wind vector is not used in this function.

    alpha = indicators.get_alpha(vec_u_earth, kite_dcm)
    beta = indicators.get_beta(vec_u_earth, kite_dcm)

    airspeed = vect_op.norm(vec_u_earth)
    force_coeff_info, moment_coeff_info = stability_derivatives.stability_derivatives(
        options, alpha, beta, airspeed, omega, delta, parameters)

    force_info = {}
    moment_info = {}

    force_info['frame'] = force_coeff_info['frame']
    moment_info['frame'] = moment_coeff_info['frame']

    CF = force_coeff_info['coeffs']
    CM = moment_coeff_info['coeffs']

    # notice that magnitudes don't change under rotation
    dynamic_pressure = 1. / 2. * rho * cas.mtimes(vec_u_earth.T, vec_u_earth)
    planform_area = parameters['theta0', 'geometry', 's_ref']

    force = CF * dynamic_pressure * planform_area
    force_info['vector'] = force

    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))

    moment = dynamic_pressure * planform_area * cas.mtimes(
        reference_lengths, CM)
    moment_info['vector'] = moment

    return force_info, moment_info
示例#25
0
def get_performance_outputs(options, atmos, wind, variables, outputs, parameters,architecture):

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

    kite_nodes = architecture.kite_nodes
    xd = variables['xd']

    outputs['performance']['freelout'] = xd['dl_t'] / vect_op.norm(
        wind.get_velocity(xd['q10'][2]))

    outputs['performance']['elevation'] = get_elevation_angle(variables['xd'])

    outputs['performance']['p_loyd_total'] = 0.

    for n in kite_nodes:
        outputs['performance']['p_loyd_total'] += outputs['local_performance']['p_loyd' + str(n)]

    [current_power, phf, phf_hubheight, hubheight_power_availability] = get_power_harvesting_factor(options, atmos,
                                                                                                    wind, variables, parameters,architecture)
    outputs['performance']['phf'] = phf
    outputs['performance']['phf_hubheight'] = phf_hubheight
    outputs['performance']['hubheight_power_availability'] = hubheight_power_availability

    outputs['performance']['phf_loyd_total'] = outputs['performance']['p_loyd_total'] / hubheight_power_availability

    outputs['performance']['p_current'] = current_power

    epsilon = 1.0e-8

    p_loyd_total = outputs['performance']['p_loyd_total']
    outputs['performance']['loyd_factor'] = current_power / (p_loyd_total + epsilon)

    outputs['performance']['power_density'] = current_power / len(kite_nodes) / parameters['theta0','geometry','s_ref']

    return outputs
示例#26
0
def get_equivalent_tether_drag_forces(model_options, diam, q_upper, q_lower, dq_upper, dq_lower, atmos, wind, cd_tether_fun):

    tether = q_upper - q_lower

    [total_force_earthfixed, total_moment_earthfixed] = get_total_drag(model_options, diam, q_upper, q_lower, dq_upper, dq_lower, atmos, wind, cd_tether_fun)

    total_force_body = from_earthfixed_to_body(total_force_earthfixed, q_upper, q_lower)
    total_moment_body = from_earthfixed_to_body(total_moment_earthfixed, q_upper, q_lower)

    total_moment_body[2] = 0.

    total_vect = cas.vertcat(total_force_body, total_moment_body)

    Ainv = get_inverse_equivalence_matrix(vect_op.norm(tether))

    equiv_vect = cas.mtimes(Ainv, total_vect)

    equiv_force_upper_body = equiv_vect[0:3]
    equiv_force_lower_body = equiv_vect[3:6]

    equiv_force_upper_earthfixed = from_body_to_earthfixed(equiv_force_upper_body, q_upper, q_lower)
    equiv_force_lower_earthfixed = from_body_to_earthfixed(equiv_force_lower_body, q_upper, q_lower)

    return [equiv_force_upper_earthfixed, equiv_force_lower_earthfixed]
示例#27
0
def get_power_density(atmos, wind, zz):

    power_density = .5 * atmos.get_density( zz) * vect_op.norm(wind.get_velocity(zz)) ** 3.

    return power_density
示例#28
0
def angle_between(a, b):
    fraction = cas.mtimes(a.T, b) / (vect_op.norm(a) * vect_op.norm(b))
    angle = np.arccos(fraction)
    return angle
示例#29
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
示例#30
0
def get_performance_outputs(options, atmos, wind, variables, outputs,
                            parameters, architecture):

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

    kite_nodes = architecture.kite_nodes
    xd = variables['xd']

    outputs['performance']['freelout'] = xd['dl_t'] / vect_op.norm(
        wind.get_velocity(xd['q10'][2]))
    outputs['performance']['elevation'] = get_elevation_angle(variables['xd'])

    layer_nodes = architecture.layer_nodes
    for parent in layer_nodes:
        outputs['performance']['actuator_center' +
                               str(parent)] = actuator_geom.get_center_point(
                                   options, parent, variables, architecture)

        average_radius = 0.

        number_children = len(architecture.children_map[parent])
        for kite in architecture.children_map[parent]:

            rad_curv_name = 'radius_of_curvature' + str(kite)
            if rad_curv_name in outputs['local_performance'].keys():
                local_radius = outputs['local_performance'][rad_curv_name]
            else:
                qkite = variables['xd']['q' + str(kite) + str(parent)]
                local_radius = vect_op.norm(
                    qkite -
                    outputs['performance']['actuator_center' + str(parent)])

            average_radius += local_radius / float(number_children)

        outputs['performance']['average_radius' + str(parent)] = average_radius

    outputs['performance']['p_loyd_total'] = 0.
    for kite in kite_nodes:
        outputs['performance']['p_loyd_total'] += outputs['local_performance'][
            'p_loyd' + str(kite)]

    [current_power, phf, phf_hubheight, hubheight_power_availability
     ] = get_power_harvesting_factor(options, atmos, wind, variables,
                                     parameters, architecture)
    outputs['performance']['phf'] = phf
    outputs['performance']['phf_hubheight'] = phf_hubheight
    outputs['performance'][
        'hubheight_power_availability'] = hubheight_power_availability

    outputs['performance']['phf_loyd_total'] = outputs['performance'][
        'p_loyd_total'] / hubheight_power_availability

    outputs['performance']['p_current'] = current_power

    epsilon = 1.0e-8
    p_loyd_total = outputs['performance']['p_loyd_total']
    outputs['performance']['loyd_factor'] = current_power / (p_loyd_total +
                                                             epsilon)

    outputs['performance']['power_density'] = current_power / len(
        kite_nodes) / parameters['theta0', 'geometry', 's_ref']

    return outputs