コード例 #1
0
def test_swept_wing_with_controls():
    # Tests the NLL algorithm correctly calculates a swept wing

    # Load input
    input_dict, aircraft_name, aircraft_dict, state, control_state = MX.helpers.parse_input(
        input_file)

    # Alter input
    input_dict["solver"]["type"] = "nonlinear"

    aircraft_dict["wings"]["main_wing"]["sweep"] = 30.0
    aircraft_dict["wings"]["h_stab"]["sweep"] = 30.0

    control_state = {"elevator": 5.0, "aileron": 5.0, "rudder": 5.0}

    # Create scene
    scene = MX.Scene(input_dict)
    scene.add_aircraft(aircraft_name,
                       aircraft_dict,
                       state=state,
                       control_state=control_state)
    FM = scene.solve_forces(non_dimensional=True)
    print(json.dumps(FM["test_plane"]["total"], indent=4))
    assert abs(FM["test_plane"]["total"]["FL"] - 32.13425691779829) < 1e-10
    assert abs(FM["test_plane"]["total"]["FD"] - 4.280678609518078) < 1e-10
    assert abs(FM["test_plane"]["total"]["FS"] + 4.397707239991741) < 1e-10
    assert abs(FM["test_plane"]["total"]["Fx"] + 3.1566015424292044) < 1e-10
    assert abs(FM["test_plane"]["total"]["Fy"] + 4.397707239991741) < 1e-10
    assert abs(FM["test_plane"]["total"]["Fz"] + 32.26407512573988) < 1e-10
    assert abs(FM["test_plane"]["total"]["Mx"] + 17.910786767633244) < 1e-10
    assert abs(FM["test_plane"]["total"]["My"] + 76.03674820597931) < 1e-10
    assert abs(FM["test_plane"]["total"]["Mz"] - 13.868978522091632) < 1e-10
コード例 #2
0
def test_stability_derivatives():
    # Tests the calculation of the stability derivatives

    # Load scene
    scene = MX.Scene(input_file)
    stab_derivs = scene.stability_derivatives()

    assert abs(stab_derivs["test_plane"]["CL,a"] - 6.322012906729068) < 1e-10
    assert abs(stab_derivs["test_plane"]["CD,a"] - 0.3246111615552763) < 1e-10
    assert abs(stab_derivs["test_plane"]["CS,a"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cx,a"] - 0.11707169911153548) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cy,a"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cz,a"] + 6.336555845802937) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cl,a"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cm,a"] + 3.946036942099846) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cn,a"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["CL,b"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["CD,b"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["CS,b"] + 0.8157254960313394) < 1e-9
    assert abs(stab_derivs["test_plane"]["Cx,b"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cy,b"] + 0.8304002728742348) < 1e-9
    assert abs(stab_derivs["test_plane"]["Cz,b"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cl,b"] + 0.1615386223535695) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cm,b"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cn,b"] - 0.6171846005680138) < 1e-9
コード例 #3
0
def test_damping_derivatives():
    # Test the calculation of the damping derivatives

    # Load scene
    scene = MX.Scene(input_file)
    damp_derivs = scene.aircraft_damping_derivatives()

    # There's something about how NLL calculates these cases that introduces a little more numerical error...
    assert abs(damp_derivs["test_plane"]["CL,pbar"] -
               0.00037018702894742184) < 1e-6
    assert abs(damp_derivs["test_plane"]["CD,pbar"] +
               6.60883695078468e-05) < 1e-6
    assert abs(damp_derivs["test_plane"]["CS,pbar"] +
               0.09305320429644524) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cx,pbar"] -
               7.896745125857141e-05) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cy,pbar"] +
               0.09305320429644524) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cz,pbar"] +
               0.0003676550701381398) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cl,pbar"] + 2.55335879459208) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cm,pbar"] +
               0.0011593362887751812) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cn,pbar"] -
               0.02514714847131455) < 1e-6
    assert abs(damp_derivs["test_plane"]["CL,qbar"] -
               13.019918503532345) < 1e-6
    assert abs(damp_derivs["test_plane"]["CD,qbar"] -
               0.3090180115277938) < 1e-6
    assert abs(damp_derivs["test_plane"]["CS,qbar"] +
               0.013965339163743515) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cx,qbar"] -
               0.14555883677632234) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cy,qbar"] +
               0.013965339163743515) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cz,qbar"] +
               13.022771694040092) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cl,qbar"] +
               0.0011967792488973804) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cm,qbar"] + 36.6535222940767) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cn,qbar"] -
               0.010480645283789216) < 1e-6
    assert abs(damp_derivs["test_plane"]["CL,rbar"] +
               2.211564265053312e-09) < 1e-6
    assert abs(damp_derivs["test_plane"]["CD,rbar"] +
               4.9465639917478654e-11) < 1e-6
    assert abs(damp_derivs["test_plane"]["CS,rbar"] -
               1.2322179506649182) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cx,rbar"] +
               2.776858604169874e-11) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cy,rbar"] -
               1.2322179506649182) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cz,rbar"] -
               2.2119805986875463e-09) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cl,rbar"] -
               0.36543638451918914) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cm,rbar"] -
               6.248890294102694e-09) < 1e-6
    assert abs(damp_derivs["test_plane"]["Cn,rbar"] +
               0.9323904254656564) < 1e-6
