Example #1
0
    def power_required(self):
        thrust_required_dict = {}
        power_required_dict = {}
        alpha_dict = {}
        for velocity in self.velocity_range:
            total_lift = 0
            alpha = self.plane.stall_min
            while total_lift < self.plane.mtow * 9.81:
                alpha += 0.1
                total_lift = self.wing1.lift(self.rho, velocity,
                                             alpha) - self.hs.lift(
                                                 self.rho, velocity, alpha)
                if self.plane.plane_type == "biplane":
                    total_lift += self.wing2.lift(self.rho, velocity, alpha)
                if alpha >= self.plane.stall_max:
                    alpha_nivel = None
                    break
                else:
                    alpha_nivel = alpha

            thrust_required = (
                drag(self.rho, velocity, self.plane.S_tp, self.plane.CD_tp) +
                drag(self.rho, velocity, self.plane.S_fus, self.plane.CD_fus) +
                self.wing1.drag(self.rho, velocity, alpha_nivel) +
                self.wing2.drag(self.rho, velocity, alpha_nivel) +
                self.hs.drag(self.rho, velocity, alpha_nivel))

            alpha_dict[velocity] = alpha_nivel
            thrust_required_dict[velocity] = thrust_required

        for velocity in thrust_required_dict:
            power_required_dict[
                velocity] = thrust_required_dict[velocity] * velocity

        self.thrust_required_dict = thrust_required_dict
        self.power_required_dict = power_required_dict
        self.alpha_dict = alpha_dict
        self.alpha_df = dict_to_dataframe(alpha_dict, "Alpha", "Velocity")
        self.thrust_required_df = dict_to_dataframe(thrust_required_dict,
                                                    "Thrust required",
                                                    "Velocity")
        self.power_required_df = dict_to_dataframe(power_required_dict,
                                                   "Power required",
                                                   "Velocity")

        return self.alpha_df, self.thrust_required_df, self.power_required_df
Example #2
0
 def power_excess(self):
     power_excess_dict = {}
     for velocity in self.power_available_dict:
         power_required = self.power_required_dict[velocity]
         power_available = self.power_available_dict[velocity]
         power_excess_dict[velocity] = power_available - power_required
     self.power_excess_dict = power_excess_dict
     self.power_excess_df = dict_to_dataframe(power_excess_dict,
                                              "Power excess", "Velocity")
Example #3
0
 def get_CD_alpha_plane(self):
     CD_alpha_plane = {}
     for alpha in np.arange(-10, 21, 1.0):
         numerator = (self.wing1.get_CD(alpha) * self.wing1.area -
                      self.hs.get_CD(alpha) * self.hs.area)
         if self.plane_type == "biplane":
             numerator += self.wing2.get_CD(alpha) * self.wing2.area
         CD_alpha_plane[alpha] = numerator / self.wing1.area
     self.CD_alpha = dict_to_dataframe(CD_alpha_plane, "CD", "alpha")
     return self.CD_alpha
Example #4
0
    def power_available(self):
        thrust_available_dict = {}
        power_available_dict = {}

        for velocity in self.velocity_range:
            thrust_available = self.plane.motor.thrust(velocity)
            thrust_available_dict[velocity] = thrust_available

        for velocity in thrust_available_dict:
            power_available_dict[
                velocity] = thrust_available_dict[velocity] * velocity

        self.thrust_available_dict = thrust_available_dict
        self.power_available_dict = power_available_dict

        self.thrust_available_df = dict_to_dataframe(thrust_available_dict,
                                                     "Thrust available",
                                                     "Velocity")
        self.power_available_df = dict_to_dataframe(power_available_dict,
                                                    "Power available",
                                                    "Velocity")

        return self.thrust_available_df, self.power_available_df
    def trimm(self):
        tail_trimm = {}
        for hs_incidence in self.hs.incidence_range:
            root = find_df_roots(
                self.CM_alpha_CG_plane_each_hs_incidence[hs_incidence], "CM")
            if len(root) != 0:
                alpha_trimm = root[0]
                tail_trimm[alpha_trimm] = hs_incidence

        self.tail_trimm = tail_trimm
        self.tail_trimm_df = dict_to_dataframe(tail_trimm, "hs_incidence",
                                               "alpha")
        self.plane.tail_trimm = self.tail_trimm_df

        if tail_trimm:
            self.plane.alpha_trimm_min = min(tail_trimm, key=tail_trimm.get)
            self.plane.alpha_trimm_max = max(tail_trimm, key=tail_trimm.get)
        else:
            self.plane.alpha_trimm_min = 0
            self.plane.alpha_trimm_max = 0

        return self.tail_trimm_df
