From 54b58a1d91e715eedee1c4b555e66a991d632a62 Mon Sep 17 00:00:00 2001 From: Markus Quaritsch <markus.quaritsch@tugraz.at> Date: Tue, 13 Dec 2016 13:42:21 +0100 Subject: [PATCH] refactoring: moving 1Hz Filter to separate file, movin modal result fields to separate file --- .../Models/Simulation/Data/ModalResult.cs | 327 ----------------- .../Simulation/Data/ModalResultField.cs | 339 ++++++++++++++++++ .../ModFilter/ModalData1HzFilter.cs | 197 ++++++++++ .../OutputData/ModalDataContainer.cs | 188 ---------- 4 files changed, 536 insertions(+), 515 deletions(-) create mode 100644 VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs create mode 100644 VectoCore/VectoCore/OutputData/ModFilter/ModalData1HzFilter.cs diff --git a/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs b/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs index 71cee71fec..f6c32af7b6 100644 --- a/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs +++ b/VectoCore/VectoCore/Models/Simulation/Data/ModalResult.cs @@ -112,331 +112,4 @@ namespace TUGraz.VectoCore.Models.Simulation.Data VectoCSVFile.Write(fileName, this); } } - - /// <summary> - /// Enum with field definitions of the Modal Results File (.vmod). - /// </summary> - public enum ModalResultField - { - /// <summary> - /// Time step [s]. - /// Midpoint of the simulated interval. - /// </summary> - [ModalResultField(typeof(SI), caption: "time [s]")] time, - - /// <summary> - /// Simulation interval around the current time step. [s] - /// </summary> - [ModalResultField(typeof(SI), "simulation_interval", "dt [s]")] simulationInterval, - - /// <summary> - /// Engine speed [1/min]. - /// </summary> - [ModalResultField(typeof(SI), caption: "n_eng_avg [1/min]", outputFactor: 60 / (2 * Math.PI))] n_eng_avg, - - /// <summary> - /// [Nm] Engine torque. - /// </summary> - [ModalResultField(typeof(SI), caption: "T_eng_fcmap [Nm]")] T_eng_fcmap, - - /// <summary> - /// [Nm] Full load torque - /// </summary> - [ModalResultField(typeof(SI), caption: "Tq_full [Nm]")] Tq_full, - - /// <summary> - /// [Nm] Motoring torque - /// </summary> - [ModalResultField(typeof(SI), caption: "Tq_drag [Nm]")] Tq_drag, - - /// <summary> - /// [kW] Engine power. - /// </summary> - [ModalResultField(typeof(SI), caption: "P_eng_out [kW]", outputFactor: 1e-3)] P_eng_out, - - /// <summary> - /// [kW] Engine full load power. - /// </summary> - [ModalResultField(typeof(SI), caption: "P_eng_full [kW]", outputFactor: 1e-3)] P_eng_full, - - /// <summary> - /// [kW] Engine drag power. - /// </summary> - [ModalResultField(typeof(SI), caption: "P_eng_drag [kW]", outputFactor: 1e-3)] P_eng_drag, - - /// <summary> - /// [kW] Engine power at clutch (equals Pe minus loss due to rotational inertia Pa Eng). - /// </summary> - [ModalResultField(typeof(SI), caption: "P_clutch_out [kW]", outputFactor: 1e-3)] P_clutch_out, - - /// <summary> - /// [kW] Rotational acceleration power: Engine. - /// </summary> - [ModalResultField(typeof(SI), name: "P_eng_inertia", caption: "P_eng_inertia [kW]", outputFactor: 1e-3)] P_eng_inertia, - - /// <summary> - /// [kW] Total auxiliary power demand . - /// </summary> - [ModalResultField(typeof(SI), caption: "P_aux [kW]", outputFactor: 1e-3)] P_aux, - - /// <summary> - /// [g/h] Fuel consumption from FC map.. - /// </summary> - [ModalResultField(typeof(SI), name: "FC-Map", caption: "FC-Map [g/h]", outputFactor: 3600 * 1000)] FCMap, - - /// <summary> - /// [g/h] Fuel consumption after Auxiliary-Start/Stop Correction. (Based on FC.) - /// </summary> - [ModalResultField(typeof(SI), name: "FC-AUXc", caption: "FC-AUXc [g/h]", outputFactor: 3600 * 1000)] FCAUXc, - - /// <summary> - /// [g/h] Fuel consumption after WHTC Correction. (Based on FC-AUXc.) - /// </summary> - [ModalResultField(typeof(SI), name: "FC-WHTCc", caption: "FC-WHTCc [g/h]", outputFactor: 3600 * 1000)] FCWHTCc, - - /// <summary> - /// [g/h] Fuel consumption after smart auxiliary correction. - /// </summary> - [ModalResultField(typeof(SI), name: "FC-AAUX", caption: "FC-AAUX [g/h]", outputFactor: 3600 * 1000)] FCAAUX, - - /// <summary> - /// [g/h] Fuel consumption after WHTC Correction. (Based on FC-AUXc.) - /// </summary> - [ModalResultField(typeof(SI), name: "FC-Final", caption: "FC-Final [g/h]", outputFactor: 3600 * 1000)] FCFinal, - - /// <summary> - /// [km] Travelled distance. - /// </summary> - [ModalResultField(typeof(SI), caption: "dist [m]")] dist, - - /// <summary> - /// [km/h] Actual vehicle speed. - /// </summary> - [ModalResultField(typeof(SI), caption: "v_act [km/h]", outputFactor: 3.6)] v_act, - - /// <summary> - /// [km/h] Target vehicle speed. - /// </summary> - [ModalResultField(typeof(SI), caption: "v_targ [km/h]", outputFactor: 3.6)] v_targ, - - /// <summary> - /// [m/s2] Vehicle acceleration. - /// </summary> - [ModalResultField(typeof(SI), caption: "acc [m/s^2]")] acc, - - /// <summary> - /// [%] Road gradient. - /// </summary> - [ModalResultField(typeof(SI), caption: "grad [%]")] grad, - - /// <summary> - /// [-] GearData. "0" = clutch opened / neutral. "0.5" = lock-up clutch is open (AT with torque converter only, see - /// Gearbox) - /// </summary> - [ModalResultField(typeof(uint), caption: "Gear [-]")] Gear, - - [ModalResultField(typeof(SI), caption: "n_gbx_out_avg [1/min]", outputFactor: 60 / (2 * Math.PI))] n_gbx_out_avg, - - [ModalResultField(typeof(SI), caption: "T_gbx_out [Nm]")] T_gbx_out, - - /// <summary> - /// [kW] Gearbox losses. - /// </summary> - [ModalResultField(typeof(SI), name: "P_gbx_loss", caption: "P_gbx_loss [kW]", outputFactor: 1e-3)] P_gbx_loss, - - /// <summary> - /// [kW] Losses in differential / axle transmission. - /// </summary> - [ModalResultField(typeof(SI), name: "Ploss Diff", caption: "P_axle_loss [kW]", outputFactor: 1e-3)] P_axle_loss, - - /// <summary> - /// [kW] Losses in angle transmission. - /// </summary> - [ModalResultField(typeof(SI), name: "Ploss Angle", caption: "P_angle_loss [kW]", outputFactor: 1e-3)] P_angle_loss, - - /// <summary> - /// [kW] Retarder losses. - /// </summary> - [ModalResultField(typeof(SI), name: "P_ret_loss", caption: "P_ret_loss [kW]", outputFactor: 1e-3)] P_ret_loss, - - /// <summary> - /// [kW] Rotational acceleration power: Gearbox. - /// </summary> - [ModalResultField(typeof(SI), name: "P_gbx_inertia", caption: "P_gbx_inertia [kW]", outputFactor: 1e-3)] P_gbx_inertia, - - /// <summary> - /// [kW] Vehicle acceleration power. - /// </summary> - [ModalResultField(typeof(SI), name: "P_veh_inertia", caption: "P_veh_inertia [kW]", outputFactor: 1e-3)] P_veh_inertia, - - /// <summary> - /// [kW] Rolling resistance power demand. - /// </summary> - [ModalResultField(typeof(SI), caption: "P_roll [kW]", outputFactor: 1e-3)] P_roll, - - /// <summary> - /// [kW] Air resistance power demand. - /// </summary> - [ModalResultField(typeof(SI), caption: "P_air [kW]", outputFactor: 1e-3)] P_air, - - /// <summary> - /// [kW] Power demand due to road gradient. - /// </summary> - [ModalResultField(typeof(SI), caption: "P_slope [kW]", outputFactor: 1e-3)] P_slope, - - /// <summary> - /// [kW] Total power demand at wheel = sum of rolling, air, acceleration and road gradient resistance. - /// </summary> - [ModalResultField(typeof(SI), caption: "P_wheel_in [kW]", outputFactor: 1e-3)] P_wheel_in, - - /// <summary> - /// [kW] Brake power. Drag power is included in Pe. - /// </summary> - [ModalResultField(typeof(SI), caption: "P_brake_loss [kW]", outputFactor: 1e-3)] P_brake_loss, - - [ModalResultField(typeof(SI), caption: "P_wheel_inertia [kW]", outputFactor: 1e-3)] P_wheel_inertia, - - [ModalResultField(typeof(SI), caption: "P_brake_in [kW]", outputFactor: 1e-3)] P_brake_in, - - [ModalResultField(typeof(SI), caption: "P_axle_in [kW]", outputFactor: 1e-3)] P_axle_in, - - [ModalResultField(typeof(SI), caption: "P_angle_in [kW]", outputFactor: 1e-3)] P_angle_in, - - [ModalResultField(typeof(SI), caption: "P_ret_in [kW]", outputFactor: 1e-3)] P_retarder_in, - - [ModalResultField(typeof(SI), caption: "P_gbx_in [kW]", outputFactor: 1e-3)] P_gbx_in, - - [ModalResultField(typeof(SI), caption: "P_clutch_loss [kW]", outputFactor: 1e-3)] P_clutch_loss, - - [ModalResultField(typeof(SI), caption: "P_trac [kW]", outputFactor: 1e-3)] P_trac, - - [ModalResultField(typeof(SI), caption: "P_eng_fcmap [kW]", outputFactor: 1e-3)] P_eng_fcmap, - - [ModalResultField(typeof(SI), caption: "P_eng_full_stat [kW]", outputFactor: 1e-3)] P_eng_full_stat, - - /// <summary> - /// [kW] Power demand of Auxiliary with ID xxx. See also Aux Dialog and Driving Cycle. - /// </summary> - [ModalResultField(typeof(SI), outputFactor: 1e-3)] P_aux_, - - /// <summary> - /// [-] true/false indicate whether torque converter is locked or not (only applicable for gears with TC) - /// </summary> - [ModalResultField(typeof(int), caption: "TC locked")] TC_Locked, - - /// <summary> - /// [-] Torque converter speed ratio - /// </summary> - [ModalResultField(typeof(double), name: "TCnu")] TorqueConverterSpeedRatio, - - /// <summary> - /// [-] Torque converter torque ratio - /// </summary> - [ModalResultField(typeof(double), name: "TCmu")] TorqueConverterTorqueRatio, - - [ModalResultField(typeof(SI), "P_TC_out [kW]", outputFactor: 1e-3)] P_TC_out, - - /// <summary> - /// [kW] Power loss at the torque converter. - /// </summary> - [ModalResultField(typeof(SI), "P_TC_loss [kW]", outputFactor: 1e-3)] P_TC_loss, - - /// <summary> - /// [Nm] Torque converter output torque - /// </summary> - [ModalResultField(typeof(SI), "T_TC_out")] TC_TorqueOut, - - /// <summary> - /// [1/min] Torque converter output speed - /// </summary> - [ModalResultField(typeof(SI), "n_TC_out", outputFactor: 60 / (2 * Math.PI))] TC_angularSpeedOut, - - /// <summary> - /// [Nm] Torque converter output torque - /// </summary> - [ModalResultField(typeof(SI), "T_TC_in")] TC_TorqueIn, - - /// <summary> - /// [1/min] Torque converter output speed - /// </summary> - [ModalResultField(typeof(SI), "n_TC_in", outputFactor: 60 / (2 * Math.PI))] TC_angularSpeedIn, - - /// <summary> - /// [m] Altitude - /// </summary> - [ModalResultField(typeof(SI))] altitude, - - [ModalResultField(typeof(SI), name: "ds [m]")] simulationDistance, - - [ModalResultField(typeof(double), caption: "AA_NonSmartAlternatorsEfficiency [%]")] AA_NonSmartAlternatorsEfficiency, - [ModalResultField(typeof(SI), caption: "AA_SmartIdleCurrent_Amps [A]")] AA_SmartIdleCurrent_Amps, - [ModalResultField(typeof(double), caption: "AA_SmartIdleAlternatorsEfficiency [%]")] AA_SmartIdleAlternatorsEfficiency, - [ModalResultField(typeof(SI), caption: "AA_SmartTractionCurrent_Amps [A]")] AA_SmartTractionCurrent_Amps, - [ModalResultField(typeof(double), caption: "AA_SmartTractionAlternatorEfficiency [%]")] AA_SmartTractionAlternatorEfficiency, - [ModalResultField(typeof(SI), caption: "AA_SmartOverrunCurrent_Amps [A]")] AA_SmartOverrunCurrent_Amps, - [ModalResultField(typeof(double), caption: "AA_SmartOverrunAlternatorEfficiency [%]")] AA_SmartOverrunAlternatorEfficiency, - [ModalResultField(typeof(SI), caption: "AA_CompressorFlowRate_LitrePerSec [Ni L/s]")] AA_CompressorFlowRate_LitrePerSec, - [ModalResultField(typeof(int), caption: "AA_OverrunFlag [bool]")] AA_OverrunFlag, - [ModalResultField(typeof(int), caption: "AA_EngineIdleFlag [bool]")] AA_EngineIdleFlag, - [ModalResultField(typeof(int), caption: "AA_CompressorFlag [bool]")] AA_CompressorFlag, - [ModalResultField(typeof(SI), caption: "AA_TotalCycleFC_Grams [g]", outputFactor: 1000)] AA_TotalCycleFC_Grams, - [ModalResultField(typeof(SI), caption: "AA_TotalCycleFC_Litres [l]")] AA_TotalCycleFC_Litres, - [ModalResultField(typeof(SI), caption: "AA_AveragePowerDemandCrankHVACMechanicals [W]")] AA_AveragePowerDemandCrankHVACMechanicals, - [ModalResultField(typeof(SI), caption: "AA_AveragePowerDemandCrankHVACElectricals [W]")] AA_AveragePowerDemandCrankHVACElectricals, - [ModalResultField(typeof(SI), caption: "AA_AveragePowerDemandCrankElectrics [W]")] AA_AveragePowerDemandCrankElectrics, - [ModalResultField(typeof(SI), caption: "AA_AveragePowerDemandCrankPneumatics [W]")] AA_AveragePowerDemandCrankPneumatics, - [ModalResultField(typeof(SI), caption: "AA_TotalCycleFuelConsumptionCompressorOff [g]", outputFactor: 1000)] AA_TotalCycleFuelConsumptionCompressorOff, - [ModalResultField(typeof(SI), caption: "AA_TotalCycleFuelConsumptionCompressorOn [g]", outputFactor: 1000)] AA_TotalCycleFuelConsumptionCompressorOn, - } - - [AttributeUsage(AttributeTargets.Field)] - public class ModalResultFieldAttribute : Attribute - { - internal ModalResultFieldAttribute(Type dataType, string name = null, string caption = null, uint decimals = 4, - double outputFactor = 1, bool showUnit = false) - { - DataType = dataType; - Name = name; - Caption = caption; - Decimals = decimals; - OutputFactor = outputFactor; - ShowUnit = showUnit; - } - - public bool ShowUnit { get; private set; } - public double OutputFactor { get; private set; } - public uint Decimals { get; private set; } - public Type DataType { get; private set; } - public string Name { get; private set; } - public string Caption { get; private set; } - } - - public static class ModalResultFieldExtensionMethods - { - public static string GetName(this ModalResultField field) - { - return GetAttribute(field).Name ?? field.ToString(); - } - - public static string GetCaption(this ModalResultField field) - { - return GetAttribute(field).Caption ?? GetAttribute(field).Name ?? field.ToString(); - } - - public static string GetShortCaption(this ModalResultField field) - { - var caption = GetCaption(field); - return Regex.Replace(caption, @"\[.*?\]|\<|\>", "").Trim(); - } - - public static ModalResultFieldAttribute GetAttribute(this ModalResultField field) - { - return (ModalResultFieldAttribute)Attribute.GetCustomAttribute(ForValue(field), typeof(ModalResultFieldAttribute)); - } - - private static MemberInfo ForValue(ModalResultField field) - { - return typeof(ModalResultField).GetField(Enum.GetName(typeof(ModalResultField), field)); - } - } } \ No newline at end of file diff --git a/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs new file mode 100644 index 0000000000..bc408df103 --- /dev/null +++ b/VectoCore/VectoCore/Models/Simulation/Data/ModalResultField.cs @@ -0,0 +1,339 @@ +using System; +using System.Reflection; +using System.Text.RegularExpressions; +using TUGraz.VectoCommon.Utils; + +namespace TUGraz.VectoCore.Models.Simulation.Data +{ + /// <summary> + /// Enum with field definitions of the Modal Results File (.vmod). + /// </summary> + public enum ModalResultField + { + /// <summary> + /// Time step [s]. + /// Midpoint of the simulated interval. + /// </summary> + [ModalResultField(typeof(SI), caption: "time [s]")] time, + + /// <summary> + /// Simulation interval around the current time step. [s] + /// </summary> + [ModalResultField(typeof(SI), "simulation_interval", "dt [s]")] simulationInterval, + + /// <summary> + /// Engine speed [1/min]. + /// </summary> + [ModalResultField(typeof(SI), caption: "n_eng_avg [1/min]", outputFactor: 60 / (2 * Math.PI))] n_eng_avg, + + /// <summary> + /// [Nm] Engine torque. + /// </summary> + [ModalResultField(typeof(SI), caption: "T_eng_fcmap [Nm]")] T_eng_fcmap, + + /// <summary> + /// [Nm] Full load torque + /// </summary> + [ModalResultField(typeof(SI), caption: "Tq_full [Nm]")] Tq_full, + + /// <summary> + /// [Nm] Motoring torque + /// </summary> + [ModalResultField(typeof(SI), caption: "Tq_drag [Nm]")] Tq_drag, + + /// <summary> + /// [kW] Engine power. + /// </summary> + [ModalResultField(typeof(SI), caption: "P_eng_out [kW]", outputFactor: 1e-3)] P_eng_out, + + /// <summary> + /// [kW] Engine full load power. + /// </summary> + [ModalResultField(typeof(SI), caption: "P_eng_full [kW]", outputFactor: 1e-3)] P_eng_full, + + /// <summary> + /// [kW] Engine drag power. + /// </summary> + [ModalResultField(typeof(SI), caption: "P_eng_drag [kW]", outputFactor: 1e-3)] P_eng_drag, + + /// <summary> + /// [kW] Engine power at clutch (equals Pe minus loss due to rotational inertia Pa Eng). + /// </summary> + [ModalResultField(typeof(SI), caption: "P_clutch_out [kW]", outputFactor: 1e-3)] P_clutch_out, + + /// <summary> + /// [kW] Rotational acceleration power: Engine. + /// </summary> + [ModalResultField(typeof(SI), name: "P_eng_inertia", caption: "P_eng_inertia [kW]", outputFactor: 1e-3)] P_eng_inertia, + + /// <summary> + /// [kW] Total auxiliary power demand . + /// </summary> + [ModalResultField(typeof(SI), caption: "P_aux [kW]", outputFactor: 1e-3)] P_aux, + + /// <summary> + /// [g/h] Fuel consumption from FC map.. + /// </summary> + [ModalResultField(typeof(SI), name: "FC-Map", caption: "FC-Map [g/h]", outputFactor: 3600 * 1000)] FCMap, + + /// <summary> + /// [g/h] Fuel consumption after Auxiliary-Start/Stop Correction. (Based on FC.) + /// </summary> + [ModalResultField(typeof(SI), name: "FC-AUXc", caption: "FC-AUXc [g/h]", outputFactor: 3600 * 1000)] FCAUXc, + + /// <summary> + /// [g/h] Fuel consumption after WHTC Correction. (Based on FC-AUXc.) + /// </summary> + [ModalResultField(typeof(SI), name: "FC-WHTCc", caption: "FC-WHTCc [g/h]", outputFactor: 3600 * 1000)] FCWHTCc, + + /// <summary> + /// [g/h] Fuel consumption after smart auxiliary correction. + /// </summary> + [ModalResultField(typeof(SI), name: "FC-AAUX", caption: "FC-AAUX [g/h]", outputFactor: 3600 * 1000)] FCAAUX, + + /// <summary> + /// [g/h] Fuel consumption after WHTC Correction. (Based on FC-AUXc.) + /// </summary> + [ModalResultField(typeof(SI), name: "FC-Final", caption: "FC-Final [g/h]", outputFactor: 3600 * 1000)] FCFinal, + + /// <summary> + /// [km] Travelled distance. + /// </summary> + [ModalResultField(typeof(SI), caption: "dist [m]")] dist, + + /// <summary> + /// [km/h] Actual vehicle speed. + /// </summary> + [ModalResultField(typeof(SI), caption: "v_act [km/h]", outputFactor: 3.6)] v_act, + + /// <summary> + /// [km/h] Target vehicle speed. + /// </summary> + [ModalResultField(typeof(SI), caption: "v_targ [km/h]", outputFactor: 3.6)] v_targ, + + /// <summary> + /// [m/s2] Vehicle acceleration. + /// </summary> + [ModalResultField(typeof(SI), caption: "acc [m/s^2]")] acc, + + /// <summary> + /// [%] Road gradient. + /// </summary> + [ModalResultField(typeof(SI), caption: "grad [%]")] grad, + + /// <summary> + /// [-] GearData. "0" = clutch opened / neutral. "0.5" = lock-up clutch is open (AT with torque converter only, see + /// Gearbox) + /// </summary> + [ModalResultField(typeof(uint), caption: "Gear [-]")] Gear, + + [ModalResultField(typeof(SI), caption: "n_gbx_out_avg [1/min]", outputFactor: 60 / (2 * Math.PI))] n_gbx_out_avg, + + [ModalResultField(typeof(SI), caption: "T_gbx_out [Nm]")] T_gbx_out, + + /// <summary> + /// [kW] Gearbox losses. + /// </summary> + [ModalResultField(typeof(SI), name: "P_gbx_loss", caption: "P_gbx_loss [kW]", outputFactor: 1e-3)] P_gbx_loss, + + /// <summary> + /// [kW] Losses in differential / axle transmission. + /// </summary> + [ModalResultField(typeof(SI), name: "Ploss Diff", caption: "P_axle_loss [kW]", outputFactor: 1e-3)] P_axle_loss, + + /// <summary> + /// [kW] Losses in angle transmission. + /// </summary> + [ModalResultField(typeof(SI), name: "Ploss Angle", caption: "P_angle_loss [kW]", outputFactor: 1e-3)] P_angle_loss, + + /// <summary> + /// [kW] Retarder losses. + /// </summary> + [ModalResultField(typeof(SI), name: "P_ret_loss", caption: "P_ret_loss [kW]", outputFactor: 1e-3)] P_ret_loss, + + /// <summary> + /// [kW] Rotational acceleration power: Gearbox. + /// </summary> + [ModalResultField(typeof(SI), name: "P_gbx_inertia", caption: "P_gbx_inertia [kW]", outputFactor: 1e-3)] P_gbx_inertia, + + /// <summary> + /// [kW] Vehicle acceleration power. + /// </summary> + [ModalResultField(typeof(SI), name: "P_veh_inertia", caption: "P_veh_inertia [kW]", outputFactor: 1e-3)] P_veh_inertia, + + /// <summary> + /// [kW] Rolling resistance power demand. + /// </summary> + [ModalResultField(typeof(SI), caption: "P_roll [kW]", outputFactor: 1e-3)] P_roll, + + /// <summary> + /// [kW] Air resistance power demand. + /// </summary> + [ModalResultField(typeof(SI), caption: "P_air [kW]", outputFactor: 1e-3)] P_air, + + /// <summary> + /// [kW] Power demand due to road gradient. + /// </summary> + [ModalResultField(typeof(SI), caption: "P_slope [kW]", outputFactor: 1e-3)] P_slope, + + /// <summary> + /// [kW] Total power demand at wheel = sum of rolling, air, acceleration and road gradient resistance. + /// </summary> + [ModalResultField(typeof(SI), caption: "P_wheel_in [kW]", outputFactor: 1e-3)] P_wheel_in, + + /// <summary> + /// [kW] Brake power. Drag power is included in Pe. + /// </summary> + [ModalResultField(typeof(SI), caption: "P_brake_loss [kW]", outputFactor: 1e-3)] P_brake_loss, + + [ModalResultField(typeof(SI), caption: "P_wheel_inertia [kW]", outputFactor: 1e-3)] P_wheel_inertia, + + [ModalResultField(typeof(SI), caption: "P_brake_in [kW]", outputFactor: 1e-3)] P_brake_in, + + [ModalResultField(typeof(SI), caption: "P_axle_in [kW]", outputFactor: 1e-3)] P_axle_in, + + [ModalResultField(typeof(SI), caption: "P_angle_in [kW]", outputFactor: 1e-3)] P_angle_in, + + [ModalResultField(typeof(SI), caption: "P_ret_in [kW]", outputFactor: 1e-3)] P_retarder_in, + + [ModalResultField(typeof(SI), caption: "P_gbx_in [kW]", outputFactor: 1e-3)] P_gbx_in, + + [ModalResultField(typeof(SI), caption: "P_clutch_loss [kW]", outputFactor: 1e-3)] P_clutch_loss, + + [ModalResultField(typeof(SI), caption: "P_trac [kW]", outputFactor: 1e-3)] P_trac, + + [ModalResultField(typeof(SI), caption: "P_eng_fcmap [kW]", outputFactor: 1e-3)] P_eng_fcmap, + + [ModalResultField(typeof(SI), caption: "P_eng_full_stat [kW]", outputFactor: 1e-3)] P_eng_full_stat, + + /// <summary> + /// [kW] Power demand of Auxiliary with ID xxx. See also Aux Dialog and Driving Cycle. + /// </summary> + [ModalResultField(typeof(SI), outputFactor: 1e-3)] P_aux_, + + /// <summary> + /// [-] true/false indicate whether torque converter is locked or not (only applicable for gears with TC) + /// </summary> + [ModalResultField(typeof(int), caption: "TC locked")] TC_Locked, + + /// <summary> + /// [-] Torque converter speed ratio + /// </summary> + [ModalResultField(typeof(double), name: "TCnu")] TorqueConverterSpeedRatio, + + /// <summary> + /// [-] Torque converter torque ratio + /// </summary> + [ModalResultField(typeof(double), name: "TCmu")] TorqueConverterTorqueRatio, + + [ModalResultField(typeof(SI), "P_TC_out [kW]", outputFactor: 1e-3)] P_TC_out, + + /// <summary> + /// [kW] Power loss at the torque converter. + /// </summary> + [ModalResultField(typeof(SI), "P_TC_loss [kW]", outputFactor: 1e-3)] P_TC_loss, + + /// <summary> + /// [Nm] Torque converter output torque + /// </summary> + [ModalResultField(typeof(SI), "T_TC_out")] TC_TorqueOut, + + /// <summary> + /// [1/min] Torque converter output speed + /// </summary> + [ModalResultField(typeof(SI), "n_TC_out", outputFactor: 60 / (2 * Math.PI))] TC_angularSpeedOut, + + /// <summary> + /// [Nm] Torque converter output torque + /// </summary> + [ModalResultField(typeof(SI), "T_TC_in")] TC_TorqueIn, + + /// <summary> + /// [1/min] Torque converter output speed + /// </summary> + [ModalResultField(typeof(SI), "n_TC_in", outputFactor: 60 / (2 * Math.PI))] TC_angularSpeedIn, + + /// <summary> + /// [m] Altitude + /// </summary> + [ModalResultField(typeof(SI))] altitude, + + [ModalResultField(typeof(SI), name: "ds [m]")] simulationDistance, + + [ModalResultField(typeof(double), caption: "AA_NonSmartAlternatorsEfficiency [%]")] AA_NonSmartAlternatorsEfficiency, + [ModalResultField(typeof(SI), caption: "AA_SmartIdleCurrent_Amps [A]")] AA_SmartIdleCurrent_Amps, + [ModalResultField(typeof(double), caption: "AA_SmartIdleAlternatorsEfficiency [%]")] AA_SmartIdleAlternatorsEfficiency, + [ModalResultField(typeof(SI), caption: "AA_SmartTractionCurrent_Amps [A]")] AA_SmartTractionCurrent_Amps, + [ModalResultField(typeof(double), caption: "AA_SmartTractionAlternatorEfficiency [%]")] AA_SmartTractionAlternatorEfficiency, + [ModalResultField(typeof(SI), caption: "AA_SmartOverrunCurrent_Amps [A]")] AA_SmartOverrunCurrent_Amps, + [ModalResultField(typeof(double), caption: "AA_SmartOverrunAlternatorEfficiency [%]")] AA_SmartOverrunAlternatorEfficiency, + [ModalResultField(typeof(SI), caption: "AA_CompressorFlowRate_LitrePerSec [Ni L/s]")] AA_CompressorFlowRate_LitrePerSec, + [ModalResultField(typeof(int), caption: "AA_OverrunFlag [bool]")] AA_OverrunFlag, + [ModalResultField(typeof(int), caption: "AA_EngineIdleFlag [bool]")] AA_EngineIdleFlag, + [ModalResultField(typeof(int), caption: "AA_CompressorFlag [bool]")] AA_CompressorFlag, + [ModalResultField(typeof(SI), caption: "AA_TotalCycleFC_Grams [g]", outputFactor: 1000)] AA_TotalCycleFC_Grams, + [ModalResultField(typeof(SI), caption: "AA_TotalCycleFC_Litres [l]")] AA_TotalCycleFC_Litres, + [ModalResultField(typeof(SI), caption: "AA_AveragePowerDemandCrankHVACMechanicals [W]")] AA_AveragePowerDemandCrankHVACMechanicals, + [ModalResultField(typeof(SI), caption: "AA_AveragePowerDemandCrankHVACElectricals [W]")] AA_AveragePowerDemandCrankHVACElectricals, + [ModalResultField(typeof(SI), caption: "AA_AveragePowerDemandCrankElectrics [W]")] AA_AveragePowerDemandCrankElectrics, + [ModalResultField(typeof(SI), caption: "AA_AveragePowerDemandCrankPneumatics [W]")] AA_AveragePowerDemandCrankPneumatics, + [ModalResultField(typeof(SI), caption: "AA_TotalCycleFuelConsumptionCompressorOff [g]", outputFactor: 1000)] AA_TotalCycleFuelConsumptionCompressorOff, + [ModalResultField(typeof(SI), caption: "AA_TotalCycleFuelConsumptionCompressorOn [g]", outputFactor: 1000)] AA_TotalCycleFuelConsumptionCompressorOn, + } + + [AttributeUsage(AttributeTargets.Field)] + public class ModalResultFieldAttribute : Attribute + { + internal ModalResultFieldAttribute(Type dataType, string name = null, string caption = null, uint decimals = 4, + double outputFactor = 1, bool showUnit = false) + { + DataType = dataType; + Name = name; + Caption = caption; + Decimals = decimals; + OutputFactor = outputFactor; + ShowUnit = showUnit; + } + + public bool ShowUnit { get; private set; } + public double OutputFactor { get; private set; } + public uint Decimals { get; private set; } + public Type DataType { get; private set; } + public string Name { get; private set; } + public string Caption { get; private set; } + } + + public static class ModalResultFieldExtensionMethods + { + public static string GetName(this ModalResultField field) + { + return GetAttribute(field).Name ?? field.ToString(); + } + + public static string GetCaption(this ModalResultField field) + { + return GetAttribute(field).Caption ?? GetAttribute(field).Name ?? field.ToString(); + } + + public static string GetShortCaption(this ModalResultField field) + { + var caption = GetCaption(field); + return Regex.Replace(caption, @"\[.*?\]|\<|\>", "").Trim(); + } + + public static Type GetDataType(this ModalResultField field) + { + return GetAttribute(field).DataType; + } + + public static ModalResultFieldAttribute GetAttribute(this ModalResultField field) + { + return (ModalResultFieldAttribute)Attribute.GetCustomAttribute(ForValue(field), typeof(ModalResultFieldAttribute)); + } + + private static MemberInfo ForValue(ModalResultField field) + { + return typeof(ModalResultField).GetField(Enum.GetName(typeof(ModalResultField), field)); + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/ModFilter/ModalData1HzFilter.cs b/VectoCore/VectoCore/OutputData/ModFilter/ModalData1HzFilter.cs new file mode 100644 index 0000000000..73b5cde315 --- /dev/null +++ b/VectoCore/VectoCore/OutputData/ModFilter/ModalData1HzFilter.cs @@ -0,0 +1,197 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using TUGraz.VectoCommon.Exceptions; +using TUGraz.VectoCommon.Models; +using TUGraz.VectoCommon.Utils; +using TUGraz.VectoCore.Models.Simulation.Data; +using TUGraz.VectoCore.Utils; + +namespace TUGraz.VectoCore.OutputData.ModFilter +{ + public class ModalData1HzFilter : IModalDataFilter + { + public ModalResults Filter(ModalResults data) + { + var results = (ModalResults)data.Clone(); + + object[] remainingRow = null; + var gearsList = new Dictionary<object, Second>(3); + + var absTime = 0.SI<Second>(); + var distance = 0.SI<Meter>(); + var v = data.Rows[0].Field<MeterPerSecond>((int)ModalResultField.v_act); + var remainingDt = 0.SI<Second>(); + var vPrevious = v; + + for (var i = 0; i < data.Rows.Count; i++) { + var row = data.Rows[i]; + + var currentDt = row.Field<Second>((int)ModalResultField.simulationInterval); + + if (row.Field<Meter>((int)ModalResultField.dist).IsSmaller(distance, 1e-3)) { + LogManager.GetLogger(typeof(ModalData1HzFilter).FullName).Error("1Hz-Filter: distance must always be increasing."); + } + + // if a remainder and currentDt would exceed 1 second: take remainder and take current row to fill up to 1 second. + if (remainingDt > 0 && remainingDt + currentDt >= 1) { + // calculate values + var dt = 1.SI<Second>() - remainingDt; + var gear = row[(int)ModalResultField.Gear]; + gearsList[gear] = gearsList.GetValueOrZero(gear) + dt; + var a = (MeterPerSquareSecond)row[(int)ModalResultField.acc]; + var ds = dt * v + a / 2 * dt * dt; + if (ds.IsSmaller(0)) { + throw new VectoSimulationException("1Hz-Filter: simulation distance must not be negative."); + } + absTime += dt; + v += dt * a; + distance += ds; + + // write a new row for the combined 1 second + var r = results.NewRow(); + r.ItemArray = AddRow(remainingRow, MultiplyRow(row.ItemArray, dt)); + r[(int)ModalResultField.time] = absTime; + r[(int)ModalResultField.simulationInterval] = 1.SI<Second>(); + r[(int)ModalResultField.Gear] = gearsList.MaxBy(kv => kv.Value).Key; + r[(int)ModalResultField.dist] = distance; + r[(int)ModalResultField.v_act] = (v + vPrevious) / 2; + vPrevious = v; + results.Rows.Add(r); + + // reset remainder + // reduce current dt by already taken diff + gearsList.Clear(); + currentDt -= dt; + remainingDt = 0.SI<Second>(); + remainingRow = null; + } + + // if current row still longer than 1 second: split it to 1 second slices until it is < 1 second + while (currentDt >= 1) { + // calculate values + var dt = 1.SI<Second>(); + currentDt = currentDt - 1.SI<Second>(); + var a = (MeterPerSquareSecond)row[(int)ModalResultField.acc]; + var ds = v * dt + a / 2 * dt * dt; + if (ds.IsSmaller(0)) { + throw new VectoSimulationException("1Hz-Filter: simulation distance must not be negative."); + } + absTime += dt; + v += a * dt; + distance += ds; + + // write a new row for the sliced 1 second + var r = results.NewRow(); + r.ItemArray = row.ItemArray; + r[(int)ModalResultField.time] = absTime; + r[(int)ModalResultField.simulationInterval] = dt; + r[(int)ModalResultField.dist] = distance; + r[(int)ModalResultField.v_act] = (v + vPrevious) / 2; + vPrevious = v; + results.Rows.Add(r); + } + + // if there still is something left in current row: add to weighted values to remainder + if (currentDt > 0) { + // calculate values + var dt = currentDt; + var gear = row[(int)ModalResultField.Gear]; + gearsList[gear] = gearsList.GetValueOrZero(gear) + dt; + var a = (MeterPerSquareSecond)row[(int)ModalResultField.acc]; + var ds = v * dt + a / 2 * dt * dt; + if (ds.IsSmaller(0)) { + throw new VectoSimulationException("1Hz-Filter: simulation distance must not be negative."); + } + absTime += dt; + v += a * dt; + distance += ds; + + // add to remainder + remainingRow = AddRow(remainingRow, MultiplyRow(row.ItemArray, dt)); + remainingDt += dt; + } else { + // reset remainder (just to be sure!) + remainingRow = null; + remainingDt = 0.SI<Second>(); + gearsList.Clear(); + } + } + + // if last row was not enough to full second: take last row as whole second + if (remainingDt > 0) { + // calculate values + var last = data.Rows.Cast<DataRow>().Last(); + var dt = remainingDt; + var a = (MeterPerSquareSecond)last[(int)ModalResultField.acc]; + var ds = v * dt + a / 2 * dt * dt; + if (ds.IsSmaller(0)) { + throw new VectoSimulationException("1Hz-Filter: simulation distance must not be negative."); + } + v += a * dt; + distance += ds; + + // write a new row for the last second + var r = results.NewRow(); + r.ItemArray = MultiplyRow(remainingRow, 1 / dt).ToArray(); + r[(int)ModalResultField.time] = VectoMath.Ceiling(absTime); + r[(int)ModalResultField.simulationInterval] = 1.SI<Second>(); + r[(int)ModalResultField.Gear] = gearsList.MaxBy(kv => kv.Value).Key; + r[(int)ModalResultField.dist] = distance; + r[(int)ModalResultField.v_act] = (v + vPrevious) / 2; + results.Rows.Add(r); + } + + return results; + } + + private static IEnumerable<object> MultiplyRow(IEnumerable<object> row, SI dt) + { + return row.Select(val => { + if (val is SI) { + val = (SI)val * dt.Value(); + } else { + val.Switch() + .Case<int>(i => val = i * dt.Value()) + .Case<double>(d => val = d * dt.Value()) + .Case<float>(f => val = f * dt.Value()) + .Case<uint>(ui => val = ui * dt.Value()); + } + return val; + }); + } + + private static object[] AddRow(IEnumerable<object> row, IEnumerable<object> addRow) + { + if (row == null) { + return addRow.ToArray(); + } + if (addRow == null) { + return row.ToArray(); + } + + return row.ZipAll(addRow, (val, addVal) => { + if (val is SI || addVal is SI) { + if (DBNull.Value == val) { + val = addVal; + } else if (DBNull.Value != addVal) { + val = (SI)val + (SI)addVal; + } + } else { + val.Switch() + .Case<int>(i => val = i + (int)addVal) + .Case<double>(d => val = d + (double)addVal) + .Case<float>(f => val = f + (float)addVal) + .Case<uint>(ui => val = ui + (uint)addVal); + } + return val; + }).ToArray(); + } + + public string ID + { + get { return "1Hz"; } + } + } +} \ No newline at end of file diff --git a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs index 3b37f42b16..bfcbf49898 100644 --- a/VectoCore/VectoCore/OutputData/ModalDataContainer.cs +++ b/VectoCore/VectoCore/OutputData/ModalDataContainer.cs @@ -35,12 +35,9 @@ using System.Data; using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; -using TUGraz.VectoCommon.Exceptions; -using TUGraz.VectoCommon.Models; using TUGraz.VectoCommon.Utils; using TUGraz.VectoCore.Models.Simulation.Data; using TUGraz.VectoCore.Models.Simulation.Impl; -using TUGraz.VectoCore.Utils; namespace TUGraz.VectoCore.OutputData { @@ -302,190 +299,5 @@ namespace TUGraz.VectoCore.OutputData Auxiliaries[id] = col; } } - - public class ModalData1HzFilter : IModalDataFilter - { - public ModalResults Filter(ModalResults data) - { - var results = (ModalResults)data.Clone(); - - object[] remainingRow = null; - var gearsList = new Dictionary<object, Second>(3); - - var absTime = 0.SI<Second>(); - var distance = 0.SI<Meter>(); - var v = data.Rows[0].Field<MeterPerSecond>((int)ModalResultField.v_act); - var remainingDt = 0.SI<Second>(); - var vPrevious = v; - - for (var i = 0; i < data.Rows.Count; i++) { - var row = data.Rows[i]; - - var currentDt = row.Field<Second>((int)ModalResultField.simulationInterval); - - if (row.Field<Meter>((int)ModalResultField.dist).IsSmaller(distance, 1e-3)) { - LogManager.GetLogger(typeof(ModalData1HzFilter).FullName).Error("1Hz-Filter: distance must always be increasing."); - } - - // if a remainder and currentDt would exceed 1 second: take remainder and take current row to fill up to 1 second. - if (remainingDt > 0 && remainingDt + currentDt >= 1) { - // calculate values - var dt = 1.SI<Second>() - remainingDt; - var gear = row[(int)ModalResultField.Gear]; - gearsList[gear] = gearsList.GetValueOrZero(gear) + dt; - var a = (MeterPerSquareSecond)row[(int)ModalResultField.acc]; - var ds = dt * v + a / 2 * dt * dt; - if (ds.IsSmaller(0)) { - throw new VectoSimulationException("1Hz-Filter: simulation distance must not be negative."); - } - absTime += dt; - v += dt * a; - distance += ds; - - // write a new row for the combined 1 second - var r = results.NewRow(); - r.ItemArray = AddRow(remainingRow, MultiplyRow(row.ItemArray, dt)); - r[(int)ModalResultField.time] = absTime; - r[(int)ModalResultField.simulationInterval] = 1.SI<Second>(); - r[(int)ModalResultField.Gear] = gearsList.MaxBy(kv => kv.Value).Key; - r[(int)ModalResultField.dist] = distance; - r[(int)ModalResultField.v_act] = (v + vPrevious) / 2; - vPrevious = v; - results.Rows.Add(r); - - // reset remainder - // reduce current dt by already taken diff - gearsList.Clear(); - currentDt -= dt; - remainingDt = 0.SI<Second>(); - remainingRow = null; - } - - // if current row still longer than 1 second: split it to 1 second slices until it is < 1 second - while (currentDt >= 1) { - // calculate values - var dt = 1.SI<Second>(); - currentDt = currentDt - 1.SI<Second>(); - var a = (MeterPerSquareSecond)row[(int)ModalResultField.acc]; - var ds = v * dt + a / 2 * dt * dt; - if (ds.IsSmaller(0)) { - throw new VectoSimulationException("1Hz-Filter: simulation distance must not be negative."); - } - absTime += dt; - v += a * dt; - distance += ds; - - // write a new row for the sliced 1 second - var r = results.NewRow(); - r.ItemArray = row.ItemArray; - r[(int)ModalResultField.time] = absTime; - r[(int)ModalResultField.simulationInterval] = dt; - r[(int)ModalResultField.dist] = distance; - r[(int)ModalResultField.v_act] = (v + vPrevious) / 2; - vPrevious = v; - results.Rows.Add(r); - } - - // if there still is something left in current row: add to weighted values to remainder - if (currentDt > 0) { - // calculate values - var dt = currentDt; - var gear = row[(int)ModalResultField.Gear]; - gearsList[gear] = gearsList.GetValueOrZero(gear) + dt; - var a = (MeterPerSquareSecond)row[(int)ModalResultField.acc]; - var ds = v * dt + a / 2 * dt * dt; - if (ds.IsSmaller(0)) { - throw new VectoSimulationException("1Hz-Filter: simulation distance must not be negative."); - } - absTime += dt; - v += a * dt; - distance += ds; - - // add to remainder - remainingRow = AddRow(remainingRow, MultiplyRow(row.ItemArray, dt)); - remainingDt += dt; - } else { - // reset remainder (just to be sure!) - remainingRow = null; - remainingDt = 0.SI<Second>(); - gearsList.Clear(); - } - } - - // if last row was not enough to full second: take last row as whole second - if (remainingDt > 0) { - // calculate values - var last = data.Rows.Cast<DataRow>().Last(); - var dt = remainingDt; - var a = (MeterPerSquareSecond)last[(int)ModalResultField.acc]; - var ds = v * dt + a / 2 * dt * dt; - if (ds.IsSmaller(0)) { - throw new VectoSimulationException("1Hz-Filter: simulation distance must not be negative."); - } - v += a * dt; - distance += ds; - - // write a new row for the last second - var r = results.NewRow(); - r.ItemArray = MultiplyRow(remainingRow, 1 / dt).ToArray(); - r[(int)ModalResultField.time] = VectoMath.Ceiling(absTime); - r[(int)ModalResultField.simulationInterval] = 1.SI<Second>(); - r[(int)ModalResultField.Gear] = gearsList.MaxBy(kv => kv.Value).Key; - r[(int)ModalResultField.dist] = distance; - r[(int)ModalResultField.v_act] = (v + vPrevious) / 2; - results.Rows.Add(r); - } - - return results; - } - - private static IEnumerable<object> MultiplyRow(IEnumerable<object> row, SI dt) - { - return row.Select(val => { - if (val is SI) { - val = (SI)val * dt.Value(); - } else { - val.Switch() - .Case<int>(i => val = i * dt.Value()) - .Case<double>(d => val = d * dt.Value()) - .Case<float>(f => val = f * dt.Value()) - .Case<uint>(ui => val = ui * dt.Value()); - } - return val; - }); - } - - private static object[] AddRow(IEnumerable<object> row, IEnumerable<object> addRow) - { - if (row == null) { - return addRow.ToArray(); - } - if (addRow == null) { - return row.ToArray(); - } - - return row.ZipAll(addRow, (val, addVal) => { - if (val is SI || addVal is SI) { - if (DBNull.Value == val) { - val = addVal; - } else if (DBNull.Value != addVal) { - val = (SI)val + (SI)addVal; - } - } else { - val.Switch() - .Case<int>(i => val = i + (int)addVal) - .Case<double>(d => val = d + (double)addVal) - .Case<float>(f => val = f + (float)addVal) - .Case<uint>(ui => val = ui + (uint)addVal); - } - return val; - }).ToArray(); - } - - public string ID - { - get { return "1Hz"; } - } - } } } \ No newline at end of file -- GitLab