コード例 #4
0
def test_stability_derivatives():
    # Tests the calculation of the stability derivatives

    # Load scene
    scene = MX.Scene(input_file)
    stab_derivs = scene.aircraft_stability_derivatives()

    assert abs(stab_derivs["test_plane"]["CL,a"] - 6.325561939795834) < 1e-10
    assert abs(stab_derivs["test_plane"]["CD,a"] - 0.32484784717545706) < 1e-10
    assert abs(stab_derivs["test_plane"]["CS,a"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cx,a"] - 0.11701146202557859) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cy,a"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cz,a"] + 6.340112485605566) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cl,a"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cm,a"] + 3.951172935738557) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cn,a"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["CL,B"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["CD,B"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["CS,B"] + 0.8173565005198824) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cx,B"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cy,B"] + 0.8320251585209351) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cz,B"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cl,B"] + 0.13833770562075048) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cm,B"]) < 1e-10
    assert abs(stab_derivs["test_plane"]["Cn,B"] - 0.6187734326780242) < 1e-10
コード例 #5
0
def test_twist_as_f_of_span():
    # Tests that twist is properly returned as a function of span

    # Load input
    input_dict, airplane_name, airplane_dict, state, control_state = MX.helpers.parse_input(
        input_file)

    # Alter input
    for key in airplane_dict["wings"]:
        airplane_dict["wings"][key].pop("sweep", None)
        if "vertical" not in key:
            airplane_dict["wings"][key].pop("dihedral", None)
        airplane_dict["wings"][key]["twist"] = [[0.0, 0.0], [0.5, 5.0],
                                                [1.0, -5.0]]

    # Load scene
    scene = MX.Scene(input_dict)
    scene.add_aircraft(airplane_name,
                       airplane_dict,
                       state=state,
                       control_state=control_state)

    spans = [0.0, 0.1, 0.2]
    twists = [0.0, 0.017453292519943295, 0.03490658503988659]

    wing_dict = scene._airplanes[airplane_name].wing_segments
    for key in wing_dict:
        for span, correct_twist in zip(spans, twists):
            twist = wing_dict[key].get_twist(span)
            print(twist)
            assert np.allclose(twist, correct_twist, rtol=0.0, atol=1e-10)
コード例 #6
0
def bire_case(params, inp_dir):
    [alpha, beta, d_e, d_a, d_r, p, q, r] = params
    rotation_angle = str(int(d_r))
    try:
        f = open(inp_dir + 'BIRE_input_dr_' + rotation_angle + '.json', )
    except FileNotFoundError:
        create_inputs(inp_dir, d_r)
    input_file = inp_dir + 'BIRE_input_dr_' + rotation_angle + '.json'
    BIRE_scene = mx.Scene(input_file)
    forces_options = {
        'body_frame': True,
        'stab_frame': False,
        'wind_frame': True,
        'dimensional': False,
        'verbose': False
    }
    rates = [p, q, r]
    BIRE_scene.set_aircraft_state(state={
        "alpha": alpha,
        "beta": beta,
        "angular_rates": rates,
        "velocity": 222.5211
    })
    BIRE_scene.set_aircraft_control_state(control_state={
        "elevator": d_e,
        "aileron": d_a
    })
    x = BIRE_scene.solve_forces(**forces_options)["BIRE"]["total"]
    fm = [x['CD'], x['CS'], x['CL'], x['Cl'], x['Cm'], x['Cn']]
    return fm
コード例 #7
0
def test_pitch_trim_orientation():

    # Alter input
    with open(input_file, 'r') as input_file_handle:
        input_dict = json.load(input_file_handle)

    input_dict["scene"]["aircraft"]["test_plane"]["control_state"] = {
        "elevator" : 0.0,
        "rudder" : 0.0,
        "aileron" : 0.0
    }

    input_dict["scene"]["aircraft"]["test_plane"]["state"] = {
        "position" : [0, 0, 1000],
        "angular_rates" : [0.0, 0.0, 0.0],
        "velocity" : 100,
        "alpha" : 2.0,
        "beta" : 0.0
    }

    # Create scene
    scene = MX.Scene(input_dict)
    trim = scene.pitch_trim_using_orientation(CL=0.1, Cm=0.2)
    print(trim)
    assert abs(trim[0]["orientation"][0]-0.9999997533435244)<1e-10
    assert abs(trim[0]["orientation"][1])<1e-10
    assert abs(trim[0]["orientation"][2]+0.0007023623640411208)<1e-10
    assert abs(trim[0]["orientation"][3])<1e-10
    assert abs(trim[1]["elevator"]+3.8073227363076954)<1e-10