Example #6
0
def test_get_CL_alpha_plane(plane):
    cl = {
        -10.0: 0.8961720610687022,
        -9.0: 1.0828123664122136,
        -8.0: 1.2690087022900762,
        -7.0: 1.4544367938931297,
        -6.0: 1.6393807633587787,
        -5.0: 1.8236004580152672,
        -4.0: 2.00718,
        -3.0: 2.1898352671755723,
        -2.0: 2.3712140458015263,
        -1.0: 2.5516685496183205,
        0.0: 2.7310867175572517,
        1.0: 2.9091882442748087,
        2.0: 3.085813282442748,
        3.0: 3.260721679389313,
        4.0: 3.4343535877862594,
        5.0: 3.606312824427481,
        6.0: 3.7766433587786263,
        7.0: 3.945017099236641,
        8.0: 4.111562137404579,
        9.0: 4.276278473282442,
        10.0: 4.438685801526717,
        11.0: 4.59902427480916,
        12.0: 4.75733786259542,
        13.0: 4.836142442748091,
        14.0: 4.913922137404579,
        15.0: 4.99043679389313,
        16.0: 4.977114045801526,
        17.0: 4.9639671755725185,
        18.0: 4.950996183206107,
        19.0: 4.938289007633587,
        20.0: 4.925757709923665
    }

    df_cl_alpha = dict_to_dataframe(cl, "CL", "alpha")
    pd.testing.assert_frame_equal(plane.get_CL_alpha_plane(),
                                  df_cl_alpha,
                                  check_less_precise=3)
