diff --git a/constraint_analysis/constraint_analysis_conf.xml b/constraint_analysis/constraint_analysis_conf.xml index b48efabd5ebe4db380f9f68c932d6843fc37b234..5d9132019a9ab853c4ce25e24523cd936b5e8ee8 100644 --- a/constraint_analysis/constraint_analysis_conf.xml +++ b/constraint_analysis/constraint_analysis_conf.xml @@ -5,7 +5,7 @@ <value>CSMR-2020.xml</value> </aircraft_exchange_file_name> <aircraft_exchange_file_directory description="Specify the direction in which the aircraft exchange file can be found"> - <value>../projects/CSMR/CSMR-2020/</value> + <value>../projects2/</value> </aircraft_exchange_file_directory> <own_tool_level description="Specify the tool level of this tool"> <value>3</value> @@ -109,11 +109,6 @@ <value>0.508</value> </minimum_climb_rate> </SEP> - <approach_speed> - <active> - <value>true</value> - </active> - </approach_speed> <landing_field_length> <active> <value>true</value> @@ -121,6 +116,18 @@ <Mach> <value>0.2</value> </Mach> + <k_TD> + <value>1.15</value> + </k_TD> + <t_FR> + <value>3</value> + </t_FR> + <obstacle_height> + <value>15.4</value> + </obstacle_height> + <Mach> + <value>0.2</value> + </Mach> </landing_field_length> <gust> <active> diff --git a/constraint_analysis/include/constraint_analysis/ca_functions.h b/constraint_analysis/include/constraint_analysis/ca_functions.h index a5126853267573559827cde2aba457a1a8cc6546..0dab17484a5be1305c06fe2b46e586e89638972e 100644 --- a/constraint_analysis/include/constraint_analysis/ca_functions.h +++ b/constraint_analysis/include/constraint_analysis/ca_functions.h @@ -184,6 +184,10 @@ namespace Mattingly { */ auto min_speed(double CL_max, double altitude, double Mach, double weight_fraction) -> const double; + auto approach_speed(double V_app, double CL_max, double weight_fraction, double s_A, double C_D, double h_obs, double k_TD, double altitude) -> const double; + + auto get_V_stall(double V_app, double k_TD, double CL_max, double CD, double h_obs, double s_A) -> const double; + private: // Membervariables diff --git a/constraint_analysis/include/constraint_analysis/ca_minfinder.h b/constraint_analysis/include/constraint_analysis/ca_minfinder.h index 674128172eb1cc626ca0a7966eb6781e2f542e82..ea0e3777bdda68e2756efc00640a13d3df5614ba 100644 --- a/constraint_analysis/include/constraint_analysis/ca_minfinder.h +++ b/constraint_analysis/include/constraint_analysis/ca_minfinder.h @@ -58,24 +58,27 @@ class Simple_Analysis : Analysis { public: std::vector<double> dominant_thrust_to_weight = {}; - std::vector<double> wing_loading_boundaries = {}; + double lower_wing_loading_boundary = {}; + double upper_wing_loading_boundary = {}; std::vector<double> wing_loading_vec = {}; double design_thrust_to_weight = 1000.0; double design_wing_loading = 0.0; - Simple_Analysis(std::vector<Constraint> constraint_list, std::vector<double> boundaries) : Analysis(constraint_list) + Simple_Analysis(std::vector<Constraint> constraint_list, std::vector<double> lower_boundaries, std::vector<double> upper_boundaries) : Analysis(constraint_list) { dominant_thrust_to_weight = constraint_list[0].thrust_to_weight; wing_loading_vec = constraint_list[0].wing_loading; - wing_loading_boundaries = boundaries; + lower_wing_loading_boundary = *std::max_element(lower_boundaries.begin(), lower_boundaries.end()); + upper_wing_loading_boundary = *std::min_element(upper_boundaries.begin(), upper_boundaries.end()); }; - Simple_Analysis(std::vector<Constraint> constraint_list, std::shared_ptr<node> acXML, std::vector<double> boundaries) : + Simple_Analysis(std::vector<Constraint> constraint_list, std::shared_ptr<node> acXML, std::vector<double> lower_boundaries, std::vector<double> upper_boundaries) : Analysis(constraint_list, acXML) { dominant_thrust_to_weight = constraint_list[0].thrust_to_weight; wing_loading_vec = constraint_list[0].wing_loading; - wing_loading_boundaries = boundaries; + lower_wing_loading_boundary = *std::max_element(lower_boundaries.begin(), lower_boundaries.end()); + upper_wing_loading_boundary = *std::min_element(upper_boundaries.begin(), upper_boundaries.end()); }; void find_dominant_curve() { @@ -90,7 +93,7 @@ public: void find_design_point(const double& safety_factor) { - std::sort(wing_loading_boundaries.begin(), wing_loading_boundaries.end()); + std::vector<double> wing_loading_boundaries = { lower_wing_loading_boundary, upper_wing_loading_boundary }; std::vector<double> xlims = {}; for (auto x_limit : wing_loading_boundaries) { auto it = std::distance(wing_loading_vec.begin(), std::lower_bound(wing_loading_vec.begin(), wing_loading_vec.end(), x_limit)); @@ -112,29 +115,38 @@ public: void find_converged_design_point(const double& previous_TW, const double& previous_WS, const double& safety_factor, const double& buffer_factor) { - std::sort(wing_loading_boundaries.begin(), wing_loading_boundaries.end()); - std::vector<double> xlims = {}; - for (auto x_limit : wing_loading_boundaries) { - auto it = std::distance(wing_loading_vec.begin(), std::lower_bound(wing_loading_vec.begin(), wing_loading_vec.end(), x_limit)); - xlims.push_back(it); + std::vector<double> wing_loading_boundaries = { lower_wing_loading_boundary, upper_wing_loading_boundary }; + if (upper_wing_loading_boundary < lower_wing_loading_boundary) + { + design_thrust_to_weight = previous_TW; + design_wing_loading = previous_WS; + std::cout << "infeasable design space, loadings are not adjusted" << std::endl; } - std::vector<double> limited_TW(dominant_thrust_to_weight.begin() + xlims[0], dominant_thrust_to_weight.begin() + xlims[1]); - int i = xlims[0]; - for (double point : limited_TW) + else { - if (point <= design_thrust_to_weight) + std::vector<double> xlims = {}; + for (auto x_limit : wing_loading_boundaries) { + auto it = std::distance(wing_loading_vec.begin(), std::lower_bound(wing_loading_vec.begin(), wing_loading_vec.end(), x_limit)); + xlims.push_back(it); + } + std::vector<double> limited_TW(dominant_thrust_to_weight.begin() + xlims[0], dominant_thrust_to_weight.begin() + xlims[1]); + int i = xlims[0]; + for (double point : limited_TW) { - design_thrust_to_weight = point; - design_wing_loading = wing_loading_vec[i]; + if (point <= design_thrust_to_weight) + { + design_thrust_to_weight = point; + design_wing_loading = wing_loading_vec[i]; + } + i++; } - i++; - } - design_thrust_to_weight = design_thrust_to_weight * (1.0 + safety_factor); + design_thrust_to_weight = design_thrust_to_weight * (1.0 + safety_factor); - double relative_change_TW = sqrt(pow(1 - previous_TW / design_thrust_to_weight, 2)); - if (relative_change_TW <= buffer_factor/100.0) { design_thrust_to_weight = previous_TW; }; - double relative_change_WS = sqrt(pow(1 - previous_WS / design_wing_loading, 2)); - if (relative_change_WS <= buffer_factor/100.0) { design_wing_loading = previous_WS; }; + double relative_change_TW = sqrt(pow(1 - previous_TW / design_thrust_to_weight, 2)); + if (relative_change_TW <= buffer_factor / 100.0) { design_thrust_to_weight = previous_TW; }; + double relative_change_WS = sqrt(pow(1 - previous_WS / design_wing_loading, 2)); + if (relative_change_WS <= buffer_factor / 100.0) { design_wing_loading = previous_WS; }; + }; }; template<typename T> diff --git a/constraint_analysis/src/ca_functions.cpp b/constraint_analysis/src/ca_functions.cpp index 738e818699064df2babaad2c3e338e13521da11c..f176ebd08e7f0be469640669c258325364a26f16 100644 --- a/constraint_analysis/src/ca_functions.cpp +++ b/constraint_analysis/src/ca_functions.cpp @@ -195,5 +195,37 @@ namespace Mattingly { return W_over_S; } + auto constraint_analysis::approach_speed(double V_app, double CL_max, double weight_fraction, double s_A, double C_D, double h_obs, double k_TD, double altitude) -> const double + { + double V_stall = 0.0; + + // this is a 4th order polynomial with coefficients (a*x^4 + b*x^3 + c*x^2 + d*x + e = 0) + double a = -k_TD * CL_max; + double b = 0.; + double c = pow(V_app, 2.) * CL_max + 2. * h_obs * CL_max - s_A * k_TD; + double d = 0.; + double e = -s_A * V_app * C_D; + + double del = pow(c, 2.) - 4. * a * e; + + V_stall = std::max(std::sqrt((-c + sqrt(del)) / (2. * a)), std::sqrt((-c - sqrt(del)) / (2. * a))); + + return pow(V_stall,2.)/(2.*weight_fraction/(atm.getDensity(altitude)*CL_max)); + } + + auto constraint_analysis::get_V_stall(double V_app, double k_TD, double CL_max, double CD, double h_obs, double s_A) -> const double + { + // this is a 4th order polynomial with coefficients (a*x^4 + b*x^3 + c*x^2 + d*x + e = 0) + double a = -k_TD * CL_max; + double b = 0.; + double c = pow(V_app, 2.) * CL_max + 2. * h_obs * CL_max - s_A * k_TD; + double d = 0.; + double e = -s_A * V_app * CD; + + double del = pow(c, 2.) - 4. * a * e; + + return std::max(std::sqrt((-c + sqrt(del)) / (2. * a)), std::sqrt((-c - sqrt(del)) / (2. * a))); + } + } diff --git a/constraint_analysis/src/energy_based/energy_based.cpp b/constraint_analysis/src/energy_based/energy_based.cpp index e11af9dfe6df0d64c8e8f945d950c7ff1b1c48f4..eb6c05e773465e0d6630cfe5e9d87b159e90a183 100644 --- a/constraint_analysis/src/energy_based/energy_based.cpp +++ b/constraint_analysis/src/energy_based/energy_based.cpp @@ -83,6 +83,9 @@ void EnergyBased::operator()() W_over_S_data[i] = (WS_start + i) * 9.81; } + this->lower_boundaries.push_back(50.0 * 9.81); + this->upper_boundaries.push_back(820.0 * 9.81); + Engine engine = Engine(this->engine_directory()); Mattingly::constraint_analysis constraint_analysis_tool; @@ -113,7 +116,7 @@ void EnergyBased::operator()() assess_constraints(W_over_S_data, constraint_analysis_tool, mission_data, engine); /* Define Simple_Analysis*/ - Simple_Analysis min_finder = Simple_Analysis(this->constraint_list, this->aircraft_xml(), this->boundaries); + Simple_Analysis min_finder = Simple_Analysis(this->constraint_list, this->aircraft_xml(), this->lower_boundaries, this->upper_boundaries); /* Find dominant curve of the design chart*/ min_finder.find_dominant_curve(); @@ -155,23 +158,26 @@ void EnergyBased::operator()() } this->constraint_list = {}; - this->boundaries = {}; + this->lower_boundaries = { 50. * 9.81 }; + this->upper_boundaries = { 820. * 9.81 }; assess_constraints(W_over_S_data, constraint_analysis_plotting, mission_data, engine); - Simple_Analysis min_finder_2 = Simple_Analysis(this->constraint_list, this->aircraft_xml(), this->boundaries); + Simple_Analysis min_finder_2 = Simple_Analysis(this->constraint_list, this->aircraft_xml(), this->lower_boundaries, this->upper_boundaries); min_finder_2.find_dominant_curve(); ConstraintAnalysis_Plot ca_plot; + std::vector<double> boundaries = { min_finder_2.lower_wing_loading_boundary , min_finder_2.upper_wing_loading_boundary }; + ca_plot.fill_infeasible_area(W_over_S_data, min_finder_2.dominant_thrust_to_weight, boundaries); for (auto ca_case : this->constraint_list) { ca_plot.add_curve(ca_case.wing_loading, ca_case.thrust_to_weight, ca_case.constraint_case); } - for (auto boundary : this->boundaries) + for (auto boundary : boundaries) { ca_plot.add_curve(boundary, "W/S limit"); } @@ -328,27 +334,33 @@ void EnergyBased::assess_constraints(std::vector<double>& W_over_S_data, Mattin minimum_climb_rate); Constraint Case(W_over_S_data, constraint_vector, constraint->name); this->constraint_list.push_back(Case); - } - else if (constraint->name == "approach_speed") - { - } else if (constraint->name == "landing_field_length") { - /* Landing */ + double k_TD = constraint->at("k_TD/value"); + double h_obs = constraint->at("obstacle_height/value"); double M = constraint->at("Mach/value"); - double thrust_lapse = calculate_thrust_lapse(M, 0.0); + double t_FR = constraint->at("t_FR/value"); + double V_app = this->aircraft_xml()->at( + "aircraft_exchange_file/requirements_and_specifications/requirements/top_level_aircraft_requirements/flight_envelope/maximum_approach_speed/value"); double CL_max_L = this->aircraft_xml()->at("aircraft_exchange_file/analysis/aerodynamics/lift_coefficients/C_LmaxLanding/value"); - double my_B = this->aircraft_xml()->at("aircraft_exchange_file/requirements_and_specifications/requirements/additional_requirements/landing_gear/braking_coefficient/value"); - double s_G_L = 0.6 * this->aircraft_xml()->at("aircraft_exchange_file/requirements_and_specifications/requirements/top_level_aircraft_requirements/landing_field_length/value"); - // s_G_L as braking distance = 60% of landing field length + double s_A = h_obs / std::tan(3. * std::numbers::pi / 180.); readPolar landing_config(this->polar(), "landing", "linear", M); double CD_max_L = landing_config.interpCD(CL_max_L); double max_landing_weight = this->aircraft_xml()->at("aircraft_exchange_file/analysis/masses_cg_inertia/maximum_landing_mass/mass_properties/mass/value"); double MTOM = this->aircraft_xml()->at("aircraft_exchange_file/analysis/masses_cg_inertia/maximum_takeoff_mass/mass_properties/mass/value"); double weight_fraction = max_landing_weight / MTOM; + const auto approach = constraint_analysis_tool.approach_speed(V_app, CL_max_L, weight_fraction, s_A, CD_max_L, h_obs, k_TD, 0.0); + this->upper_boundaries.push_back(approach); + double V_stall = constraint_analysis_tool.get_V_stall(V_app, k_TD, CL_max_L, CD_max_L, h_obs, s_A); + double s_FR = V_stall * k_TD * t_FR; + + /* Landing */ + double thrust_lapse = calculate_thrust_lapse(M, 0.0); + double my_B = this->aircraft_xml()->at("aircraft_exchange_file/requirements_and_specifications/requirements/additional_requirements/landing_gear/braking_coefficient/value"); + double s_G_L = 0.6 * this->aircraft_xml()->at("aircraft_exchange_file/requirements_and_specifications/requirements/top_level_aircraft_requirements/landing_field_length/value") - s_A - s_FR; const auto constraint_border = constraint_analysis_tool.braking_roll(CD_max_L, CL_max_L, weight_fraction, thrust_lapse, M, 0.0, my_B, s_G_L); - this->boundaries.push_back(constraint_border); + this->upper_boundaries.push_back(constraint_border); } else if (constraint->name == "gust") { @@ -364,7 +376,7 @@ void EnergyBased::assess_constraints(std::vector<double>& W_over_S_data, Mattin double w_g = this->configuration()->at("module_configuration_file/program_settings/constraint_selection/standard_set/gust/gust_speed/value"); double dn_G = this->configuration()->at("module_configuration_file/program_settings/constraint_selection/standard_set/gust/gust_load_factor/value"); const auto constraint_border = constraint_analysis_tool.gust(CL_alpha, 0.0, V_TO_L, w_g, dn_G, weight_fraction); - this->boundaries.push_back(constraint_border); + this->lower_boundaries.push_back(constraint_border); } } }; diff --git a/constraint_analysis/src/energy_based/energy_based.h b/constraint_analysis/src/energy_based/energy_based.h index b8c56b24a7868ef269aab12a8475172acf2af084..3e48c381278b41cef14732ef9790ed89bd484d88 100644 --- a/constraint_analysis/src/energy_based/energy_based.h +++ b/constraint_analysis/src/energy_based/energy_based.h @@ -70,7 +70,8 @@ public: void assess_constraints(std::vector<double>& W_over_S_data, Mattingly::constraint_analysis& constraint_analysis_tool, readMission& mission_data, Engine& engine); std::vector<Constraint> constraint_list = {}; - std::vector<double> boundaries = {}; + std::vector<double> lower_boundaries = {}; + std::vector<double> upper_boundaries = {}; }; // namespace design #endif // SRC_CONSTRAINT_ANALYSIS_ENERGY_BASED_H_ \ No newline at end of file