コード例 #8
0
def test_tapered_wing():
    # Tests the NLL algorithm correctly calculates a swept wing

    # Load input
    input_dict, aircraft_name, aircraft_dict, state, control_state = MX.helpers.parse_input(input_file)

    # Alter input
    input_dict["solver"]["type"] = "nonlinear"

    aircraft_dict["wings"]["main_wing"]["chord"] = [[0.0, 1.0],[1.0, 0.5]]
    aircraft_dict["wings"]["main_wing"]["dihedral"] = 10.0

    # Create scene
    scene = MX.Scene(input_dict)
    scene.add_aircraft(aircraft_name, aircraft_dict, state=state, control_state=control_state)
    FM = scene.solve_forces(non_dimensional=True)
    print(json.dumps(FM["test_plane"]["total"], indent=4))
    assert abs(FM["test_plane"]["total"]["FL"]-17.722533099036767)<1e-10
    assert abs(FM["test_plane"]["total"]["FD"]-1.184375545596456)<1e-10
    assert abs(FM["test_plane"]["total"]["FS"])<1e-10
    assert abs(FM["test_plane"]["total"]["Fx"]+0.565146570565037)<1e-10
    assert abs(FM["test_plane"]["total"]["Fy"])<1e-10
    assert abs(FM["test_plane"]["total"]["Fz"]+17.753071121167718)<1e-10
    assert abs(FM["test_plane"]["total"]["Mx"])<1e-10
    assert abs(FM["test_plane"]["total"]["My"]+13.573362229826092)<1e-10
    assert abs(FM["test_plane"]["total"]["Mz"])<1e-10
コード例 #9
0
def test_step_change_in_twist_wing():
    # Tests the NLL algorithm correctly calculates a wing with a step change in twist

    # Load input
    input_dict, aircraft_name, aircraft_dict, state, control_state = MX.helpers.parse_input(input_file)

    # Alter input
    input_dict["solver"]["type"] = "nonlinear"

    aircraft_dict["wings"]["main_wing"]["chord"] = [[0.0, 1.0],[1.0, 0.5]]
    aircraft_dict["wings"]["main_wing"]["dihedral"] = 10.0
    aircraft_dict["wings"]["main_wing"]["twist"] = [[0.0, 5.0],
                                                    [0.5, 5.0],
                                                    [0.5, 0.0],
                                                    [1.0, 0.0]]
    aircraft_dict["wings"]["main_wing"]["sweep"] = 30.0
    aircraft_dict["wings"]["main_wing"]["grid"]["N"] = 100

    # Create scene
    scene = MX.Scene(input_dict)
    scene.add_aircraft(aircraft_name, aircraft_dict, state=state, control_state=control_state)
    FM = scene.solve_forces(non_dimensional=True)
    print(json.dumps(FM["test_plane"]["total"], indent=4))
    assert abs(FM["test_plane"]["total"]["FL"]-28.35481401045731)<1e-10
    assert abs(FM["test_plane"]["total"]["FD"]-3.606067666817706)<1e-10
    assert abs(FM["test_plane"]["total"]["FS"])<1e-10
    assert abs(FM["test_plane"]["total"]["Fx"]+2.614302209769785)<1e-10
    assert abs(FM["test_plane"]["total"]["Fy"])<1e-10
    assert abs(FM["test_plane"]["total"]["Fz"]+28.463390970530668)<1e-10
    assert abs(FM["test_plane"]["total"]["Mx"])<1e-10
    assert abs(FM["test_plane"]["total"]["My"]+18.601536350947654)<1e-10
    assert abs(FM["test_plane"]["total"]["Mz"])<1e-10
コード例 #10
0
def test_swept_wing():
    # Tests the NLL algorithm correctly calculates a swept wing

    # Load input
    input_dict, aircraft_name, aircraft_dict, state, control_state = MX.helpers.parse_input(input_file)

    # Alter input
    input_dict["solver"]["type"] = "nonlinear"

    aircraft_dict["wings"]["main_wing"]["sweep"] = 30.0

    # Create scene
    scene = MX.Scene(input_dict)
    scene.add_aircraft(aircraft_name, aircraft_dict, state=state, control_state=control_state)
    FM = scene.solve_forces(non_dimensional=True)
    print(json.dumps(FM["test_plane"]["total"], indent=4))
    assert abs(FM["test_plane"]["total"]["FL"]-19.783243781894804)<1e-10
    assert abs(FM["test_plane"]["total"]["FD"]-1.5107597754297257)<1e-10
    assert abs(FM["test_plane"]["total"]["FS"])<1e-10
    assert abs(FM["test_plane"]["total"]["Fx"]+0.8194142102628863)<1e-10
    assert abs(FM["test_plane"]["total"]["Fy"])<1e-10
    assert abs(FM["test_plane"]["total"]["Fz"]+19.823917120109112)<1e-10
    assert abs(FM["test_plane"]["total"]["Mx"])<1e-10
    assert abs(FM["test_plane"]["total"]["My"]+30.137871282759612)<1e-10
    assert abs(FM["test_plane"]["total"]["Mz"])<1e-10
コード例 #11
0
def test_swept_wing_with_controls():
    # Tests the NLL algorithm correctly calculates a swept wing

    # Load input
    input_dict, aircraft_name, aircraft_dict, state, control_state = MX.helpers.parse_input(input_file)

    # Alter input
    input_dict["solver"]["type"] = "nonlinear"

    aircraft_dict["wings"]["main_wing"]["sweep"] = 30.0
    aircraft_dict["wings"]["h_stab"]["sweep"] = 30.0

    control_state = {
        "elevator" : 5.0,
        "aileron" : 5.0,
        "rudder" : 5.0
    }

    # Create scene
    scene = MX.Scene(input_dict)
    scene.add_aircraft(aircraft_name, aircraft_dict, state=state, control_state=control_state)
    FM = scene.solve_forces(non_dimensional=True)
    print(json.dumps(FM["test_plane"]["total"], indent=4))
    assert abs(FM["test_plane"]["total"]["FL"]-32.44429480507447)<1e-10
    assert abs(FM["test_plane"]["total"]["FD"]-4.283836550324898)<1e-10
    assert abs(FM["test_plane"]["total"]["FS"]+4.414822066505888)<1e-10
    assert abs(FM["test_plane"]["total"]["Fx"]+3.1489373932791636)<1e-10
    assert abs(FM["test_plane"]["total"]["Fy"]+4.414822066505888)<1e-10
    assert abs(FM["test_plane"]["total"]["Fz"]+32.57403435685684)<1e-10
    assert abs(FM["test_plane"]["total"]["Mx"]+17.905545144497058)<1e-10
    assert abs(FM["test_plane"]["total"]["My"]+76.51699263955834)<1e-10
    assert abs(FM["test_plane"]["total"]["Mz"]-13.915921134824531)<1e-10