Example #7
0
def test_get_CD_alpha_plane(plane):
    cd = {
        -10.0: 0.005704,
        -9.0: 0.011138,
        -8.0: 0.017323,
        -7.0: 0.024453,
        -6.0: 0.032331,
        -5.0: 0.040958,
        -4.0: 0.050333,
        -3.0: 0.060700,
        -2.0: 0.072012,
        -1.0: 0.083633,
        0.0: 0.096442,
        1.0: 0.109715,
        2.0: 0.123580,
        3.0: 0.138194,
        4.0: 0.153556,
        5.0: 0.169427,
        6.0: 0.185846,
        7.0: 0.203057,
        8.0: 0.220337,
        9.0: 0.238164,
        10.0: 0.256300,
        11.0: 0.274833,
        12.0: 0.293873,
        13.0: 0.303226,
        14.0: 0.312970,
        15.0: 0.322387,
        16.0: 0.320189,
        17.0: 0.317946,
        18.0: 0.315616,
        19.0: 0.313242,
        20.0: 0.31082
    }

    df_cd_alpha = dict_to_dataframe(cd, "CD", "alpha")
    pd.testing.assert_frame_equal(plane.get_CD_alpha_plane(),
                                  df_cd_alpha,
                                  check_less_precise=3)
    def static_margin(self):
        SM_alpha = {}
        self.hs.incidence = 0
        for alpha_plane in self.plane.alpha_range:
            self.wing1.update_alpha(float(alpha_plane))
            self.wing2.update_alpha(float(alpha_plane))
            self.hs.update_alpha(float(alpha_plane))

            if self.hs.attack_angle in self.hs.get_alpha_range():
                # Calculating Static Margin for each alpha
                self.sm = SM(
                    self.plane.plane_type,
                    self.wing1,
                    self.wing2,
                    self.hs,
                    alpha_plane,
                    self.plane.dCM_dalpha.at[alpha_plane, "CM"],
                )  # TODO: We should pass the entire plane into SM analysys
                SM_alpha[alpha_plane] = self.sm.SM

        self.SM_alpha_df = dict_to_dataframe(SM_alpha, "SM", "alpha")
        self.plane.SM_alpha = self.SM_alpha_df
        return self.SM_alpha_df
    def CM_plane_CG(self, cg):

        CM_alpha_CG_tail = {}
        CM_alpha_CG_wing1 = {}
        CM_alpha_CG_wing2 = {}
        CM_alpha_CG_wings = {}
        CM_alpha_CG_plane = {}
        self.CM_alpha_CG_plane_each_hs_incidence = {}

        for alpha_plane in self.plane.alpha_range:

            self.wing1.update_alpha(float(alpha_plane))
            self.wing2.update_alpha(float(alpha_plane))

            # Getting CM_alpha of wing1
            CM_alpha_CG_wing1[alpha_plane] = self.wing1.moment_on_CG(
                self.wing1, self.plane.cg, alpha_plane)

            CM_alpha_CG_wings[alpha_plane] = CM_alpha_CG_wing1[alpha_plane]

            if self.plane.plane_type == "biplane":
                CM_alpha_CG_wing2[alpha_plane] = self.wing2.moment_on_CG(
                    self.wing1, self.plane.cg, alpha_plane)
                CM_alpha_CG_wings[alpha_plane] += CM_alpha_CG_wing2[
                    alpha_plane]

        for hs_incidence in self.hs.incidence_range:
            self.hs.incidence = hs_incidence
            for alpha_plane in self.plane.alpha_range:
                self.hs.update_alpha(float(alpha_plane))

                if self.hs.attack_angle in self.hs.get_alpha_range():
                    # Getting CM_alpha of tail
                    CM_alpha_CG_tail[alpha_plane] = self.hs.moment_on_CG(
                        self.wing1, self.plane.cg, alpha_plane)
                    # Summing CM of tail with CM of wing per each alpha
                    # Getting CM_alpha of plane
                    CM_alpha_CG_plane[alpha_plane] = (
                        CM_alpha_CG_wings[alpha_plane] +
                        CM_alpha_CG_tail[alpha_plane])
                else:
                    CM_alpha_CG_tail[alpha_plane] = None
                    CM_alpha_CG_plane[alpha_plane] = None

            CM_alpha_CG_plane_df = dict_to_dataframe(CM_alpha_CG_plane, "CM",
                                                     "alpha")
            self.CM_alpha_CG_plane_each_hs_incidence[
                hs_incidence] = CM_alpha_CG_plane_df

        self.trimm()

        dCM_dalpha_plane_df = self.CM_alpha_CG_plane_each_hs_incidence[0].diff(
        )
        dCM_dalpha_plane_df.fillna(method="bfill", inplace=True)
        self.plane.dCM_dalpha = dCM_dalpha_plane_df

        self.wing1.CM_alpha_CG = dict_to_dataframe(CM_alpha_CG_wing1, "CM",
                                                   "alpha")
        self.wing2.CM_alpha_CG = dict_to_dataframe(CM_alpha_CG_wing2, "CM",
                                                   "alpha")
        self.hs.CM_alpha_CG = dict_to_dataframe(CM_alpha_CG_tail, "CM",
                                                "alpha")

        return self.CM_alpha_CG_plane_each_hs_incidence
