From 00df046e7a8a3a63c810200edfb0c3ccda3db19a Mon Sep 17 00:00:00 2001 From: Gerrit Pauls <gerrit.pauls@tuhh.de> Date: Wed, 11 Dec 2024 17:08:33 +0100 Subject: [PATCH 1/2] LoD added to CSV --- mission_analysis/mission_analysis_conf.xml | 2 +- .../condition_methods/flight_conditions.cpp | 1 + .../condition_methods/flight_conditions.h | 7 +- .../condition_methods/operating_conditions.h | 6 +- .../flight_segments/flight_segments.cpp | 88 +++++++++++++------ .../output/standard_mission_output.cpp | 8 +- .../standard_mission/standard_mission.cpp | 40 +++++---- .../standard_mission/standard_mission.h | 37 ++++++-- 8 files changed, 127 insertions(+), 62 deletions(-) diff --git a/mission_analysis/mission_analysis_conf.xml b/mission_analysis/mission_analysis_conf.xml index 7978e1d8..f26e4b04 100644 --- a/mission_analysis/mission_analysis_conf.xml +++ b/mission_analysis/mission_analysis_conf.xml @@ -34,7 +34,7 @@ <value>true</value> </tex_report> <write_info_files description="Switch to generate info files. Switch: true (On) / false (Off)"> - <value>true</value> + <value>false</value> </write_info_files> <log_file description="Specify the name of the log file"> <value>mission_analysis.log</value> diff --git a/mission_analysis/src/libs/condition_methods/flight_conditions.cpp b/mission_analysis/src/libs/condition_methods/flight_conditions.cpp index 56f5b01a..d7fd5acd 100644 --- a/mission_analysis/src/libs/condition_methods/flight_conditions.cpp +++ b/mission_analysis/src/libs/condition_methods/flight_conditions.cpp @@ -68,6 +68,7 @@ Flight_conditions::Flight_conditions(std::vector<mission_file_data_handler::miss /* Initialization of parameters at the end of the segment */ end_angle_of_attack(0.), end_CL(0.), + end_L_over_D(0.), end_specific_air_range(0.), /* Initialization of parameters for engine parameter calculation */ rel_engine_availability(1.), diff --git a/mission_analysis/src/libs/condition_methods/flight_conditions.h b/mission_analysis/src/libs/condition_methods/flight_conditions.h index 15ee5cd1..8226aa04 100644 --- a/mission_analysis/src/libs/condition_methods/flight_conditions.h +++ b/mission_analysis/src/libs/condition_methods/flight_conditions.h @@ -9,8 +9,8 @@ * */ -#ifndef MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_Flight_conditions_H_ -#define MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_Flight_conditions_H_ +#ifndef MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_FLIGHT_CONDITIONS_H_ +#define MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_FLIGHT_CONDITIONS_H_ #include <map> #include <memory> @@ -90,6 +90,7 @@ class Flight_conditions { double end_angle_of_attack; /**< Angle of attack AOA at the end of the segment [deg] */ double end_CL; /**< Lift coefficient at the end of the segment [-] */ + double end_L_over_D; /**< Lift over drag coefficient at the end of the segment [-] */ double end_specific_air_range; /**< Specific air range at the end of the segment [m/kg] */ double rel_engine_availability; /**< Percentage of available engines; default 1 (AEO), OEI: (numberOfEngines-1)/numberOfEngines [-] */ @@ -186,4 +187,4 @@ class Flight_conditions { void update_end_mass(const bool& use_breguet = false); }; -#endif // MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_Flight_conditions_H_ +#endif // MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_FLIGHT_CONDITIONS_H_ diff --git a/mission_analysis/src/libs/condition_methods/operating_conditions.h b/mission_analysis/src/libs/condition_methods/operating_conditions.h index c10562de..c17893ec 100644 --- a/mission_analysis/src/libs/condition_methods/operating_conditions.h +++ b/mission_analysis/src/libs/condition_methods/operating_conditions.h @@ -12,8 +12,8 @@ /* List of references [1] Airbus customer services, Flight Operations Support & Line Assistance: Getting to grips with the cost index, Issue II, May 1998, p.7 */ -#ifndef MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_Operating_conditions_H_ -#define MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_Operating_conditions_H_ +#ifndef MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_OPERATING_CONDITIONS_H_ +#define MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_OPERATING_CONDITIONS_H_ #include <string> #include <vector> @@ -58,4 +58,4 @@ class Operating_conditions { void delete_used_bleed_and_shaft_power_offtakes(const double& time_step); }; -#endif // MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_Operating_conditions_H_ +#endif // MISSION_ANALYSIS_SRC_LIBS_CONDITION_METHODS_OPERATING_CONDITIONS_H_ diff --git a/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp b/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp index e0000899..395ca07c 100644 --- a/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp +++ b/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp @@ -29,6 +29,7 @@ standard_mission::mission_segment::mission_segment(const std::map<int, double>& double an_end_altitude, double an_end_total_mass, double an_end_CL, + double an_end_L_over_D, double an_end_specific_air_range, const std::string& an_end_aero_config, double an_end_glidepath_angle, @@ -58,6 +59,7 @@ standard_mission::mission_segment::mission_segment(const std::map<int, double>& end_altitude(an_end_altitude), end_total_mass(an_end_total_mass), end_CL(an_end_CL), + end_L_over_D(an_end_L_over_D), end_specific_air_range(an_end_specific_air_range), end_aero_config(an_end_aero_config), end_glidepath_angle(an_end_glidepath_angle), @@ -207,12 +209,12 @@ void standard_mission::climb_to_service_ceiling(Operating_conditions* oc, Flight fc->delta_h = (steps <= 0.) ? 0. : fc->delta_h / steps; try { myRuntimeInfo->out << std::endl << "Flying maximum operating altitude ..." << std::endl; - myRuntimeInfo->out << "Climb Step: " << convertUnit(METER, FOOT, fc->delta_h) << " ft." - << "Total: " << convertUnit(METER, FOOT, fc->delta_h * steps) << " ft." << std::endl; - myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl; - myRuntimeInfo->out << "End altitude: " << convertUnit(METER, FOOT, (fc->delta_h * steps + fc->altitude)) << " ft." << std::endl; + myRuntimeInfo->out << "Climb Step: " << convertUnit(METER, FOOT, fc->delta_h) << " ft." + << "Total: " << convertUnit(METER, FOOT, fc->delta_h * steps) << " ft." << std::endl; + myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl; + myRuntimeInfo->out << "End altitude: " << convertUnit(METER, FOOT, (fc->delta_h * steps + fc->altitude)) << " ft." << std::endl; myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, get_transition_altitude(CAS, transition_mach, this->atm)) << " ft." << std::endl; - myRuntimeInfo->out << "Engine Rating: " << oc->rating << std::endl; + myRuntimeInfo->out << "Engine Rating: " << oc->rating << std::endl; for (uint16_t step_number(0); step_number < steps; ++step_number) { /* Set the initial conditions of the segment */ this->set_segment_initial_conditions(fc); @@ -238,12 +240,12 @@ void standard_mission::climb_to_service_ceiling(Operating_conditions* oc, Flight fc->delta_h = (steps <= 0.) ? 0. : fc->delta_h / steps; try { myRuntimeInfo->out << std::endl << "Flying absolute ceiling altitude ..." << std::endl; - myRuntimeInfo->out << "Climb Step: " << convertUnit(METER, FOOT, fc->delta_h) << " ft." - << "Total: " << convertUnit(METER, FOOT, fc->delta_h * steps) << " ft." << std::endl; - myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl; - myRuntimeInfo->out << "End altitude: " << convertUnit(METER, FOOT, (fc->delta_h * steps + fc->altitude)) << " ft." << std::endl; + myRuntimeInfo->out << "Climb Step: " << convertUnit(METER, FOOT, fc->delta_h) << " ft." + << "Total: " << convertUnit(METER, FOOT, fc->delta_h * steps) << " ft." << std::endl; + myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl; + myRuntimeInfo->out << "End altitude: " << convertUnit(METER, FOOT, (fc->delta_h * steps + fc->altitude)) << " ft." << std::endl; myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, get_transition_altitude(CAS, transition_mach, this->atm)) << " ft." << std::endl; - myRuntimeInfo->out << "Engine Rating: " << oc->rating << std::endl; + myRuntimeInfo->out << "Engine Rating: " << oc->rating << std::endl; for (uint16_t step_number(0); step_number < steps; ++step_number) { this->set_segment_initial_conditions(fc); if (fc->altitude < get_transition_altitude(CAS, transition_mach, this->atm)) { @@ -274,12 +276,12 @@ void standard_mission::climb_to_service_ceiling(Operating_conditions* oc, Flight fc->delta_h = (steps <= 0.) ? 0. : fc->delta_h / steps; try { myRuntimeInfo->out << std::endl << "Flying maximum altitude with one engine inoperative ..." << std::endl; - myRuntimeInfo->out << "Climb Step: " << convertUnit(METER, FOOT, fc->delta_h) << " ft." - << " Total: " << convertUnit(METER, FOOT, fc->delta_h * steps) << " ft." << std::endl; - myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl; - myRuntimeInfo->out << "End altitude: " << convertUnit(METER, FOOT, (fc->delta_h * steps + fc->altitude)) << " ft." << std::endl; + myRuntimeInfo->out << "Climb Step: " << convertUnit(METER, FOOT, fc->delta_h) << " ft." + << " Total: " << convertUnit(METER, FOOT, fc->delta_h * steps) << " ft." << std::endl; + myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl; + myRuntimeInfo->out << "End altitude: " << convertUnit(METER, FOOT, (fc->delta_h * steps + fc->altitude)) << " ft." << std::endl; myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, get_transition_altitude(CAS, transition_mach, this->atm)) << " ft." << std::endl; - myRuntimeInfo->out << "Engine Rating: " << oc->rating << std::endl; + myRuntimeInfo->out << "Engine Rating: " << oc->rating << std::endl; for (uint16_t step_number(0); step_number < steps; ++step_number) { this->set_segment_initial_conditions(fc); if (fc->altitude < get_transition_altitude(CAS, transition_mach, this->atm)) { @@ -430,12 +432,12 @@ double standard_mission::calculate_climb_or_descent(Operating_conditions* oc, Fl Flight_conditions fc_tmp(*fc); fc_tmp.delta_h /= steps; if (!simulation_mode) { - myRuntimeInfo->out << ((fc_tmp.delta_h > 0.) ? "Climb step: " : "Descent step: ") + myRuntimeInfo->out << ((fc_tmp.delta_h > 0.) ? "Climb step: " : "Descent step: ") << convertUnit(METER, FOOT, fc_tmp.delta_h) << " ft." << std::endl; myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc_tmp.altitude) << " ft." << std::endl; - myRuntimeInfo->out << "End altitude" << ((this->mission_file->mission_data.at(a_mission_step).auto_FL_optimum) ? " (estimated): " : ": ") + myRuntimeInfo->out << "End altitude " << ((this->mission_file->mission_data.at(a_mission_step).auto_FL_optimum) ? " (estimated): " : ": ") << convertUnit(METER, FOOT, (fc_tmp.delta_h * steps + fc_tmp.altitude)) << " ft." << std::endl; - if (change_speed_at_transition_altitude) myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, transitionAltitude) << " ft." << std::endl; + if (change_speed_at_transition_altitude) myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, transitionAltitude) << " ft." << std::endl; } for (uint16_t step_number(0); step_number < steps; ++step_number) { this->set_segment_initial_conditions(&fc_tmp, !simulation_mode); @@ -706,6 +708,7 @@ double standard_mission::landing(Operating_conditions* oc, Flight_conditions* fc residuum = fabs(oldTAS - fc->end_TAS) / fabs(oldTAS); } while (residuum > ACCURACY_LOW); fc->end_CL = this->aero.CLgroundRoll; + fc->end_L_over_D = this->aero.getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), fc->end_CL, fc->operating_condition->config); fc->end_angle_of_attack = 0.; fc->end_specific_air_range = 0.; this->mission_file->mission_data.at(a_mission_step).mode = Flight_conditions::LANDING; @@ -1073,9 +1076,9 @@ void standard_mission::free_flight(Operating_conditions* oc, Flight_conditions* static_cast<uint16_t>(ceil(fabs(fc->delta_h / EndnodeReadOnly<double>( "program_settings/precision/altitude_increment").read(this->rtIO->moduleConfig).value()))); fc->delta_h = fc->delta_h / flightLevelSteps; - myRuntimeInfo->out << "Climb Step: " << convertUnit(METER, FOOT, fc->delta_h) << " ft." << std::endl; - myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl; - myRuntimeInfo->out << "End altitude: " << convertUnit(METER, FOOT, (fc->delta_h * flightLevelSteps + fc->altitude)) << " ft." << std::endl; + myRuntimeInfo->out << "Climb Step: " << convertUnit(METER, FOOT, fc->delta_h) << " ft." << std::endl; + myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc->altitude) << " ft." << std::endl; + myRuntimeInfo->out << "End altitude: " << convertUnit(METER, FOOT, (fc->delta_h * flightLevelSteps + fc->altitude)) << " ft." << std::endl; myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, get_transition_altitude(CAS, transition_mach, this->atm)) << " ft." << std::endl; for (uint16_t step_number(0); step_number < flightLevelSteps; ++step_number) { /* Set the initial conditions of the segment */ @@ -1429,10 +1432,28 @@ void standard_mission::free_flight_iteration(Operating_conditions* oc, Flight_co convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), 0., fc->aircraft_mass - fc->step_fuel_mass, this->atm)); } - fc->end_specific_air_range = - this->static_flight_specific_air_range(energy_carrier_id, convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), - fc->end_altitude, fc->aircraft_mass - - fc->step_fuel_mass, oc->config, oc->rating); + + fc->end_L_over_D = this->aero.getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), fc->end_CL, fc->operating_condition->config); + if (sophistication_level != UNSOPHISTICATED) { + double current_cg(get_current_cg()); + fc->end_L_over_D = this->interpolateViaCoG(current_cg, fc->end_L_over_D, + getAlternativeAero(current_cg)->getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), + fc->end_CL, fc->operating_condition->config)); + } + + double sar_tmp; + try { + sar_tmp = + this->static_flight_specific_air_range(energy_carrier_id, convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), + fc->end_altitude, fc->aircraft_mass - + fc->step_fuel_mass, oc->config, oc->rating); + } catch (const int& engine_status) { + throwError(__FILE__, __func__, __LINE__, + ("Required thrust (" + num2Str(this->aero.getCruiseDrag(mach, fc->end_altitude, 0., fc->aircraft_mass - + fc->step_fuel_mass, oc->config, this->atm)) + " kN) cannot be delivered by engines in current status.")); + } + fc->end_specific_air_range = sar_tmp; + fc->end_angle_of_attack = this->aero.getAlphaAtFlightCondition(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), oc->config, fc->end_CL); @@ -1576,6 +1597,13 @@ void standard_mission::set_iteration_start_values(Flight_conditions* fc, const d } else { fc->end_CL = an_end_CL; } + fc->end_L_over_D = this->aero.getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), fc->end_CL, fc->operating_condition->config); + if (sophistication_level != UNSOPHISTICATED) { + double current_cg(get_current_cg()); + fc->end_L_over_D = this->interpolateViaCoG(current_cg, fc->end_L_over_D, + getAlternativeAero(current_cg)->getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), + fc->end_CL, fc->operating_condition->config)); + } fc->end_drag = this->aero.getCLDrag(mach, fc->end_altitude, fc->end_CL, fc->operating_condition->config, atm); if (sophistication_level != UNSOPHISTICATED) { double current_cg(get_current_cg()); @@ -1621,6 +1649,15 @@ void standard_mission::set_aerodynamic_values(Flight_conditions* fc, const doubl } } + // L over D + fc->end_L_over_D = this->aero.getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), fc->end_CL, fc->operating_condition->config); + if (sophistication_level != UNSOPHISTICATED) { + double current_cg(get_current_cg()); + fc->end_L_over_D = this->interpolateViaCoG(current_cg, fc->end_L_over_D, + getAlternativeAero(current_cg)->getCLLoverD(convertUnit(TRUEAIRSPEED, MACH, fc->end_altitude, this->atm, fc->end_TAS), + fc->end_CL, fc->operating_condition->config)); + } + // Drag fc->end_drag = this->aero.getCLDrag(mach, fc->end_altitude, fc->end_CL, fc->operating_condition->config, this->atm); @@ -1821,6 +1858,7 @@ void standard_mission::save_segment_data(Flight_conditions* fc, const Operating_ this->mission_profile.back().end_altitude + fc->delta_h, this->mission_profile.back().end_total_mass - fc->step_fuel_mass, fc->end_CL, + fc->end_L_over_D, fc->end_specific_air_range, oc.config, fc->mean_glidepath_angle, diff --git a/mission_analysis/src/standard_mission/output/standard_mission_output.cpp b/mission_analysis/src/standard_mission/output/standard_mission_output.cpp index 8cf1df72..5c02063c 100644 --- a/mission_analysis/src/standard_mission/output/standard_mission_output.cpp +++ b/mission_analysis/src/standard_mission/output/standard_mission_output.cpp @@ -147,7 +147,7 @@ void standard_mission_output::generate_mission_profile_data() { << (std::format("Energy consumed ({}, ID = {}) [J]; ", rtIO->get_fuel_type(energy_carrier.first), energy_carrier.first)); } csvStream << "Mach [-]; " << "CAS [m/s]; " << "TAS [m/s]; " << "TAS [kts]; " << "ROC [fpm]; " << "SAR [m/kg]; " << "Aero Config [-]; " << "C_L [-]; " - << "Spoiler Factor [-]; " << "Reynolds Number [-]; " << "Engine Rating [-]; "; + << "L over D [-]; " << "Spoiler Factor [-]; " << "Reynolds Number [-]; " << "Engine Rating [-]; "; for (node* propulsor : rtIO->acxml.at("component_design/propulsion/specific").getVector("propulsion")) { csvStream << "Engine N1 (" << propulsor->at("engine/model/value") << ", ID = " << propulsor->getIntAttrib("ID") << ") [-]; "; } @@ -198,6 +198,7 @@ void standard_mission_output::generate_mission_profile_data() { csvStream << my_mission_ptr->mission_profile.at(i).end_specific_air_range << "; " << my_mission_ptr->mission_profile.at(i).end_aero_config << "; " << my_mission_ptr->mission_profile.at(i).end_CL << "; " + << my_mission_ptr->mission_profile.at(i).end_L_over_D << "; " << my_mission_ptr->mission_profile.at(i).end_spoiler_factor << "; " << my_mission_ptr->mission_profile.at(i).end_reynolds_number << "; " << my_mission_ptr->mission_profile.at(i).end_engine_rating << "; "; @@ -289,8 +290,9 @@ void standard_mission_output::generate_SAR_plot_data() { try { SAR_tmp = my_mission_ptr->static_flight_specific_air_range(energy_carrier_id, Ma, convertUnit(HECTO, FOOT, NOPREFIX, METER, Alt), aircraft_mass, Config_set, Rating_set); - } catch (const char * text) { - } catch (const std::string& text) { + } catch (const std::string& text) { + myRuntimeInfo->out << "... but this was intended: SAR limit for plotting reached!" << std::endl; + } catch (...) { } plot << std::setprecision(7) << Ma << "; "; plot << std::setprecision(7) << Alt << "; "; // in meters diff --git a/mission_analysis/src/standard_mission/standard_mission/standard_mission.cpp b/mission_analysis/src/standard_mission/standard_mission/standard_mission.cpp index 41ddcf37..0a56d150 100644 --- a/mission_analysis/src/standard_mission/standard_mission/standard_mission.cpp +++ b/mission_analysis/src/standard_mission/standard_mission/standard_mission.cpp @@ -357,6 +357,7 @@ void standard_mission::run() { this->takeoff_mass.value(), 0., 0., + 0., oc.config, 0., 0., @@ -385,11 +386,12 @@ void standard_mission::run() { for (size_t i(0); i < this->mission_file->mission_data.size(); i++) { /* Output: calculation mode and current parameters */ myRuntimeInfo->out << "*********************************************************" << std::endl; - myRuntimeInfo->out << "Calculation mode: " << this->mission_file->mission_data.at(i).mode << " in mission segment: " << i + 1 << std::endl; - myRuntimeInfo->out << "Current altitude: " << convertUnit(METER, FOOT, this->mission_profile.back().end_altitude) << " ft." << std::endl; - myRuntimeInfo->out << "Current range: " << convertUnit(METER, NAUTICALMILE, this->mission_profile.back().end_range) << " NM." << std::endl; + myRuntimeInfo->out << "Calculation mode: " << this->mission_file->mission_data.at(i).mode << " in mission segment: " << i + 1 << std::endl; + myRuntimeInfo->out << "Current altitude: " << convertUnit(METER, FOOT, this->mission_profile.back().end_altitude) << " ft." << std::endl; + myRuntimeInfo->out << "Current range: " << convertUnit(METER, NAUTICALMILE, this->mission_profile.back().end_range) << " NM." << std::endl; myRuntimeInfo->out << "Current Mach number: " << this->mission_profile.back().end_mach << std::endl; - myRuntimeInfo->out << "Current CL: " << this->mission_profile.back().end_CL << std::endl; + myRuntimeInfo->out << "Current CL: " << this->mission_profile.back().end_CL << std::endl; + myRuntimeInfo->out << "Current L/D: " << this->mission_profile.back().end_L_over_D << std::endl; switch (this->mission_file->mission_data.at(i).mode) { /* Mode: take off */ case Flight_conditions::TAKEOFF: @@ -493,7 +495,7 @@ void standard_mission::update() { Endnode<double> flight_time("flight_time", "Flight time for the whole mission", this->mission_profile.back().end_time, "s", 0, 44500); Endnode<double> total_range("range", "Traveled range from break release to end of taxi at destination", this->mission_profile.back().end_range, "m", 0, 5000000); Endnode<int> energy_carrier_id("energy_carrier_ID", "See energy carrier specification node", 0, "1", 0, 5); // TODO(GErrit): Auf Multifuel anpassen hier und drunter - Endnode<double> consumed_energy("consumed_energy", "Energy amount", 0, "J", 0, 1.e12); + Endnode<double> consumed_energy("consumed_energy", "Energy amount", 0, "J", 0, 1.e13); /* Aircraft parameters */ // Since takeoff_mass can be put into mission node for study mission and into masses_cg_inertia node for design mission, @@ -635,9 +637,9 @@ void standard_mission::analyze_cruise_profile() { step.mass = this->mission_profile.at(this->cruise_profile_end).end_total_mass; this->cruise_profile.push_back(step); /* Output: current parameters */ - myRuntimeInfo->out << "Current altitude: " << convertUnit(METER, FOOT, this->mission_profile.back().end_altitude) << " ft." << std::endl; - myRuntimeInfo->out << "Current range: " << convertUnit(METER, NAUTICALMILE, this->mission_profile.back().end_range) << " NM." << std::endl; - myRuntimeInfo->out << "Cruise Step Profile:" << std::endl; + myRuntimeInfo->out << "Current altitude: " << convertUnit(METER, FOOT, this->mission_profile.back().end_altitude) << " ft." << std::endl; + myRuntimeInfo->out << "Current range: " << convertUnit(METER, NAUTICALMILE, this->mission_profile.back().end_range) << " NM." << std::endl; + myRuntimeInfo->out << "Cruise Step Profile: " << std::endl; myRuntimeInfo->out << " FL | rel. Step Length | End Mass [kg]" << std::endl; for (size_t i(0); i < this->cruise_profile.size(); ++i) { myRuntimeInfo->out << std::setprecision(2) << std::fixed << this->cruise_profile.at(i).FL << " | " @@ -740,36 +742,36 @@ void standard_mission::throw_mission_error(int error_code, const uint16_t &missi switch (error_code) { /* Error: negative flight route leading to an insufficient thrust */ case 1: - error_message << "Error: Negative flight distance! -> Thrust not sufficient." << std::endl; + error_message << "Error: Negative flight distance! -> Thrust not sufficient."; break; /* Error: insufficient acceleration potential */ case 2: - error_message << "Error: Acceleration not sufficient!" << std::endl; + error_message << "Error: Acceleration not sufficient!"; break; /* Error: resistance too low to maintain the glide path */ case 3: - error_message << "Error: Drag too low to maintain the glide path!" << std::endl; + error_message << "Error: Drag too low to maintain the glide path!"; break; /* Error: insufficient thrust to maintain trajectory */ case 4: - error_message << "Error: Thrust not sufficient to maintain trajectory!" << std::endl; + error_message << "Error: Thrust not sufficient to maintain trajectory!"; break; /* Error: divergence too low */ case 5: - error_message << "Error: Divergence too large!" << std::endl; + error_message << "Error: Divergence too large!"; break; /* Error: climb angle for iteration too small leading to a too large or too small thrust */ case 6: - error_message << "Climb angle for Iteration too small - Thrust too high or too low!" << std::endl; + error_message << "Climb angle for Iteration too small - Thrust too high or too low!"; break; /* Unknown error */ default: - error_message << "Unkown Error" << std::endl; + error_message << "Unkown Error"; break; } - error_message << "Occured in mode step " << mission_step + 1 << std::endl; - error_message << "Mode: " << this->mission_file->mission_data.at(mission_step).mode_name << ", "; - error_message << "Index in mission file: " << this->mission_file->mission_data.at(mission_step).mission_file_index << std::endl; + error_message << " Occured in mode step " << mission_step + 1; + error_message << " Mode: " << this->mission_file->mission_data.at(mission_step).mode_name << ", "; + error_message << " Index in mission file: " << this->mission_file->mission_data.at(mission_step).mission_file_index << std::endl; throw error_message.str(); } @@ -924,7 +926,7 @@ void standard_mission::first_loop_update() {/* Create path to mission and build Endnode<double> total_range("range", "Traveled range from break release to end of taxi at destination", // take required range for 1st assumption EndnodeReadOnly<double>("requirements_and_specifications/requirements/top_level_aircraft_requirements/design_mission/range").read(rtIO->acxml).value(), "m", 0, 5000000); Endnode<int> energy_carrier_id("energy_carrier_ID", "See energy carrier specification node", 0, "1", 0, 5); // TODO(GErrit): Auf Multifuel anpassen hier und drunter - Endnode<double> consumed_energy("consumed_energy", "Energy amount", 0, "J", 0, 1.e12); + Endnode<double> consumed_energy("consumed_energy", "Energy amount", 0, "J", 0, 1.e13); /* Aircraft parameters */ // Since takeoff_mass can be put into mission node for study mission and into masses_cg_inertia node for design mission, diff --git a/mission_analysis/src/standard_mission/standard_mission/standard_mission.h b/mission_analysis/src/standard_mission/standard_mission/standard_mission.h index a350e629..19726a6d 100644 --- a/mission_analysis/src/standard_mission/standard_mission/standard_mission.h +++ b/mission_analysis/src/standard_mission/standard_mission/standard_mission.h @@ -229,6 +229,7 @@ class standard_mission : public Strategy { double end_altitude; /**< Altitude at the end of the segment [m] */ double end_total_mass; /**< Aircraft mass at the end of the segment [kg] */ double end_CL; /**< Lift coefficient at the end of the segment [-] */ + double end_L_over_D; /**< Lift over drag coefficient at the end of the segment [-] */ double end_specific_air_range; /**< Specific air range at the end of the segment [m/kg] */ std::string end_aero_config; /**< Aerodynamic configuration at the end of the segment */ double end_glidepath_angle; /**< Path angle at the end of the segment [deg] */ @@ -249,7 +250,7 @@ class standard_mission : public Strategy { double end_fuel_cg; /**< Fuel center of gravity at the end of the segment [m] */ double end_stabilizer_incidence; /**< incidence angle of stabilizer at the end of the segment [deg] */ std::vector<std::vector<double>> end_origin_polar; /**< Origin polar with variable camber infos at the end of the segment */ - int energy_carrier_id; + int energy_carrier_id; /* Energy carrier used for the profile step */ /* Constructor and destructor */ /** \brief Constructor for the class mission_segment * \param an_end_total_fuel_mass: cumulative consumption at the end of the segment [kg] @@ -259,6 +260,7 @@ class standard_mission : public Strategy { * \param an_end_altitude: altitude at the end of the segment [m] * \param an_end_total_mass: weight at the end of the segment [kg] * \param an_end_CL: lift coefficient at the end of the segment [-] + * \param an_end_L_over_D: lift over drag coefficient at the end of the segment [-] * \param an_end_specific_air_range: specific air range at the end of the segment [m/kg] * \param an_end_aero_config: aerodynamic configuration at the end of the segment * \param an_end_glidepath_angle: glidepath angle at the end of the segment [deg] @@ -279,6 +281,7 @@ class standard_mission : public Strategy { * \param an_end_fuel_cg: Fuel center of gravity at the end of the segment [m] * \param an_end_stabilizer_incidence: incidence angle of stabilizer at the end of the segment [deg] * \param an_end_origin_polar: Origin polar with variable camber infos at the end of the segment + * \param an_energy_carrier_id: Energy carrier used for the profile step */ mission_segment(const std::map<int, double>& an_end_total_fuel_mass, double an_end_fuel_flow, @@ -287,6 +290,7 @@ class standard_mission : public Strategy { double an_end_altitude, double an_end_total_mass, double an_end_CL, + double an_end_L_over_D, double an_end_specific_air_range, const std::string& an_end_aero_config, double an_end_glidepath_angle, @@ -314,10 +318,32 @@ class standard_mission : public Strategy { }; std::vector<mission_segment> mission_profile; /**< Profile of the mission */ - /* Methods */ + /* Auxillary functions */ + /** \brief Function checks if the needed node is existing. If not, it's created + * \param nodepath: path leading to the wanted node + * \param description: description of the new node + * \param id: if multiple same nodes are set, given ID for it + * \param tool_level: if a tool level is needed, given tool level + */ void check_and_add_nodes(std::string nodepath, const std::string& description, const int& id = -1, const int& tool_level = -1); + /** \brief Function returns the whole fuel mass within the map + * \param fuel_map: A fuel map with int keys corresponding to the energy carrier IDs <[-], [kg]> + * \return double value of the fuel mass [kg] + */ double get_fuel_sum(std::map<int, double> fuel_map); + /** \brief Function checks if the needed node is existing. If not, it's created + * \param subpath: Path to energy node + * \param energy_nodes: Name of the final energy node itself + * \return A fuel map with int keys corresponding to the energy carrier IDs <[-], [kg]> + */ std::map<int, double> fuel_map_setup(const std::string& subpath, const std::string& energy_nodes); + /** \brief Function checks if the needed node is existing. If not, it's created + * \param fuel_map: A fuel map with int keys corresponding to the energy carrier IDs <[-], [kg]> + * \param subpath: Path to energy node + * \param description: description of the new node + * \param energy_carrier_id: Energy carrier ID of the used fuel + * \param consumed_energy: Energy which was consumed during the respective fligth segment + */ void update_energy_nodes(const std::map<int, double>& fuel_map, const std::string& subpath, const std::string& description, Endnode<int>* energy_carrier_id, Endnode<double>* consumed_energy); /* Inline auxillary functions */ @@ -334,12 +360,7 @@ class standard_mission : public Strategy { inline double static_flight_specific_air_range(const int& energy_carrier_id, const double &mach, const double &altitude, const double &aircraft_mass, const std::string &config, const std::string &rating, const double &bleed = 0., const double &shaft_power = 0.) { const double& required_thrust(this->aero.getCruiseDrag(mach, altitude, 0., aircraft_mass, config, this->atm)); - try { - this->engine.calculate_N1_with_thrustlimit(energy_carrier_id, altitude, mach, atm, 1., rating, bleed, shaft_power, required_thrust); - } catch (const int& engine_status) { - throwError(__FILE__, __func__, __LINE__, - ("Required thrust (" + num2Str(required_thrust) + " kN) cannot be delivered by engines in current status.")); - } + this->engine.calculate_N1_with_thrustlimit(energy_carrier_id, altitude, mach, atm, 1., rating, bleed, shaft_power, required_thrust); return this->aero.getCruiseLoverD(mach, altitude, 0., aircraft_mass, config, atm) * convertUnit(MACH, TRUEAIRSPEED, altitude, this->atm, mach) / this->engine.get_aircraft_fuelflow(energy_carrier_id) * this->engine.get_thrust_aircraft(energy_carrier_id) / aircraft_mass / G_FORCE; } -- GitLab From f50c35fb0bedb89cca813f093e0c87ae18fe6638 Mon Sep 17 00:00:00 2001 From: Gerrit Pauls <gerrit.pauls@tuhh.de> Date: Thu, 12 Dec 2024 07:55:09 +0100 Subject: [PATCH 2/2] Minor shell output change --- .../standard_mission/flight_segments/flight_segments.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp b/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp index 395ca07c..8d8b5b50 100644 --- a/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp +++ b/mission_analysis/src/standard_mission/flight_segments/flight_segments.cpp @@ -432,12 +432,12 @@ double standard_mission::calculate_climb_or_descent(Operating_conditions* oc, Fl Flight_conditions fc_tmp(*fc); fc_tmp.delta_h /= steps; if (!simulation_mode) { - myRuntimeInfo->out << ((fc_tmp.delta_h > 0.) ? "Climb step: " : "Descent step: ") + myRuntimeInfo->out << ((fc_tmp.delta_h > 0.) ? "Climb step: " : "Descent step: ") << convertUnit(METER, FOOT, fc_tmp.delta_h) << " ft." << std::endl; - myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc_tmp.altitude) << " ft." << std::endl; - myRuntimeInfo->out << "End altitude " << ((this->mission_file->mission_data.at(a_mission_step).auto_FL_optimum) ? " (estimated): " : ": ") + myRuntimeInfo->out << "Start altitude: " << convertUnit(METER, FOOT, fc_tmp.altitude) << " ft." << std::endl; + myRuntimeInfo->out << "End altitude" << ((this->mission_file->mission_data.at(a_mission_step).auto_FL_optimum) ? " (estimated): " : ": ") << convertUnit(METER, FOOT, (fc_tmp.delta_h * steps + fc_tmp.altitude)) << " ft." << std::endl; - if (change_speed_at_transition_altitude) myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, transitionAltitude) << " ft." << std::endl; + if (change_speed_at_transition_altitude) myRuntimeInfo->out << "Transition altitude: " << convertUnit(METER, FOOT, transitionAltitude) << " ft." << std::endl; } for (uint16_t step_number(0); step_number < steps; ++step_number) { this->set_segment_initial_conditions(&fc_tmp, !simulation_mode); -- GitLab