コード例 #12
0
def test_pitch_trim_with_finite_moment():

    # Alter input
    with open(input_file, 'r') as input_file_handle:
        input_dict = json.load(input_file_handle)

    input_dict["scene"]["aircraft"]["test_plane"]["control_state"] = {
        "elevator" : 0.0,
        "rudder" : 0.0,
        "aileron" : 0.0
    }

    input_dict["scene"]["aircraft"]["test_plane"]["state"] = {
        "position" : [0, 0, 1000],
        "angular_rates" : [0.0, 0.0, 0.0],
        "velocity" : 100,
        "alpha" : 2.0,
        "beta" : 0.0
    }

    # Create scene
    scene = MX.Scene(input_dict)
    trim = scene.pitch_trim(CL=0.1, Cm=0.2)
    print(trim)
    assert abs(trim["test_plane"]["alpha"]-1.9195151950855374)<1e-10
    assert abs(trim["test_plane"]["elevator"]+3.807322736307231)<1e-10
コード例 #13
0
def trim_func(x,Cl,static_margin, Cn_beta, Cl_beta):
    with open('glider_2.0.json') as f:
        airplane = json.load(f)
    f.close()
    with open('scene.json') as f:
        scene = json.load(f)
    f.close()
    wing_twist = 2.5        # angle to twist wing down from mounting angle.
    airplane['CG'][0] = x[0]
    airplane['wings']['main_wing']['twist'] = [[0.0, x[1],
                                                1.0, x[1]-wing_twist]]
    airplane['wings']['outside_wings']['twist'] =  [[0.0, 0,
                                                    1.0, 0]]
    airplane['wings']['H_Stab']['connect_to']['dx'] = x[2]
    airplane['wings']['V_Stab']['connect_to']['dx'] = x[3]
    airplane['wings']['main_wing']['dihedral'] = x[4]
    with open('glider_2.0.json', 'w') as fp:
        json.dump(airplane,fp,indent = 4)
    fp.close()
    my_scene = MX.Scene('scene.json')
    FM_results = my_scene.solve_forces(non_dimensional = True)
    derivs = my_scene.derivatives()['glider_2.0']
    residual = FM_results['glider_2.0']['total']['Cm']**2 + (derivs['stability']['%_static_margin']/100-static_margin)**2+\
        + (derivs['stability']['Cn,b'] - Cn_beta)**2 + (derivs['stability']['Cl,b']-Cl_beta)**2 + (FM_results['glider_2.0']['total']['CL']-Cl)**2
    print('The moment coefficient is: ',FM_results['glider_2.0']['total']['Cm'])
    print('The static margin is: ',derivs['stability']['%_static_margin']/100)
    print('Cn,b is: ',derivs['stability']['Cn,b'])
    print('Cl,b is: ',derivs['stability']['Cl,b'])
    print('Cl is: ',FM_results['glider_2.0']['total']['CL'])
    print('L/D is: ',FM_results['glider_2.0']['total']['CL']/FM_results['glider_2.0']['total']['CD'])
    return residual
コード例 #14
0
def test_target_CL():

    # Alter input
    with open(input_file, 'r') as input_file_handle:
        input_dict = json.load(input_file_handle)

    input_dict["scene"]["aircraft"]["test_plane"]["control_state"] = {
        "elevator" : 0.0,
        "rudder" : 0.0,
        "aileron" : 0.0
    }

    input_dict["scene"]["aircraft"]["test_plane"]["state"] = {
        "position" : [0, 0, 1000],
        "angular_rates" : [0.0, 0.0, 0.0],
        "velocity" : 100,
        "alpha" : 2.0,
        "beta" : 0.0
    }

    # Create scene
    scene = MX.Scene(input_dict)
    alpha = scene.target_CL(CL=0.5)
    print(alpha)
    assert abs(alpha-4.531085683208453)<1e-10
コード例 #15
0
def test_pitch_trim():

    # Alter input
    with open(input_file, 'r') as input_file_handle:
        input_dict = json.load(input_file_handle)

    input_dict["scene"]["aircraft"]["test_plane"]["control_state"] = {
        "elevator" : 0.0,
        "rudder" : 0.0,
        "aileron" : 0.0
    }

    input_dict["scene"]["aircraft"]["test_plane"]["state"] = {
        "position" : [0, 0, 1000],
        "angular_rates" : [0.0, 0.0, 0.0],
        "velocity" : 100,
        "alpha" : 2.0,
        "beta" : 0.0
    }

    # Create scene
    scene = MX.Scene(input_dict)
    trim = scene.pitch_trim()
    print(trim)
    assert abs(trim["test_plane"]["alpha"]-12.27375383887546)<1e-10
    assert abs(trim["test_plane"]["elevator"]+10.303072276682208)<1e-10