Example #10
0
def test_power_required(power):
    power_required_check = {
        3.693459: 55.925256,
        3.793459: 60.549268,
        3.893459: 65.434352,
        3.993459: 70.606824,
        4.093459: 76.044941,
        4.193459: 81.755353,
        4.293459: 87.744713,
        4.393459: 94.019673,
        4.493459: 100.586884,
        4.593459: 107.452999,
        4.693459: 114.624669,
        4.793459: 122.108547,
        4.893459: 129.911284,
        4.993459: 138.039533,
        5.093459: 146.499945,
        5.193459: 155.299173,
        5.293459: 164.443868,
        5.393459: 173.940683,
        5.493459: 183.796268,
        5.593459: 194.017277,
        5.693459: 204.610362,
        5.793459: 215.582173,
        5.893459: 226.939364,
        5.993459: 238.688586,
        6.093459: 250.836491,
        6.193459: 263.389731,
        6.293459: 276.354958,
        6.393459: 289.738825,
        6.493459: 303.547982,
        6.593459: 317.789082,
        6.693459: 332.468778,
        6.793459: 347.593720,
        6.893459: 363.170561,
        6.993459: 379.205954,
        7.093459: 395.706549,
        7.193459: 412.678999,
        7.293459: 430.129955,
        7.393459: 448.066071,
        7.493459: 466.493997,
        7.593459: 485.420386,
        7.693459: 504.851889,
        7.793459: 524.795160,
        7.893459: 545.256849,
        7.993459: 566.243608,
        8.093459: 587.762090,
        8.193459: 609.818947,
        8.293459: 632.420830,
        8.393459: 655.574392,
        8.493459: 679.286284,
        8.593459: 703.563159,
        8.693459: 728.411668,
    }

    df_power_required_check = dict_to_dataframe(power_required_check,
                                                "Power required", "Velocity")

    alpha_velocity_check = {
        3.693459: -9.4,
        3.793459: -9.7,
        3.893459: -9.9,
        3.993459: -9.9,
        4.093459: -9.9,
        4.193459: -9.9,
        4.293459: -9.9,
        4.393459: -9.9,
        4.493459: -9.9,
        4.593459: -9.9,
        4.693459: -9.9,
        4.793459: -9.9,
        4.893459: -9.9,
        4.993459: -9.9,
        5.093459: -9.9,
        5.193459: -9.9,
        5.293459: -9.9,
        5.393459: -9.9,
        5.493459: -9.9,
        5.593459: -9.9,
        5.693459: -9.9,
        5.793459: -9.9,
        5.893459: -9.9,
        5.993459: -9.9,
        6.093459: -9.9,
        6.193459: -9.9,
        6.293459: -9.9,
        6.393459: -9.9,
        6.493459: -9.9,
        6.593459: -9.9,
        6.693459: -9.9,
        6.793459: -9.9,
        6.893459: -9.9,
        6.993459: -9.9,
        7.093459: -9.9,
        7.193459: -9.9,
        7.293459: -9.9,
        7.393459: -9.9,
        7.493459: -9.9,
        7.593459: -9.9,
        7.693459: -9.9,
        7.793459: -9.9,
        7.893459: -9.9,
        7.993459: -9.9,
        8.093459: -9.9,
        8.193459: -9.9,
        8.293459: -9.9,
        8.393459: -9.9,
        8.493459: -9.9,
        8.593459: -9.9,
        8.693459: -9.9,
    }

    df_alpha_velocity_check = dict_to_dataframe(alpha_velocity_check, "Alpha",
                                                "Velocity")

    thrust_velocity_check = {
        3.693459: 15.141704,
        3.793459: 15.961495,
        3.893459: 16.806228,
        3.993459: 17.680620,
        4.093459: 18.577186,
        4.193459: 19.495925,
        4.293459: 20.436837,
        4.393459: 21.399922,
        4.493459: 22.385181,
        4.593459: 23.392613,
        4.693459: 24.422218,
        4.793459: 25.473996,
        4.893459: 26.547948,
        4.993459: 27.644073,
        5.093459: 28.762371,
        5.193459: 29.902842,
        5.293459: 31.065487,
        5.393459: 32.250305,
        5.493459: 33.457296,
        5.593459: 34.686460,
        5.693459: 35.937797,
        5.793459: 37.211308,
        5.893459: 38.506992,
        5.993459: 39.824849,
        6.093459: 41.164880,
        6.193459: 42.527084,
        6.293459: 43.911461,
        6.393459: 45.318011,
        6.493459: 46.746734,
        6.593459: 48.197631,
        6.693459: 49.670701,
        6.793459: 51.165944,
        6.893459: 52.683360,
        6.993459: 54.222950,
        7.093459: 55.784713,
        7.193459: 57.368649,
        7.293459: 58.974758,
        7.393459: 60.603041,
        7.493459: 62.253496,
        7.593459: 63.926125,
        7.693459: 65.620928,
        7.793459: 67.337903,
        7.893459: 69.077052,
        7.993459: 70.838374,
        8.093459: 72.621869,
        8.193459: 74.427538,
        8.293459: 76.255379,
        8.393459: 78.105394,
        8.493459: 79.977582,
        8.593459: 81.871944,
        8.693459: 83.788479,
    }

    df_thrust_velocity_check = dict_to_dataframe(thrust_velocity_check,
                                                 "Thrust required", "Velocity")

    pd.testing.assert_frame_equal(power.power_required_df,
                                  df_power_required_check,
                                  check_less_precise=3)
    pd.testing.assert_frame_equal(power.alpha_df,
                                  df_alpha_velocity_check,
                                  check_less_precise=3)
    pd.testing.assert_frame_equal(power.thrust_required_df,
                                  df_thrust_velocity_check,
                                  check_less_precise=3)