コード例 #16
0
def test_swept_wing():
    # Tests the NLL algorithm correctly calculates a swept wing

    # Load input
    input_dict, aircraft_name, aircraft_dict, state, control_state = MX.helpers.parse_input(
        input_file)

    # Alter input
    input_dict["solver"]["type"] = "nonlinear"

    aircraft_dict["wings"]["main_wing"]["sweep"] = 30.0

    # Create scene
    scene = MX.Scene(input_dict)
    scene.add_aircraft(aircraft_name,
                       aircraft_dict,
                       state=state,
                       control_state=control_state)
    FM = scene.solve_forces(non_dimensional=True)
    print(json.dumps(FM["test_plane"]["total"], indent=4))
    assert abs(FM["test_plane"]["total"]["FL"] - 19.68954318567083) < 1e-10
    assert abs(FM["test_plane"]["total"]["FD"] - 1.5070187293045343) < 1e-10
    assert abs(FM["test_plane"]["total"]["FS"]) < 1e-10
    assert abs(FM["test_plane"]["total"]["Fx"] + 0.8189455467308557) < 1e-10
    assert abs(FM["test_plane"]["total"]["Fy"]) < 1e-10
    assert abs(FM["test_plane"]["total"]["Fz"] + 19.73014304312974) < 1e-10
    assert abs(FM["test_plane"]["total"]["Mx"]) < 1e-10
    assert abs(FM["test_plane"]["total"]["My"] + 30.285634979503445) < 1e-10
    assert abs(FM["test_plane"]["total"]["Mz"]) < 1e-10
コード例 #17
0
def test_tapered_wing():
    # Tests the NLL algorithm correctly calculates a swept wing

    # Load input
    input_dict, aircraft_name, aircraft_dict, state, control_state = MX.helpers.parse_input(
        input_file)

    # Alter input
    input_dict["solver"]["type"] = "nonlinear"

    aircraft_dict["wings"]["main_wing"]["chord"] = [[0.0, 1.0], [1.0, 0.5]]
    aircraft_dict["wings"]["main_wing"]["dihedral"] = 10.0

    # Create scene
    scene = MX.Scene(input_dict)
    scene.add_aircraft(aircraft_name,
                       aircraft_dict,
                       state=state,
                       control_state=control_state)
    FM = scene.solve_forces(non_dimensional=True)
    print(json.dumps(FM["test_plane"]["total"], indent=4))
    assert abs(FM["test_plane"]["total"]["FL"] - 17.728023315126524) < 1e-10
    assert abs(FM["test_plane"]["total"]["FD"] - 1.1847391542471732) < 1e-10
    assert abs(FM["test_plane"]["total"]["FS"]) < 1e-10
    assert abs(FM["test_plane"]["total"]["Fx"] + 0.5653183519368681) < 1e-10
    assert abs(FM["test_plane"]["total"]["Fy"]) < 1e-10
    assert abs(FM["test_plane"]["total"]["Fz"] + 17.758570682525082) < 1e-10
    assert abs(FM["test_plane"]["total"]["Mx"]) < 1e-10
    assert abs(FM["test_plane"]["total"]["My"] + 13.56985584130499) < 1e-10
    assert abs(FM["test_plane"]["total"]["Mz"]) < 1e-10
コード例 #18
0
def test_step_change_in_twist_wing():
    # Tests the NLL algorithm correctly calculates a wing with a step change in twist

    # Load input
    input_dict, aircraft_name, aircraft_dict, state, control_state = MX.helpers.parse_input(
        input_file)

    # Alter input
    input_dict["solver"]["type"] = "nonlinear"

    aircraft_dict["wings"]["main_wing"]["chord"] = [[0.0, 1.0], [1.0, 0.5]]
    aircraft_dict["wings"]["main_wing"]["dihedral"] = 10.0
    aircraft_dict["wings"]["main_wing"]["twist"] = [[0.0, 5.0], [0.5, 5.0],
                                                    [0.5, 0.0], [1.0, 0.0]]
    aircraft_dict["wings"]["main_wing"]["sweep"] = 30.0
    aircraft_dict["wings"]["main_wing"]["grid"]["N"] = 100

    # Create scene
    scene = MX.Scene(input_dict)
    scene.add_aircraft(aircraft_name,
                       aircraft_dict,
                       state=state,
                       control_state=control_state)
    FM = scene.solve_forces(non_dimensional=True)
    print(json.dumps(FM["test_plane"]["total"], indent=4))
    assert abs(FM["test_plane"]["total"]["FL"] - 28.12285963876808) < 1e-10
    assert abs(FM["test_plane"]["total"]["FD"] - 3.5693179079748987) < 1e-10
    assert abs(FM["test_plane"]["total"]["FS"]) < 1e-10
    assert abs(FM["test_plane"]["total"]["Fx"] + 2.585669928717018) < 1e-10
    assert abs(FM["test_plane"]["total"]["Fy"]) < 1e-10
    assert abs(FM["test_plane"]["total"]["Fz"] + 28.23029535108992) < 1e-10
    assert abs(FM["test_plane"]["total"]["Mx"]) < 1e-10
    assert abs(FM["test_plane"]["total"]["My"] + 18.969204048301485) < 1e-10
    assert abs(FM["test_plane"]["total"]["Mz"]) < 1e-10