Example #11
0
def test_power_excess(power):
    power_excess_check = {
        3.693458584650559: -53.87901072296934,
        3.7934585846505593: -58.39071923177715,
        3.8934585846505594: -63.16049866668177,
        3.9934585846505595: -68.21466776637739,
        4.093458584650559: -73.53148059043242,
        4.19345858465056: -79.11758911028298,
        4.29345858465056: -84.97964529736497,
        4.39345858465056: -91.12430112311439,
        4.4934585846505595: -97.55820855896721,
        4.59345858465056: -104.28801957635953,
        4.6934585846505605: -111.32038614672733,
        4.79345858465056: -118.66196024150648,
        4.89345858465056: -126.31939383213309,
        4.99345858465056: -134.2993388900432,
        5.093458584650561: -142.60844738667276,
        5.1934585846505605: -151.2533712934577,
        5.29345858465056: -160.24076258183413,
        5.393458584650561: -169.57727322323802,
        5.493458584650561: -179.26955518910538,
        5.593458584650561: -189.3242604508721,
        5.6934585846505605: -199.74804097997426,
        5.793458584650561: -210.54754874784794,
        5.893458584650562: -221.72943572592908,
        5.993458584650561: -233.30035388565358,
        6.093458584650561: -245.26695519845754,
        6.193458584650561: -257.6358916357771,
        6.293458584650562: -270.4138151690479,
        6.393458584650562: -283.60737776970626,
        6.493458584650561: -297.22323140918803,
        6.593458584650562: -311.26802805892925,
        6.693458584650562: -325.74841969036595,
        6.793458584650562: -340.671058274934,
        6.893458584650562: -356.04259578406953,
        6.993458584650562: -371.8696841892086,
        7.093458584650563: -388.15897546178707,
        7.193458584650562: -404.917121573241,
        7.293458584650562: -422.1507744950062,
        7.3934585846505625: -439.86658619851903,
        7.493458584650563: -458.0712086552154,
        7.593458584650563: -476.77129383653096,
        7.693458584650562: -495.9734937139021,
        7.793458584650562: -515.6844602587644,
        7.893458584650563: -535.9108454425548,
        7.993458584650563: -556.6593012367081,
        8.093458584650563: -577.936479612661,
        8.193458584650562: -599.7490325418494,
        8.293458584650564: -622.1036119957093,
        8.393458584650563: -645.0068699456767,
        8.493458584650563: -668.465458363187,
        8.593458584650563: -692.4860292196771,
        8.693458584650564: -717.0752344865831,
    }

    df_power_excess_check = dict_to_dataframe(power_excess_check,
                                              "Power excess", "Velocity")

    pd.testing.assert_frame_equal(power.power_excess_df,
                                  df_power_excess_check,
                                  check_less_precise=3)
Example #12
0
def test_power_available(power):
    thrust_available_check = {
        3.693459: 0.554019,
        3.793459: 0.569019,
        3.893459: 0.584019,
        3.993459: 0.599019,
        4.093459: 0.614019,
        4.193459: 0.629019,
        4.293459: 0.644019,
        4.393459: 0.659019,
        4.493459: 0.674019,
        4.593459: 0.689019,
        4.693459: 0.704019,
        4.793459: 0.719019,
        4.893459: 0.734019,
        4.993459: 0.749019,
        5.093459: 0.764019,
        5.193459: 0.779019,
        5.293459: 0.794019,
        5.393459: 0.809019,
        5.493459: 0.824019,
        5.593459: 0.839019,
        5.693459: 0.854019,
        5.793459: 0.869019,
        5.893459: 0.884019,
        5.993459: 0.899019,
        6.093459: 0.914019,
        6.193459: 0.929019,
        6.293459: 0.944019,
        6.393459: 0.959019,
        6.493459: 0.974019,
        6.593459: 0.989019,
        6.693459: 1.004019,
        6.793459: 1.019019,
        6.893459: 1.034019,
        6.993459: 1.049019,
        7.093459: 1.064019,
        7.193459: 1.079019,
        7.293459: 1.094019,
        7.393459: 1.109019,
        7.493459: 1.124019,
        7.593459: 1.139019,
        7.693459: 1.154019,
        7.793459: 1.169019,
        7.893459: 1.184019,
        7.993459: 1.199019,
        8.093459: 1.214019,
        8.193459: 1.229019,
        8.293459: 1.244019,
        8.393459: 1.259019,
        8.493459: 1.274019,
        8.593459: 1.289019,
        8.693459: 1.304019,
    }

    df_thrust_available_check = dict_to_dataframe(thrust_available_check,
                                                  "Thrust available",
                                                  "Velocity")

    power_available_check = {
        3.693459: 2.046245,
        3.793459: 2.158549,
        3.893459: 2.273853,
        3.993459: 2.392157,
        4.093459: 2.513460,
        4.193459: 2.637764,
        4.293459: 2.765068,
        4.393459: 2.895372,
        4.493459: 3.028676,
        4.593459: 3.164979,
        4.693459: 3.304283,
        4.793459: 3.446587,
        4.893459: 3.591891,
        4.993459: 3.740194,
        5.093459: 3.891498,
        5.193459: 4.045802,
        5.293459: 4.203106,
        5.393459: 4.363409,
        5.493459: 4.526713,
        5.593459: 4.693017,
        5.693459: 4.862321,
        5.793459: 5.034624,
        5.893459: 5.209928,
        5.993459: 5.388232,
        6.093459: 5.569536,
        6.193459: 5.753839,
        6.293459: 5.941143,
        6.393459: 6.131447,
        6.493459: 6.324751,
        6.593459: 6.521054,
        6.693459: 6.720358,
        6.793459: 6.922662,
        6.893459: 7.127966,
        6.993459: 7.336269,
        7.093459: 7.547573,
        7.193459: 7.761877,
        7.293459: 7.979181,
        7.393459: 8.199484,
        7.493459: 8.422788,
        7.593459: 8.649092,
        7.693459: 8.878396,
        7.793459: 9.110700,
        7.893459: 9.346003,
        7.993459: 9.584307,
        8.093459: 9.825611,
        8.193459: 10.069915,
        8.293459: 10.317218,
        8.393459: 10.567522,
        8.493459: 10.820826,
        8.593459: 11.077130,
        8.693459: 11.336433,
    }

    df_power_available_check = dict_to_dataframe(power_available_check,
                                                 "Power available", "Velocity")

    pd.testing.assert_frame_equal(power.thrust_available_df,
                                  df_thrust_available_check,
                                  check_less_precise=3)
    pd.testing.assert_frame_equal(power.power_available_df,
                                  df_power_available_check,
                                  check_less_precise=3)