コード例 #19
0
def test_distributions():

    #Load scene
    scene = MX.Scene(input_file)
    dist = scene.distributions()

    assert np.allclose(dist["test_plane"]["main_wing_right"]["chord"], 1.0, rtol=0.0, atol=1e-10)
    assert np.allclose(dist["test_plane"]["main_wing_right"]["sweep"], 0.0, rtol=0.0, atol=1e-10)
    assert np.allclose(dist["test_plane"]["main_wing_left"]["dihedral"], 0.0, rtol=0.0, atol=1e-10)
    assert np.allclose(dist["test_plane"]["v_stab_right"]["dihedral"], 1.5707963267948966, rtol=0.0, atol=1e-10)
    assert np.allclose(dist["test_plane"]["h_stab_left"]["twist"], 0.0, rtol=0.0, atol=1e-10)
コード例 #20
0
def test_compute_constant_swept_dihedral_wing_tip_location():
    # Tests the tip of the wing is in the proper location for a wing with
    # both constant sweep and constant dihedral

    # Alter input
    with open(input_file, 'r') as input_handle:
        input_dict = json.load(input_handle)

    with open(input_dict["scene"]["aircraft"]["test_plane"]["file"],
              'r') as airplane_file_handle:
        airplane_dict = json.load(airplane_file_handle)

    for key in airplane_dict["wings"]:
        airplane_dict["wings"][key]["sweep"] = 30
        if "v_stab" not in key:
            airplane_dict["wings"][key]["dihedral"] = 10
        airplane_dict["wings"][key].pop("twist", None)

    airplane_state = input_dict["scene"]["aircraft"].pop("test_plane")
    state = airplane_state.get("state", {})
    control_state = airplane_state.get("control_state", {})

    # Load scene
    scene = MX.Scene(input_dict)
    scene.add_aircraft("test_plane",
                       airplane_dict,
                       state=state,
                       control_state=control_state)

    # Check wing tip locations
    correct_locations = {
        "main_wing_left": [
            -4.618802153517006 / 2, -7.878462024097664 / 2,
            -1.3891854213354426 / 2
        ],
        "main_wing_right": [
            -4.618802153517006 / 2, 7.878462024097664 / 2,
            -1.3891854213354426 / 2
        ],
        "h_stab_left":
        [-4.1547005383792515, -1.9696155060244158, -0.3472963553338607],
        "h_stab_right":
        [-4.1547005383792515, 1.9696155060244158, -0.3472963553338607],
        "v_stab_right": [-4.1547005383792515, 0, -2.1]
    }

    wing_dict = scene._airplanes["test_plane"].wing_segments
    for key in wing_dict:
        tip_loc = wing_dict[key].get_tip_loc()
        print(tip_loc[2])
        assert np.allclose(tip_loc.flatten(),
                           correct_locations[key],
                           rtol=0,
                           atol=1e-10)
コード例 #21
0
def test_two_aircraft():
    # Tests that two aircraft flying side by side are properly modelled

    # Load input
    with open(input_file, 'r') as input_handle:
        input_dict = json.load(input_handle)

    with open(input_dict["scene"]["aircraft"]["test_plane"]["file"],
              'r') as airplane_file_handle:
        airplane_dict = json.load(airplane_file_handle)

    input_dict["solver"]["type"] = "nonlinear"

    airplane_state = input_dict["scene"]["aircraft"].pop("test_plane")
    state = airplane_state.get("state", {})
    control_state = airplane_state.get("control_state", {})

    # Load scene
    scene = MX.Scene(input_dict)

    state["orientation"] = [np.sqrt(2) / 2, 0, 0, np.sqrt(2) / 2]
    scene.add_aircraft("test_plane_0",
                       airplane_dict,
                       state=state,
                       control_state=control_state)

    state["position"] = [25, 0, 0]
    scene.add_aircraft("test_plane_1",
                       airplane_dict,
                       state=state,
                       control_state=control_state)

    FM = scene.solve_forces(verbose=True)

    # Since the aircraft are mirror images, their forces should be the same, with some being opposite
    assert abs(FM["test_plane_0"]["total"]["FL"] -
               FM["test_plane_1"]["total"]["FL"]) < 1e-6
    assert abs(FM["test_plane_0"]["total"]["FD"] -
               FM["test_plane_1"]["total"]["FD"]) < 1e-6
    assert abs(FM["test_plane_0"]["total"]["FS"] +
               FM["test_plane_1"]["total"]["FS"]) < 1e-6
    assert abs(FM["test_plane_0"]["total"]["Fx"] -
               FM["test_plane_1"]["total"]["Fx"]) < 1e-6
    assert abs(FM["test_plane_0"]["total"]["Fy"] +
               FM["test_plane_1"]["total"]["Fy"]) < 1e-6
    assert abs(FM["test_plane_0"]["total"]["Fz"] -
               FM["test_plane_1"]["total"]["Fz"]) < 1e-6
    assert abs(FM["test_plane_0"]["total"]["Mx"] +
               FM["test_plane_1"]["total"]["Mx"]) < 1e-6
    assert abs(FM["test_plane_0"]["total"]["My"] -
               FM["test_plane_1"]["total"]["My"]) < 1e-6
    assert abs(FM["test_plane_0"]["total"]["Mz"] +
               FM["test_plane_1"]["total"]["Mz"]) < 1e-6
コード例 #22
0
def worker(input, output):
    my_scene = MX.Scene("F16_input.json")
    for args in iter(input.get, 'STOP'):
        t0 = time.time()
        my_scene.set_aircraft_state(state={
            "alpha": args[0],
            "beta": args[1],
            "velocity": 222.5211
        })
        result = my_scene.solve_forces()
        print(time.time() - t0)
        output.put(result)
コード例 #23
0
def test_jackson_compare():
    # Tests that the circulation distribution for a swept wing matches Jackson's result (quickly becoming obsolete...)
    return  # This test is obsolete

    # Inputs
    input_dict = {"solver": {"type": "scipy_fsolve"}, "scene": {}}
    airplane_dict = {
        "weight": 10,
        "airfoils": {
            "NACA_0012": {
                "CLa": 6.907213339669221,
                "geometry": {
                    "NACA": "0012"
                }
            }
        },
        "wings": {
            "main_wing": {
                "ID": 1,
                "side": "both",
                "is_main": True,
                "semispan": 2.5,
                "chord": 1.0,
                "airfoil": "NACA_0012",
                "sweep": 45.0,
                "ac_offset": "kuchemann",
                "grid": {
                    "N": 20,
                    "reid_corrections": True
                }
            }
        }
    }

    # Get results
    state = {"velocity": 10.0, "alpha": 10.0}
    scene = MX.Scene(input_dict)
    scene.add_aircraft("jackson_wing", airplane_dict, state=state)
    FM = scene.solve_forces(verbose=True,
                            report_by_segment=True,
                            non_dimensional=False)

    # Check circulation distribution
    correct_gamma = np.array([
        0.47123536, 1.36936314, 2.16971088, 2.78795243, 3.18301932, 3.41035458,
        3.53474218, 3.59736899, 3.62115168, 3.61858063, 3.59673976, 3.56030944,
        3.5136121, 3.46215726, 3.41358434, 3.37738807, 3.36088964, 3.35806733,
        3.35540463, 3.353645, 3.353645, 3.35540463, 3.35806733, 3.36088964,
        3.37738807, 3.41358434, 3.46215726, 3.5136121, 3.56030944, 3.59673976,
        3.61858063, 3.62115168, 3.59736899, 3.53474218, 3.41035458, 3.18301932,
        2.78795243, 2.16971088, 1.36936314, 0.47123536
    ])
    assert np.allclose(scene._gamma, correct_gamma)
コード例 #24
0
ファイル: test_get_wind.py プロジェクト: kgp-niko98/MachUpX
def test_unspecified_wind():
    # Alter input
    with open(input_file, 'r') as json_handle:
        input_dict = json.load(json_handle)

    input_dict["units"] = "SI"

    scene = MX.Scene(input_dict)

    for i in range(5):  # Test 5 random positions
        position = np.random.random(3) * 10000
        wind = scene._get_wind(position).flatten()
        assert np.allclose(wind, [0, 0, 0], rtol=0.0, atol=1e-10) == True
コード例 #25
0
def test_unspecified_english_density():
    # Alter input
    with open(input_file, 'r') as json_handle:
        input_dict = json.load(json_handle)

    input_dict["units"] = "English"

    scene = MX.Scene(input_dict)

    for i in range(5):  # Test 5 random positions
        position = np.random.random(3) * 10000
        density = scene._get_density(position)
        assert np.allclose(density, 0.00237689072965, rtol=0.0,
                           atol=1e-10) == True
コード例 #26
0
def test_control_derivatives():
    # Test the calculation of the control derivatives

    # Load scene
    scene = MX.Scene(input_file)
    cont_derivs = scene.aircraft_control_derivatives()

    assert abs(cont_derivs["test_plane"]["CL,daileron"]) < 1e-10
    assert abs(cont_derivs["test_plane"]["CD,daileron"]) < 1e-10
    assert abs(cont_derivs["test_plane"]["CS,daileron"] -
               0.13409255196609768) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cx,daileron"]) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cy,daileron"] -
               0.13409255196609768) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cz,daileron"]) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cl,daileron"] +
               0.4829213183114422) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cm,daileron"]) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cn,daileron"] +
               0.1173202524037608) < 1e-10
    assert abs(cont_derivs["test_plane"]["CL,delevator"] -
               1.6795004768670678) < 1e-10
    assert abs(cont_derivs["test_plane"]["CD,delevator"] -
               0.030957629339379567) < 1e-10
    assert abs(cont_derivs["test_plane"]["CS,delevator"] +
               2.7500552332993075e-16) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cx,delevator"] -
               0.02767495056623802) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cy,delevator"] +
               2.7500552332993075e-16) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cz,delevator"] +
               1.6795577762381937) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cl,delevator"]) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cm,delevator"] +
               4.975416426126367) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cn,delevator"] -
               1.5931710494786176e-16) < 1e-10
    assert abs(cont_derivs["test_plane"]["CL,drudder"]) < 1e-10
    assert abs(cont_derivs["test_plane"]["CD,drudder"]) < 1e-10
    assert abs(cont_derivs["test_plane"]["CS,drudder"] +
               0.6384357546253706) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cx,drudder"]) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cy,drudder"] +
               0.6384357546253706) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cz,drudder"]) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cl,drudder"] +
               0.1411603229331166) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cm,drudder"]) < 1e-10
    assert abs(cont_derivs["test_plane"]["Cn,drudder"] -
               0.5111158114523209) < 1e-10
コード例 #27
0
def test_all_wing_segments_get_added():
    # Tests that all wing segments have been added and are available through
    # both the tree and the dict.

    # Load wing segments
    with open(input_file, 'r') as input_handle:
        input_dict = json.load(input_handle)

    with open(input_dict["scene"]["aircraft"]["test_plane"]["file"],
              'r') as airplane_file_handle:
        airplane_dict = json.load(airplane_file_handle)

    wing_segments = []
    wing_segment_sides = []
    for key in airplane_dict["wings"]:
        wing_segments.append(key)
        wing_segment_sides.append(airplane_dict["wings"][key]["side"])

    # Create scene
    scene = MX.Scene(input_file)

    # Check for each wing segment in both the tree and the dict
    wing_dict = scene._airplanes["test_plane"].wing_segments
    for segment_name, segment_side in zip(wing_segments, wing_segment_sides):

        if segment_side == "left" or segment_side == "both":
            name = segment_name + "_left"

            # Retrieve from dictionary
            dict_segment = wing_dict[name]

            # Retrieve from tree
            tree_segment = scene._airplanes["test_plane"]._get_wing_segment(
                name)

            # Make sure these reference the same object
            assert dict_segment is tree_segment

        if segment_side == "right" or segment_side == "both":
            name = segment_name + "_right"

            # Retrieve from dictionary
            dict_segment = wing_dict[name]

            # Retrieve from tree
            tree_segment = scene._airplanes["test_plane"]._get_wing_segment(
                name)

            # Make sure these reference the same object
            assert dict_segment is tree_segment
コード例 #28
0
def test_compute_variable_swept_dihedral_wing_tip_location():
    # Tests the tip of the wing is in the proper location for a wing with
    # both linearly varying sweep and linearly varying dihedral

    # Alter input
    with open(input_file, 'r') as input_handle:
        input_dict = json.load(input_handle)

    with open(input_dict["scene"]["aircraft"]["test_plane"]["file"],
              'r') as airplane_file_handle:
        airplane_dict = json.load(airplane_file_handle)

    for key in airplane_dict["wings"]:
        airplane_dict["wings"][key]["sweep"] = [[0.0, 0.0], [1.0, 40.0]]
        if "v_stab" not in key:
            airplane_dict["wings"][key]["dihedral"] = [[0.0, 0.0], [1.0, 10.0]]
        airplane_dict["wings"][key].pop("twist", None)

    airplane_state = input_dict["scene"]["aircraft"].pop("test_plane")
    state = airplane_state.get("state", {})
    control_state = airplane_state.get("control_state", {})

    # Load scene
    scene = MX.Scene(input_dict)
    scene.add_aircraft("test_plane",
                       airplane_dict,
                       state=state,
                       control_state=control_state)

    # Check wing tip locations
    correct_locations = {
        "main_wing_left":
        [-1.5270189901562612, -3.979723080181195, -0.3481806534883265],
        "main_wing_right":
        [-1.5270189901562612, 3.979723080181195, -0.3481806534883265],
        "h_stab_left":
        [-3.7635094950781305, -1.9898615400905975, -0.17409032674416325],
        "h_stab_right":
        [-3.7635094950781305, 1.9898615400905975, -0.17409032674416325],
        "v_stab_right": [-3.7635094950781305, 0, -2.1]
    }

    wing_dict = scene._airplanes["test_plane"].wing_segments
    for key in wing_dict:
        tip_loc = wing_dict[key].get_tip_loc()
        assert np.allclose(tip_loc.flatten(),
                           correct_locations[key],
                           rtol=0,
                           atol=1e-10)
コード例 #29
0
def test_specified_SI_density_with_english_units():
    # Alter input
    with open(input_file, 'r') as json_handle:
        input_dict = json.load(json_handle)

    input_dict["units"] = "English"
    input_dict["scene"]["atmosphere"]["rho"] = [1.225, "kg/m^3"]

    scene = MX.Scene(input_dict)

    for i in range(5):  # Test 5 random positions
        position = np.random.random(3) * 10000
        density = scene._get_density(position)
        assert np.allclose(density, 0.0023768923675, rtol=0.0,
                           atol=1e-10) == True
コード例 #30
0
def test_constant_airfoil_section_get_lift():
    # Tests the lift coefficient is properly given for a constant airfoil section

    # Load scene
    scene = MX.Scene(input_file)

    alphas = np.radians([0, 1, 2])
    CLs = [0.0, 0.1122875027563072, 0.2245750055126144]

    wing_segments = scene._airplanes["test_plane"].wing_segments
    for alpha, correct_CL in zip(alphas, CLs):
        for key in wing_segments:
            N = wing_segments[key].N
            CL = wing_segments[key].get_cp_CL(np.repeat(alpha, N), 0.0, 0.0)
            assert np.allclose(CL, correct_CL, rtol=0.0, atol=1e-10)